blob: ce162a5645e9a7bac009392440518a35cd9d11b6 [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Ensuring this macro is not defined since we include the tracing macros and
// tracing utilities separately and do not want to test or include the pw_trace
// functions.
#ifdef CHRE_TRACING_ENABLED
#undef CHRE_TRACING_ENABLED
#endif // CHRE_TRACING_ENABLED
#include <stdlib.h>
#include <cstdlib>
#include <cstring>
#include <string>
#include "chre/platform/tracing.h"
#include "chre/target_platform/tracing_util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace tracing_internal {
namespace {
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
TEST(Trace, PopulateBufferWithTracedPtr) {
const uint8_t var = 0x12;
const uint8_t *data = &var;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, __SIZEOF_POINTER__);
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
// Already verified in chre/platform/tracing.h this value is either 8 or 4.
#if __SIZEOF_POINTER__ == 8
EXPECT_EQ(*((uint64_t *)chreTraceDataBuffer), (uint64_t)data);
#elif __SIZEOF_POINTER__ == 4
EXPECT_EQ(*((uint32_t *)chreTraceDataBuffer), (uint32_t)data);
#else
#error "Pointer size is of unsupported size"
#endif
}
TEST(Trace, PopulateBufferWithTracedBool) {
const bool data = true;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(bool));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(1));
}
TEST(Trace, PopulateBufferWithTracedUInt8) {
const uint8_t data = 0x12;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(uint8_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x12));
}
TEST(Trace, PopulateBufferWithTracedUInt16) {
uint16_t data = 0x1234;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(uint16_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x34, 0x12));
}
TEST(Trace, PopulateBufferWithTracedUInt32) {
const uint32_t data = 0x12345678;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(uint32_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x78, 0x56, 0x34, 0x12));
}
TEST(Trace, PopulateBufferWithTracedUInt64) {
const uint64_t data = 0x1234567890123456;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(uint64_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer,
ElementsAre(0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12));
}
TEST(Trace, PopulateBufferWithTracedInt8) {
const int8_t data = 0x12;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(int8_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x12));
}
TEST(Trace, PopulateBufferWithTracedInt16) {
const int16_t data = 0x1234;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(int16_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x34, 0x12));
}
TEST(Trace, PopulateBufferWithTracedInt32) {
const int32_t data = 0x12345678;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(int32_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x78, 0x56, 0x34, 0x12));
}
TEST(Trace, PopulateBufferWithTracedInt64) {
const int64_t data = 0x1234567890123456;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(int64_t));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer,
ElementsAre(0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12));
}
TEST(Trace, PopulateBufferWithTracedChar) {
char data = 'a';
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, sizeof(char));
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
EXPECT_THAT(chreTraceDataBuffer, ElementsAre('a'));
}
TEST(Trace, PopulateBufferWithTracedStrDoesNotOverflow) {
const char data[] = "test";
const size_t kBufferPadding = 5;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
uint8_t chreTraceDataBuffer[chreTraceDataSize + kBufferPadding];
memset(chreTraceDataBuffer, 0xFF, chreTraceDataSize + kBufferPadding);
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
for (std::size_t i = 0; i < kBufferPadding; i++) {
EXPECT_EQ(chreTraceDataBuffer[chreTraceDataSize + i], 0xFF);
}
}
TEST(Trace, PopulateBufferWithTracedShortStrAndNullBytePadding) {
// expected variable + length
const char data[] = "test";
uint8_t dataLen = static_cast<uint8_t>(strlen(data));
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
EXPECT_EQ(chreTraceDataSize, CHRE_TRACE_STR_BUFFER_SIZE);
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
// Fully populated buffer with data len and null-byte padding at the end.
uint8_t expectedBuffer[CHRE_TRACE_STR_BUFFER_SIZE] = {dataLen, 't', 'e', 's',
't'};
for (std::size_t i = dataLen + 1; i < CHRE_TRACE_STR_BUFFER_SIZE; i++) {
expectedBuffer[i] = '\0';
}
EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
}
TEST(Trace, PopulateBufferWithTracedMaxLenStrNoPadding) {
// String data buffer to hold max-len string.
char dataBuffer[CHRE_TRACE_MAX_STRING_SIZE + 1];
// Fully populated buffer with data len and no null-byte padding.
// In this case data len should equal CHRE_TRACE_MAX_STRING_SIZE.
uint8_t expectedBuffer[CHRE_TRACE_STR_BUFFER_SIZE] = {
CHRE_TRACE_MAX_STRING_SIZE};
// Populate the buffer with str "0123456789..." until we hit max size.
for (std::size_t i = 0; i < CHRE_TRACE_MAX_STRING_SIZE; i++) {
dataBuffer[i] = '0' + (i % 10);
expectedBuffer[i + 1] = '0' + (i % 10);
}
dataBuffer[CHRE_TRACE_MAX_STRING_SIZE] = '\0';
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(dataBuffer)>();
EXPECT_EQ(chreTraceDataSize, CHRE_TRACE_STR_BUFFER_SIZE);
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer,
dataBuffer);
EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
}
TEST(Trace, PopulateBufferWithTracedStringTuncateToMaxLength) {
const size_t kBufferPadding = 5;
const std::size_t kOversizeStrLen =
CHRE_TRACE_MAX_STRING_SIZE + kBufferPadding;
// String data buffer to hold oversized string.
char dataBuffer[kOversizeStrLen + 1];
// Populate the buffer with str "0123456789..." until we hit kOversizeStrLen.
for (std::size_t i = 0; i < kOversizeStrLen; i++) {
dataBuffer[i] = '0' + (i % 10);
}
dataBuffer[kOversizeStrLen] = '\0';
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(dataBuffer)>();
EXPECT_EQ(chreTraceDataSize, CHRE_TRACE_STR_BUFFER_SIZE);
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer,
dataBuffer);
// Fully populated buffer with data len and truncated string.
// In this case data len should equal CHRE_TRACE_MAX_STRING_SIZE, not
// kOversizeStrLen.
uint8_t expectedBuffer[CHRE_TRACE_STR_BUFFER_SIZE] = {
CHRE_TRACE_MAX_STRING_SIZE};
// Populate the buffer with str "0123456789..." until we hit
// CHRE_TRACE_MAX_STRING_SIZE.
for (std::size_t i = 0; i < CHRE_TRACE_MAX_STRING_SIZE; i++) {
expectedBuffer[i + 1] = '0' + (i % 10);
}
EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
}
TEST(Trace, PopulateBufferWithMultipleTracedData) {
uint8_t dataUint8 = 0x12;
char dataChar = 'a';
uint32_t dataUint32 = 0x12345678;
char dataStr[CHRE_TRACE_MAX_STRING_SIZE];
strncpy(dataStr, "test", CHRE_TRACE_MAX_STRING_SIZE);
uint8_t dataStrLen = static_cast<uint8_t>(strlen(dataStr));
std::size_t totalDataSize = sizeof(uint8_t) + sizeof(char) +
sizeof(uint32_t) + CHRE_TRACE_STR_BUFFER_SIZE;
constexpr std::size_t chreTraceDataSize =
tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(
dataUint8, dataChar, dataUint32, dataStr)>();
EXPECT_EQ(chreTraceDataSize, totalDataSize);
uint8_t expectedBuffer[chreTraceDataSize] = {0x12, 'a', 0x78, 0x56,
0x34, 0x12, dataStrLen};
strncpy((char *)(&expectedBuffer[7]), dataStr, CHRE_TRACE_MAX_STRING_SIZE);
uint8_t chreTraceDataBuffer[chreTraceDataSize];
tracing_internal::chreTracePopulateBufferWithArgs(
chreTraceDataBuffer, dataUint8, dataChar, dataUint32, dataStr);
EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
}
// TODO(b/302232350): Add a death test for unsupported data types. Currently
// testing unsupported types (structs) with manual testing.
} // namespace
} // namespace tracing_internal