blob: 06063aa32ded2d3c831bbb9d9c94ebe6612b3e44 [file] [log] [blame]
//===-- TraceGDBRemotePacketsTest.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
#include "gtest/gtest.h"
#include <limits>
using namespace lldb_private;
using namespace llvm;
// Test serialization and deserialization of a non-empty
// TraceIntelPTGetStateResponse.
TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponse) {
// This test works as follows:
// 1. Create a non-empty TraceIntelPTGetStateResponse
// 2. Serialize to JSON
// 3. Deserialize the serialized JSON value
// 4. Ensure the original value and the deserialized value are equivalent
//
// Notes:
// - We intentionally set an integer value out of its signed range
// to ensure the serialization/deserialization isn't lossy since JSON
// operates on signed values
// Choose arbitrary values for time_mult and time_shift
uint32_t test_time_mult = 1076264588;
uint16_t test_time_shift = 31;
// Intentionally set time_zero value out of the signed type's range.
uint64_t test_time_zero =
static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1;
// Create TraceIntelPTGetStateResponse.
TraceIntelPTGetStateResponse response;
response.tsc_perf_zero_conversion = LinuxPerfZeroTscConversion{test_time_mult, test_time_shift, {test_time_zero}};
// Serialize then deserialize.
Expected<TraceIntelPTGetStateResponse> deserialized_response =
json::parse<TraceIntelPTGetStateResponse>(
llvm::formatv("{0}", toJSON(response)).str(),
"TraceIntelPTGetStateResponse");
if (!deserialized_response)
FAIL() << toString(deserialized_response.takeError());
// Choose arbitrary TSC value to test the Convert function.
const uint64_t TSC = std::numeric_limits<uint32_t>::max();
// Expected nanosecond value pre calculated using the TSC to wall time
// conversion formula located in the time_zero section of
// https://man7.org/linux/man-pages/man2/perf_event_open.2.html
const uint64_t EXPECTED_NANOS = 9223372039007304983u;
uint64_t pre_serialization_conversion =
response.tsc_perf_zero_conversion->ToNanos(TSC);
uint64_t post_serialization_conversion =
deserialized_response->tsc_perf_zero_conversion->ToNanos(TSC);
// Check equality:
// Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse
// portions of the JSON representation are unchanged.
ASSERT_EQ(toJSON(response), toJSON(*deserialized_response));
// Ensure the result of the Convert function is unchanged.
ASSERT_EQ(EXPECTED_NANOS, pre_serialization_conversion);
ASSERT_EQ(EXPECTED_NANOS, post_serialization_conversion);
}
// Test serialization and deserialization of an empty
// TraceIntelPTGetStateResponse.
TEST(TraceGDBRemotePacketsTest, IntelPTGetStateResponseEmpty) {
// This test works as follows:
// 1. Create an empty TraceIntelPTGetStateResponse
// 2. Serialize to JSON
// 3. Deserialize the serialized JSON value
// 4. Ensure the original value and the deserialized value are equivalent
// Create TraceIntelPTGetStateResponse.
TraceIntelPTGetStateResponse response;
// Serialize then deserialize.
Expected<TraceIntelPTGetStateResponse> deserialized_response =
json::parse<TraceIntelPTGetStateResponse>(
llvm::formatv("{0}", toJSON(response)).str(),
"TraceIntelPTGetStateResponse");
if (!deserialized_response)
FAIL() << toString(deserialized_response.takeError());
// Check equality:
// Ensure that both the TraceGetStateResponse and TraceIntelPTGetStateResponse
// portions of the JSON representation are unchanged.
ASSERT_EQ(toJSON(response), toJSON(*deserialized_response));
// Ensure that the tsc_conversion's are nullptr.
ASSERT_FALSE((bool)response.tsc_perf_zero_conversion);
ASSERT_FALSE((bool)deserialized_response->tsc_perf_zero_conversion);
}