|  | //===-- TraceGDBRemotePacketsTest.cpp -------------------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" | 
|  |  | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | #include <limits> | 
|  |  | 
|  | using namespace lldb_private; | 
|  | using namespace llvm; | 
|  |  | 
|  | // Test serialization and deserialization of a non-empty | 
|  | // TraceIntelPTGetStateResponse. | 
|  | TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponse) { | 
|  | // This test works as follows: | 
|  | //  1. Create a non-empty TraceIntelPTGetStateResponse | 
|  | //  2. Serialize to JSON | 
|  | //  3. Deserialize the serialized JSON value | 
|  | //  4. Ensure the original value and the deserialized value are equivalent | 
|  | // | 
|  | //  Notes: | 
|  | //    - We intentionally set an integer value out of its signed range | 
|  | //      to ensure the serialization/deserialization isn't lossy since JSON | 
|  | //      operates on signed values | 
|  |  | 
|  | // Choose arbitrary values for time_mult and time_shift | 
|  | uint32_t test_time_mult = 1076264588; | 
|  | uint16_t test_time_shift = 31; | 
|  | // Intentionally set time_zero value out of the signed type's range. | 
|  | uint64_t test_time_zero = | 
|  | static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1; | 
|  |  | 
|  | // Create TraceIntelPTGetStateResponse. | 
|  | TraceIntelPTGetStateResponse response; | 
|  | response.tsc_perf_zero_conversion = LinuxPerfZeroTscConversion{test_time_mult, test_time_shift, {test_time_zero}}; | 
|  |  | 
|  | // Serialize then deserialize. | 
|  | Expected<TraceIntelPTGetStateResponse> deserialized_response = | 
|  | json::parse<TraceIntelPTGetStateResponse>( | 
|  | llvm::formatv("{0}", toJSON(response)).str(), | 
|  | "TraceIntelPTGetStateResponse"); | 
|  | if (!deserialized_response) | 
|  | FAIL() << toString(deserialized_response.takeError()); | 
|  |  | 
|  | // Choose arbitrary TSC value to test the Convert function. | 
|  | const uint64_t TSC = std::numeric_limits<uint32_t>::max(); | 
|  | // Expected nanosecond value pre calculated using the TSC to wall time | 
|  | // conversion formula located in the time_zero section of | 
|  | // https://man7.org/linux/man-pages/man2/perf_event_open.2.html | 
|  | const uint64_t EXPECTED_NANOS = 9223372039007304983u; | 
|  |  | 
|  | uint64_t pre_serialization_conversion = | 
|  | response.tsc_perf_zero_conversion->ToNanos(TSC); | 
|  | uint64_t post_serialization_conversion = | 
|  | deserialized_response->tsc_perf_zero_conversion->ToNanos(TSC); | 
|  |  | 
|  | // Check equality: | 
|  | // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse | 
|  | // portions of the JSON representation are unchanged. | 
|  | ASSERT_EQ(toJSON(response), toJSON(*deserialized_response)); | 
|  | // Ensure the result of the Convert function is unchanged. | 
|  | ASSERT_EQ(EXPECTED_NANOS, pre_serialization_conversion); | 
|  | ASSERT_EQ(EXPECTED_NANOS, post_serialization_conversion); | 
|  | } | 
|  |  | 
|  | // Test serialization and deserialization of an empty | 
|  | // TraceIntelPTGetStateResponse. | 
|  | TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponseEmpty) { | 
|  | // This test works as follows: | 
|  | //  1. Create an empty TraceIntelPTGetStateResponse | 
|  | //  2. Serialize to JSON | 
|  | //  3. Deserialize the serialized JSON value | 
|  | //  4. Ensure the original value and the deserialized value are equivalent | 
|  |  | 
|  | // Create TraceIntelPTGetStateResponse. | 
|  | TraceIntelPTGetStateResponse response; | 
|  |  | 
|  | // Serialize then deserialize. | 
|  | Expected<TraceIntelPTGetStateResponse> deserialized_response = | 
|  | json::parse<TraceIntelPTGetStateResponse>( | 
|  | llvm::formatv("{0}", toJSON(response)).str(), | 
|  | "TraceIntelPTGetStateResponse"); | 
|  | if (!deserialized_response) | 
|  | FAIL() << toString(deserialized_response.takeError()); | 
|  |  | 
|  | // Check equality: | 
|  | // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse | 
|  | // portions of the JSON representation are unchanged. | 
|  | ASSERT_EQ(toJSON(response), toJSON(*deserialized_response)); | 
|  | // Ensure that the tsc_conversion's are nullptr. | 
|  | ASSERT_FALSE((bool)response.tsc_perf_zero_conversion); | 
|  | ASSERT_FALSE((bool)deserialized_response->tsc_perf_zero_conversion); | 
|  | } |