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_conversion = std::make_unique<LinuxPerfZeroTscConversion>( 42 test_time_mult, test_time_shift, test_time_zero); 43 44 // Serialize then deserialize. 45 Expected<TraceIntelPTGetStateResponse> deserialized_response = 46 json::parse<TraceIntelPTGetStateResponse>( 47 llvm::formatv("{0}", toJSON(response)).str(), 48 "TraceIntelPTGetStateResponse"); 49 if (!deserialized_response) 50 FAIL() << toString(deserialized_response.takeError()); 51 52 // Choose arbitrary TSC value to test the Convert function. 53 const uint64_t TSC = std::numeric_limits<uint32_t>::max(); 54 // Expected nanosecond value pre calculated using the TSC to wall time 55 // conversion formula located in the time_zero section of 56 // https://man7.org/linux/man-pages/man2/perf_event_open.2.html 57 const uint64_t EXPECTED_NANOS = 9223372039007304983u; 58 59 uint64_t pre_serialization_conversion = 60 response.tsc_conversion->Convert(TSC).count(); 61 uint64_t post_serialization_conversion = 62 deserialized_response->tsc_conversion->Convert(TSC).count(); 63 64 // Check equality: 65 // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse 66 // portions of the JSON representation are unchanged. 67 ASSERT_EQ(toJSON(response), toJSON(*deserialized_response)); 68 // Ensure the result of the Convert function is unchanged. 69 ASSERT_EQ(EXPECTED_NANOS, pre_serialization_conversion); 70 ASSERT_EQ(EXPECTED_NANOS, post_serialization_conversion); 71 } 72 73 // Test serialization and deserialization of an empty 74 // TraceIntelPTGetStateResponse. 75 TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponseEmpty) { 76 // This test works as follows: 77 // 1. Create an empty TraceIntelPTGetStateResponse 78 // 2. Serialize to JSON 79 // 3. Deserialize the serialized JSON value 80 // 4. Ensure the original value and the deserialized value are equivalent 81 82 // Create TraceIntelPTGetStateResponse. 83 TraceIntelPTGetStateResponse response; 84 85 // Serialize then deserialize. 86 Expected<TraceIntelPTGetStateResponse> deserialized_response = 87 json::parse<TraceIntelPTGetStateResponse>( 88 llvm::formatv("{0}", toJSON(response)).str(), 89 "TraceIntelPTGetStateResponse"); 90 if (!deserialized_response) 91 FAIL() << toString(deserialized_response.takeError()); 92 93 // Check equality: 94 // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse 95 // portions of the JSON representation are unchanged. 96 ASSERT_EQ(toJSON(response), toJSON(*deserialized_response)); 97 // Ensure that the tsc_conversion's are nullptr. 98 ASSERT_EQ(response.tsc_conversion.get(), nullptr); 99 ASSERT_EQ(response.tsc_conversion.get(), 100 deserialized_response->tsc_conversion.get()); 101 } 102