1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // Ensuring this macro is not defined since we include the tracing macros and
18 // tracing utilities separately and do not want to test or include the pw_trace
19 // functions.
20 #ifdef CHRE_TRACING_ENABLED
21 #undef CHRE_TRACING_ENABLED
22 #endif // CHRE_TRACING_ENABLED
23
24 #include <stdlib.h>
25 #include <cstdlib>
26 #include <cstring>
27 #include <string>
28
29 #include "chre/platform/tracing.h"
30 #include "chre/target_platform/tracing_util.h"
31 #include "gmock/gmock.h"
32 #include "gtest/gtest.h"
33
34 namespace tracing_internal {
35 namespace {
36
37 using ::testing::ElementsAre;
38 using ::testing::ElementsAreArray;
39
TEST(Trace,PopulateBufferWithTracedPtr)40 TEST(Trace, PopulateBufferWithTracedPtr) {
41 const uint8_t var = 0x12;
42 const uint8_t *data = &var;
43
44 constexpr std::size_t chreTraceDataSize =
45 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
46
47 EXPECT_EQ(chreTraceDataSize, __SIZEOF_POINTER__);
48
49 uint8_t chreTraceDataBuffer[chreTraceDataSize];
50 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
51
52 // Already verified in chre/platform/tracing.h this value is either 8 or 4.
53 #if __SIZEOF_POINTER__ == 8
54 EXPECT_EQ(*((uint64_t *)chreTraceDataBuffer), (uint64_t)data);
55 #elif __SIZEOF_POINTER__ == 4
56 EXPECT_EQ(*((uint32_t *)chreTraceDataBuffer), (uint32_t)data);
57 #else
58 #error "Pointer size is of unsupported size"
59 #endif
60 }
61
TEST(Trace,PopulateBufferWithTracedBool)62 TEST(Trace, PopulateBufferWithTracedBool) {
63 const bool data = true;
64
65 constexpr std::size_t chreTraceDataSize =
66 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
67
68 EXPECT_EQ(chreTraceDataSize, sizeof(bool));
69
70 uint8_t chreTraceDataBuffer[chreTraceDataSize];
71 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
72
73 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(1));
74 }
75
TEST(Trace,PopulateBufferWithTracedUInt8)76 TEST(Trace, PopulateBufferWithTracedUInt8) {
77 const uint8_t data = 0x12;
78
79 constexpr std::size_t chreTraceDataSize =
80 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
81
82 EXPECT_EQ(chreTraceDataSize, sizeof(uint8_t));
83
84 uint8_t chreTraceDataBuffer[chreTraceDataSize];
85 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
86
87 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x12));
88 }
89
TEST(Trace,PopulateBufferWithTracedUInt16)90 TEST(Trace, PopulateBufferWithTracedUInt16) {
91 uint16_t data = 0x1234;
92
93 constexpr std::size_t chreTraceDataSize =
94 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
95
96 EXPECT_EQ(chreTraceDataSize, sizeof(uint16_t));
97
98 uint8_t chreTraceDataBuffer[chreTraceDataSize];
99 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
100
101 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x34, 0x12));
102 }
103
TEST(Trace,PopulateBufferWithTracedUInt32)104 TEST(Trace, PopulateBufferWithTracedUInt32) {
105 const uint32_t data = 0x12345678;
106
107 constexpr std::size_t chreTraceDataSize =
108 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
109
110 EXPECT_EQ(chreTraceDataSize, sizeof(uint32_t));
111
112 uint8_t chreTraceDataBuffer[chreTraceDataSize];
113 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
114
115 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x78, 0x56, 0x34, 0x12));
116 }
117
TEST(Trace,PopulateBufferWithTracedUInt64)118 TEST(Trace, PopulateBufferWithTracedUInt64) {
119 const uint64_t data = 0x1234567890123456;
120
121 constexpr std::size_t chreTraceDataSize =
122 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
123
124 EXPECT_EQ(chreTraceDataSize, sizeof(uint64_t));
125
126 uint8_t chreTraceDataBuffer[chreTraceDataSize];
127 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
128
129 EXPECT_THAT(chreTraceDataBuffer,
130 ElementsAre(0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12));
131 }
132
TEST(Trace,PopulateBufferWithTracedInt8)133 TEST(Trace, PopulateBufferWithTracedInt8) {
134 const int8_t data = 0x12;
135
136 constexpr std::size_t chreTraceDataSize =
137 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
138
139 EXPECT_EQ(chreTraceDataSize, sizeof(int8_t));
140
141 uint8_t chreTraceDataBuffer[chreTraceDataSize];
142 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
143
144 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x12));
145 }
146
TEST(Trace,PopulateBufferWithTracedInt16)147 TEST(Trace, PopulateBufferWithTracedInt16) {
148 const int16_t data = 0x1234;
149
150 constexpr std::size_t chreTraceDataSize =
151 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
152
153 EXPECT_EQ(chreTraceDataSize, sizeof(int16_t));
154
155 uint8_t chreTraceDataBuffer[chreTraceDataSize];
156 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
157
158 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x34, 0x12));
159 }
160
TEST(Trace,PopulateBufferWithTracedInt32)161 TEST(Trace, PopulateBufferWithTracedInt32) {
162 const int32_t data = 0x12345678;
163
164 constexpr std::size_t chreTraceDataSize =
165 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
166
167 EXPECT_EQ(chreTraceDataSize, sizeof(int32_t));
168
169 uint8_t chreTraceDataBuffer[chreTraceDataSize];
170 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
171
172 EXPECT_THAT(chreTraceDataBuffer, ElementsAre(0x78, 0x56, 0x34, 0x12));
173 }
174
TEST(Trace,PopulateBufferWithTracedInt64)175 TEST(Trace, PopulateBufferWithTracedInt64) {
176 const int64_t data = 0x1234567890123456;
177
178 constexpr std::size_t chreTraceDataSize =
179 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
180
181 EXPECT_EQ(chreTraceDataSize, sizeof(int64_t));
182
183 uint8_t chreTraceDataBuffer[chreTraceDataSize];
184 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
185
186 EXPECT_THAT(chreTraceDataBuffer,
187 ElementsAre(0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12));
188 }
189
TEST(Trace,PopulateBufferWithTracedChar)190 TEST(Trace, PopulateBufferWithTracedChar) {
191 char data = 'a';
192
193 constexpr std::size_t chreTraceDataSize =
194 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
195
196 EXPECT_EQ(chreTraceDataSize, sizeof(char));
197
198 uint8_t chreTraceDataBuffer[chreTraceDataSize];
199 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
200
201 EXPECT_THAT(chreTraceDataBuffer, ElementsAre('a'));
202 }
203
TEST(Trace,PopulateBufferWithTracedStrDoesNotOverflow)204 TEST(Trace, PopulateBufferWithTracedStrDoesNotOverflow) {
205 const char data[] = "test";
206 const size_t kBufferPadding = 5;
207
208 constexpr std::size_t chreTraceDataSize =
209 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
210
211 uint8_t chreTraceDataBuffer[chreTraceDataSize + kBufferPadding];
212 memset(chreTraceDataBuffer, 0xFF, chreTraceDataSize + kBufferPadding);
213 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
214
215 for (std::size_t i = 0; i < kBufferPadding; i++) {
216 EXPECT_EQ(chreTraceDataBuffer[chreTraceDataSize + i], 0xFF);
217 }
218 }
219
TEST(Trace,PopulateBufferWithTracedShortStrAndNullBytePadding)220 TEST(Trace, PopulateBufferWithTracedShortStrAndNullBytePadding) {
221 // expected variable + length
222 const char data[] = "test";
223 uint8_t dataLen = static_cast<uint8_t>(strlen(data));
224
225 constexpr std::size_t chreTraceDataSize =
226 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(data)>();
227
228 EXPECT_EQ(chreTraceDataSize, CHRE_TRACE_STR_BUFFER_SIZE);
229
230 uint8_t chreTraceDataBuffer[chreTraceDataSize];
231 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer, data);
232
233 // Fully populated buffer with data len and null-byte padding at the end.
234 uint8_t expectedBuffer[CHRE_TRACE_STR_BUFFER_SIZE] = {dataLen, 't', 'e', 's',
235 't'};
236 for (std::size_t i = dataLen + 1; i < CHRE_TRACE_STR_BUFFER_SIZE; i++) {
237 expectedBuffer[i] = '\0';
238 }
239
240 EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
241 }
242
TEST(Trace,PopulateBufferWithTracedMaxLenStrNoPadding)243 TEST(Trace, PopulateBufferWithTracedMaxLenStrNoPadding) {
244 // String data buffer to hold max-len string.
245 char dataBuffer[CHRE_TRACE_MAX_STRING_SIZE + 1];
246 // Fully populated buffer with data len and no null-byte padding.
247 // In this case data len should equal CHRE_TRACE_MAX_STRING_SIZE.
248 uint8_t expectedBuffer[CHRE_TRACE_STR_BUFFER_SIZE] = {
249 CHRE_TRACE_MAX_STRING_SIZE};
250
251 // Populate the buffer with str "0123456789..." until we hit max size.
252 for (std::size_t i = 0; i < CHRE_TRACE_MAX_STRING_SIZE; i++) {
253 dataBuffer[i] = '0' + (i % 10);
254 expectedBuffer[i + 1] = '0' + (i % 10);
255 }
256 dataBuffer[CHRE_TRACE_MAX_STRING_SIZE] = '\0';
257
258 constexpr std::size_t chreTraceDataSize =
259 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(dataBuffer)>();
260
261 EXPECT_EQ(chreTraceDataSize, CHRE_TRACE_STR_BUFFER_SIZE);
262
263 uint8_t chreTraceDataBuffer[chreTraceDataSize];
264 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer,
265 dataBuffer);
266
267 EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
268 }
269
TEST(Trace,PopulateBufferWithTracedStringTuncateToMaxLength)270 TEST(Trace, PopulateBufferWithTracedStringTuncateToMaxLength) {
271 const size_t kBufferPadding = 5;
272 const std::size_t kOversizeStrLen =
273 CHRE_TRACE_MAX_STRING_SIZE + kBufferPadding;
274 // String data buffer to hold oversized string.
275 char dataBuffer[kOversizeStrLen + 1];
276
277 // Populate the buffer with str "0123456789..." until we hit kOversizeStrLen.
278 for (std::size_t i = 0; i < kOversizeStrLen; i++) {
279 dataBuffer[i] = '0' + (i % 10);
280 }
281 dataBuffer[kOversizeStrLen] = '\0';
282
283 constexpr std::size_t chreTraceDataSize =
284 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(dataBuffer)>();
285
286 EXPECT_EQ(chreTraceDataSize, CHRE_TRACE_STR_BUFFER_SIZE);
287
288 uint8_t chreTraceDataBuffer[chreTraceDataSize];
289 tracing_internal::chreTracePopulateBufferWithArgs(chreTraceDataBuffer,
290 dataBuffer);
291
292 // Fully populated buffer with data len and truncated string.
293 // In this case data len should equal CHRE_TRACE_MAX_STRING_SIZE, not
294 // kOversizeStrLen.
295 uint8_t expectedBuffer[CHRE_TRACE_STR_BUFFER_SIZE] = {
296 CHRE_TRACE_MAX_STRING_SIZE};
297
298 // Populate the buffer with str "0123456789..." until we hit
299 // CHRE_TRACE_MAX_STRING_SIZE.
300 for (std::size_t i = 0; i < CHRE_TRACE_MAX_STRING_SIZE; i++) {
301 expectedBuffer[i + 1] = '0' + (i % 10);
302 }
303
304 EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
305 }
306
TEST(Trace,PopulateBufferWithMultipleTracedData)307 TEST(Trace, PopulateBufferWithMultipleTracedData) {
308 uint8_t dataUint8 = 0x12;
309 char dataChar = 'a';
310 uint32_t dataUint32 = 0x12345678;
311 char dataStr[CHRE_TRACE_MAX_STRING_SIZE];
312 strncpy(dataStr, "test", CHRE_TRACE_MAX_STRING_SIZE);
313 uint8_t dataStrLen = static_cast<uint8_t>(strlen(dataStr));
314 std::size_t totalDataSize = sizeof(uint8_t) + sizeof(char) +
315 sizeof(uint32_t) + CHRE_TRACE_STR_BUFFER_SIZE;
316
317 constexpr std::size_t chreTraceDataSize =
318 tracing_internal::chreTraceGetSizeOfVarArgs<TYPE_LIST(
319 dataUint8, dataChar, dataUint32, dataStr)>();
320
321 EXPECT_EQ(chreTraceDataSize, totalDataSize);
322
323 uint8_t expectedBuffer[chreTraceDataSize] = {0x12, 'a', 0x78, 0x56,
324 0x34, 0x12, dataStrLen};
325 strncpy((char *)(&expectedBuffer[7]), dataStr, CHRE_TRACE_MAX_STRING_SIZE);
326
327 uint8_t chreTraceDataBuffer[chreTraceDataSize];
328 tracing_internal::chreTracePopulateBufferWithArgs(
329 chreTraceDataBuffer, dataUint8, dataChar, dataUint32, dataStr);
330
331 EXPECT_THAT(chreTraceDataBuffer, ElementsAreArray(expectedBuffer));
332 }
333
334 // TODO(b/302232350): Add a death test for unsupported data types. Currently
335 // testing unsupported types (structs) with manual testing.
336
337 } // namespace
338 } // namespace tracing_internal