1 //===-- TraceGDBRemotePacketsTest.cpp -------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" 10 11 #include "gtest/gtest.h" 12 13 #include <limits> 14 15 using namespace lldb_private; 16 using namespace llvm; 17 18 // Test serialization and deserialization of a non-empty 19 // TraceIntelPTGetStateResponse. 20 TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponse) { 21 // This test works as follows: 22 // 1. Create a non-empty TraceIntelPTGetStateResponse 23 // 2. Serialize to JSON 24 // 3. Deserialize the serialized JSON value 25 // 4. Ensure the original value and the deserialized value are equivalent 26 // 27 // Notes: 28 // - We intentionally set an integer value out of its signed range 29 // to ensure the serialization/deserialization isn't lossy since JSON 30 // operates on signed values 31 32 // Choose arbitrary values for time_mult and time_shift 33 uint32_t test_time_mult = 1076264588; 34 uint16_t test_time_shift = 31; 35 // Intentionally set time_zero value out of the signed type's range. 36 uint64_t test_time_zero = 37 static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1; 38 39 // Create TraceIntelPTGetStateResponse. 40 TraceIntelPTGetStateResponse response; 41 response.tsc_perf_zero_conversion = LinuxPerfZeroTscConversion{test_time_mult, test_time_shift, {test_time_zero}}; 42 43 // Serialize then deserialize. 44 Expected<TraceIntelPTGetStateResponse> deserialized_response = 45 json::parse<TraceIntelPTGetStateResponse>( 46 llvm::formatv("{0}", toJSON(response)).str(), 47 "TraceIntelPTGetStateResponse"); 48 if (!deserialized_response) 49 FAIL() << toString(deserialized_response.takeError()); 50 51 // Choose arbitrary TSC value to test the Convert function. 52 const uint64_t TSC = std::numeric_limits<uint32_t>::max(); 53 // Expected nanosecond value pre calculated using the TSC to wall time 54 // conversion formula located in the time_zero section of 55 // https://man7.org/linux/man-pages/man2/perf_event_open.2.html 56 const uint64_t EXPECTED_NANOS = 9223372039007304983u; 57 58 uint64_t pre_serialization_conversion = 59 response.tsc_perf_zero_conversion->ToNanos(TSC); 60 uint64_t post_serialization_conversion = 61 deserialized_response->tsc_perf_zero_conversion->ToNanos(TSC); 62 63 // Check equality: 64 // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse 65 // portions of the JSON representation are unchanged. 66 ASSERT_EQ(toJSON(response), toJSON(*deserialized_response)); 67 // Ensure the result of the Convert function is unchanged. 68 ASSERT_EQ(EXPECTED_NANOS, pre_serialization_conversion); 69 ASSERT_EQ(EXPECTED_NANOS, post_serialization_conversion); 70 } 71 72 // Test serialization and deserialization of an empty 73 // TraceIntelPTGetStateResponse. 74 TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponseEmpty) { 75 // This test works as follows: 76 // 1. Create an empty TraceIntelPTGetStateResponse 77 // 2. Serialize to JSON 78 // 3. Deserialize the serialized JSON value 79 // 4. Ensure the original value and the deserialized value are equivalent 80 81 // Create TraceIntelPTGetStateResponse. 82 TraceIntelPTGetStateResponse response; 83 84 // Serialize then deserialize. 85 Expected<TraceIntelPTGetStateResponse> deserialized_response = 86 json::parse<TraceIntelPTGetStateResponse>( 87 llvm::formatv("{0}", toJSON(response)).str(), 88 "TraceIntelPTGetStateResponse"); 89 if (!deserialized_response) 90 FAIL() << toString(deserialized_response.takeError()); 91 92 // Check equality: 93 // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse 94 // portions of the JSON representation are unchanged. 95 ASSERT_EQ(toJSON(response), toJSON(*deserialized_response)); 96 // Ensure that the tsc_conversion's are nullptr. 97 ASSERT_FALSE((bool)response.tsc_perf_zero_conversion); 98 ASSERT_FALSE((bool)deserialized_response->tsc_perf_zero_conversion); 99 } 100