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
15using namespace lldb_private;
16using namespace llvm;
17
18// Test serialization and deserialization of a non-empty
19// TraceIntelPTGetStateResponse.
20TEST(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{.time_mult: test_time_mult, .time_shift: test_time_shift, .time_zero: {.value: test_time_zero}};
42
43 // Serialize then deserialize.
44 Expected<TraceIntelPTGetStateResponse> deserialized_response =
45 json::parse<TraceIntelPTGetStateResponse>(
46 JSON: llvm::formatv(Fmt: "{0}", Vals: toJSON(packet: response)).str(),
47 RootName: "TraceIntelPTGetStateResponse");
48 if (!deserialized_response)
49 FAIL() << toString(E: 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: TSC);
60 uint64_t post_serialization_conversion =
61 deserialized_response->tsc_perf_zero_conversion->ToNanos(tsc: 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.
74TEST(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 JSON: llvm::formatv(Fmt: "{0}", Vals: toJSON(packet: response)).str(),
88 RootName: "TraceIntelPTGetStateResponse");
89 if (!deserialized_response)
90 FAIL() << toString(E: 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

source code of lldb/unittests/Utility/TraceGDBRemotePacketsTest.cpp