19b79187cSJakob Johnson //===-- TraceGDBRemotePacketsTest.cpp -------------------------------------===//
29b79187cSJakob Johnson //
39b79187cSJakob Johnson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49b79187cSJakob Johnson // See https://llvm.org/LICENSE.txt for license information.
59b79187cSJakob Johnson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69b79187cSJakob Johnson //
79b79187cSJakob Johnson //===----------------------------------------------------------------------===//
89b79187cSJakob Johnson
99b79187cSJakob Johnson #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
109b79187cSJakob Johnson
119b79187cSJakob Johnson #include "gtest/gtest.h"
129b79187cSJakob Johnson
139b79187cSJakob Johnson #include <limits>
149b79187cSJakob Johnson
159b79187cSJakob Johnson using namespace lldb_private;
169b79187cSJakob Johnson using namespace llvm;
179b79187cSJakob Johnson
189b79187cSJakob Johnson // Test serialization and deserialization of a non-empty
199b79187cSJakob Johnson // TraceIntelPTGetStateResponse.
TEST(TraceGDBRemotePacketsTest,IntelPTGetStateResponse)209b79187cSJakob Johnson TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponse) {
219b79187cSJakob Johnson // This test works as follows:
229b79187cSJakob Johnson // 1. Create a non-empty TraceIntelPTGetStateResponse
239b79187cSJakob Johnson // 2. Serialize to JSON
249b79187cSJakob Johnson // 3. Deserialize the serialized JSON value
259b79187cSJakob Johnson // 4. Ensure the original value and the deserialized value are equivalent
269b79187cSJakob Johnson //
279b79187cSJakob Johnson // Notes:
289b79187cSJakob Johnson // - We intentionally set an integer value out of its signed range
299b79187cSJakob Johnson // to ensure the serialization/deserialization isn't lossy since JSON
309b79187cSJakob Johnson // operates on signed values
319b79187cSJakob Johnson
329b79187cSJakob Johnson // Choose arbitrary values for time_mult and time_shift
339b79187cSJakob Johnson uint32_t test_time_mult = 1076264588;
349b79187cSJakob Johnson uint16_t test_time_shift = 31;
359b79187cSJakob Johnson // Intentionally set time_zero value out of the signed type's range.
369b79187cSJakob Johnson uint64_t test_time_zero =
379b79187cSJakob Johnson static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1;
389b79187cSJakob Johnson
399b79187cSJakob Johnson // Create TraceIntelPTGetStateResponse.
409b79187cSJakob Johnson TraceIntelPTGetStateResponse response;
41*dae2fafeSWalter Erquinigo response.tsc_perf_zero_conversion = LinuxPerfZeroTscConversion{test_time_mult, test_time_shift, {test_time_zero}};
429b79187cSJakob Johnson
439b79187cSJakob Johnson // Serialize then deserialize.
449b79187cSJakob Johnson Expected<TraceIntelPTGetStateResponse> deserialized_response =
459b79187cSJakob Johnson json::parse<TraceIntelPTGetStateResponse>(
469b79187cSJakob Johnson llvm::formatv("{0}", toJSON(response)).str(),
479b79187cSJakob Johnson "TraceIntelPTGetStateResponse");
489b79187cSJakob Johnson if (!deserialized_response)
499b79187cSJakob Johnson FAIL() << toString(deserialized_response.takeError());
509b79187cSJakob Johnson
519b79187cSJakob Johnson // Choose arbitrary TSC value to test the Convert function.
529b79187cSJakob Johnson const uint64_t TSC = std::numeric_limits<uint32_t>::max();
539b79187cSJakob Johnson // Expected nanosecond value pre calculated using the TSC to wall time
549b79187cSJakob Johnson // conversion formula located in the time_zero section of
559b79187cSJakob Johnson // https://man7.org/linux/man-pages/man2/perf_event_open.2.html
569b79187cSJakob Johnson const uint64_t EXPECTED_NANOS = 9223372039007304983u;
579b79187cSJakob Johnson
589b79187cSJakob Johnson uint64_t pre_serialization_conversion =
59*dae2fafeSWalter Erquinigo response.tsc_perf_zero_conversion->ToNanos(TSC);
609b79187cSJakob Johnson uint64_t post_serialization_conversion =
61*dae2fafeSWalter Erquinigo deserialized_response->tsc_perf_zero_conversion->ToNanos(TSC);
629b79187cSJakob Johnson
639b79187cSJakob Johnson // Check equality:
649b79187cSJakob Johnson // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse
659b79187cSJakob Johnson // portions of the JSON representation are unchanged.
669b79187cSJakob Johnson ASSERT_EQ(toJSON(response), toJSON(*deserialized_response));
679b79187cSJakob Johnson // Ensure the result of the Convert function is unchanged.
689b79187cSJakob Johnson ASSERT_EQ(EXPECTED_NANOS, pre_serialization_conversion);
699b79187cSJakob Johnson ASSERT_EQ(EXPECTED_NANOS, post_serialization_conversion);
709b79187cSJakob Johnson }
719b79187cSJakob Johnson
729b79187cSJakob Johnson // Test serialization and deserialization of an empty
739b79187cSJakob Johnson // TraceIntelPTGetStateResponse.
TEST(TraceGDBRemotePacketsTest,IntelPTGetStateResponseEmpty)749b79187cSJakob Johnson TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponseEmpty) {
759b79187cSJakob Johnson // This test works as follows:
769b79187cSJakob Johnson // 1. Create an empty TraceIntelPTGetStateResponse
779b79187cSJakob Johnson // 2. Serialize to JSON
789b79187cSJakob Johnson // 3. Deserialize the serialized JSON value
799b79187cSJakob Johnson // 4. Ensure the original value and the deserialized value are equivalent
809b79187cSJakob Johnson
819b79187cSJakob Johnson // Create TraceIntelPTGetStateResponse.
829b79187cSJakob Johnson TraceIntelPTGetStateResponse response;
839b79187cSJakob Johnson
849b79187cSJakob Johnson // Serialize then deserialize.
859b79187cSJakob Johnson Expected<TraceIntelPTGetStateResponse> deserialized_response =
869b79187cSJakob Johnson json::parse<TraceIntelPTGetStateResponse>(
879b79187cSJakob Johnson llvm::formatv("{0}", toJSON(response)).str(),
889b79187cSJakob Johnson "TraceIntelPTGetStateResponse");
899b79187cSJakob Johnson if (!deserialized_response)
909b79187cSJakob Johnson FAIL() << toString(deserialized_response.takeError());
919b79187cSJakob Johnson
929b79187cSJakob Johnson // Check equality:
939b79187cSJakob Johnson // Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse
949b79187cSJakob Johnson // portions of the JSON representation are unchanged.
959b79187cSJakob Johnson ASSERT_EQ(toJSON(response), toJSON(*deserialized_response));
969b79187cSJakob Johnson // Ensure that the tsc_conversion's are nullptr.
97b97b082cSWalter Erquinigo ASSERT_FALSE((bool)response.tsc_perf_zero_conversion);
98b97b082cSWalter Erquinigo ASSERT_FALSE((bool)deserialized_response->tsc_perf_zero_conversion);
999b79187cSJakob Johnson }
100