xref: /llvm-project/lldb/unittests/Utility/TraceGDBRemotePacketsTest.cpp (revision dae2fafe056c83a802c1f1a1baa3cd48416c06f7)
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.
TEST(TraceGDBRemotePacketsTest,IntelPTGetStateResponse)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.
TEST(TraceGDBRemotePacketsTest,IntelPTGetStateResponseEmpty)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