/* * 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 #include #include #include #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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(strlen(data)); constexpr std::size_t chreTraceDataSize = tracing_internal::chreTraceGetSizeOfVarArgs(); 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(); 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(); 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(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(); 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