1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #define PW_TRACE_MODULE_NAME "TST"
16
17 #include "pw_trace_tokenized/trace_buffer.h"
18
19 #include "gtest/gtest.h"
20 #include "pw_trace/trace.h"
21
TEST(TokenizedTrace,Simple)22 TEST(TokenizedTrace, Simple) {
23 PW_TRACE_SET_ENABLED(true);
24 pw::trace::ClearBuffer();
25
26 PW_TRACE_INSTANT("Test");
27
28 // Check results
29 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
30
31 EXPECT_EQ(buf->EntryCount(), 1u);
32 const size_t expected_min_bytes_used =
33 1 /*varint size */ + 4 /*token*/ + 1 /* min varint time */;
34 const size_t expected_max_bytes_used = 1 /*varint size */ + 4 /*token*/ +
35 sizeof(PW_TRACE_TIME_TYPE) +
36 1 /* max varint time */;
37
38 EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
39 EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
40 }
41
TEST(TokenizedTrace,TraceId)42 TEST(TokenizedTrace, TraceId) {
43 PW_TRACE_SET_ENABLED(true);
44 pw::trace::ClearBuffer();
45
46 uint32_t trace_id = 256;
47 PW_TRACE_INSTANT("Test", "group", trace_id);
48
49 // Check results
50 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
51
52 EXPECT_EQ(buf->EntryCount(), 1u);
53 const size_t expected_min_bytes_used = 1 /*varint size */ + 4 /*token*/ +
54 1 /* min varint time */ +
55 2 /*varint trace id*/;
56 const size_t expected_max_bytes_used =
57 1 /*varint size */ + 4 /*token*/ + sizeof(PW_TRACE_TIME_TYPE) +
58 1 /* max varint time */ + 2 /*varint trace id*/;
59
60 EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
61 EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
62 }
63
TEST(TokenizedTrace,Data)64 TEST(TokenizedTrace, Data) {
65 PW_TRACE_SET_ENABLED(true);
66 pw::trace::ClearBuffer();
67
68 char data[] = "some test data";
69 PW_TRACE_INSTANT_DATA("Test", "test_data", data, sizeof(data));
70
71 // Check results
72 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
73
74 EXPECT_EQ(buf->EntryCount(), 1u);
75 const size_t expected_min_bytes_used =
76 1 /*varint size */ + 4 /*token*/ + 1 /* min varint time */ + sizeof(data);
77 const size_t expected_max_bytes_used = 1 /*varint size */ + 4 /*token*/ +
78 sizeof(PW_TRACE_TIME_TYPE) +
79 1 /* max varint time */ + sizeof(data);
80
81 EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
82 EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
83
84 std::byte value[expected_max_bytes_used];
85 size_t bytes_read = 0;
86 EXPECT_EQ(buf->PeekFront(std::span<std::byte>(value), &bytes_read),
87 pw::OkStatus());
88
89 // read size is minus 1, since doesn't include varint size
90 EXPECT_GE(bytes_read, expected_min_bytes_used - 1);
91 EXPECT_LE(bytes_read, expected_max_bytes_used - 1);
92 EXPECT_STREQ(data,
93 reinterpret_cast<char*>(&value[bytes_read - sizeof(data)]));
94 }
95
TEST(TokenizedTrace,Clear)96 TEST(TokenizedTrace, Clear) {
97 PW_TRACE_SET_ENABLED(true);
98 pw::trace::ClearBuffer();
99 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
100
101 PW_TRACE_INSTANT("Test");
102 EXPECT_EQ(buf->EntryCount(), 1u);
103 pw::trace::ClearBuffer();
104 EXPECT_EQ(buf->EntryCount(), 0u);
105 }
106
TEST(TokenizedTrace,Overflow)107 TEST(TokenizedTrace, Overflow) {
108 PW_TRACE_SET_ENABLED(true);
109 pw::trace::ClearBuffer();
110 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
111
112 // Add samples until entry count stops increasing.
113 uint32_t last_entry_count = 0;
114 size_t count = 0;
115 while (buf->EntryCount() == 0 || buf->EntryCount() > last_entry_count) {
116 last_entry_count = buf->EntryCount();
117 PW_TRACE_INSTANT_DATA("Test", "count", &count, sizeof(count));
118 count++;
119 }
120 // CHECK
121 size_t expected_count = 1; // skip first (since it was lost)
122 while (buf->EntryCount() > 0) {
123 std::byte value[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
124 size_t bytes_read = 0;
125 EXPECT_EQ(buf->PeekFront(std::span<std::byte>(value), &bytes_read),
126 pw::OkStatus());
127 EXPECT_EQ(buf->PopFront(), pw::OkStatus());
128 size_t entry_count;
129 memcpy(
130 &entry_count, &value[bytes_read - sizeof(size_t)], sizeof(entry_count));
131 EXPECT_EQ(entry_count, expected_count);
132 expected_count++;
133 }
134
135 EXPECT_EQ(count, expected_count);
136 }
137
TEST(TokenizedTrace,BlockTooLarge)138 TEST(TokenizedTrace, BlockTooLarge) {
139 PW_TRACE_SET_ENABLED(true);
140 pw::trace::ClearBuffer();
141 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
142 uint8_t data[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
143 PW_TRACE_INSTANT_DATA("Test", "data", data, sizeof(data));
144 EXPECT_EQ(buf->EntryCount(), 0u);
145 }
146
TEST(TokenizedTrace,DeringAndViewRawBuffer)147 TEST(TokenizedTrace, DeringAndViewRawBuffer) {
148 PW_TRACE_SET_ENABLED(true);
149 pw::trace::ClearBuffer();
150
151 // Should be empty span
152 pw::ConstByteSpan buf = pw::trace::DeringAndViewRawBuffer();
153 EXPECT_EQ(buf.size(), 0u);
154
155 // Should now have data
156 PW_TRACE_INSTANT("Test");
157 buf = pw::trace::DeringAndViewRawBuffer();
158 EXPECT_GT(buf.size(), 0u);
159
160 // Should now have more data
161 PW_TRACE_INSTANT("Test");
162 size_t size_start = buf.size();
163 buf = pw::trace::DeringAndViewRawBuffer();
164 EXPECT_GT(buf.size(), size_start);
165 }
166