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 "pw_trace/trace.h"
20 #include "pw_unit_test/framework.h"
21
22 namespace {
23
TEST(TokenizedTrace,Simple)24 TEST(TokenizedTrace, Simple) {
25 PW_TRACE_SET_ENABLED(true);
26 pw::trace::ClearBuffer();
27
28 PW_TRACE_INSTANT("Test");
29
30 // Check results
31 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
32
33 EXPECT_EQ(buf->EntryCount(), 1u);
34 const size_t expected_min_bytes_used =
35 1 /*varint size */ + 4 /*token*/ + 1 /* min varint time */;
36 const size_t expected_max_bytes_used = 1 /*varint size */ + 4 /*token*/ +
37 sizeof(PW_TRACE_TIME_TYPE) +
38 1 /* max varint time */;
39
40 EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
41 EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
42 }
43
TEST(TokenizedTrace,TraceId)44 TEST(TokenizedTrace, TraceId) {
45 PW_TRACE_SET_ENABLED(true);
46 pw::trace::ClearBuffer();
47
48 uint32_t trace_id = 256;
49 PW_TRACE_INSTANT("Test", "group", trace_id);
50
51 // Check results
52 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
53
54 EXPECT_EQ(buf->EntryCount(), 1u);
55 const size_t expected_min_bytes_used = 1 /*varint size */ + 4 /*token*/ +
56 1 /* min varint time */ +
57 2 /*varint trace id*/;
58 const size_t expected_max_bytes_used =
59 1 /*varint size */ + 4 /*token*/ + sizeof(PW_TRACE_TIME_TYPE) +
60 1 /* max varint time */ + 2 /*varint trace id*/;
61
62 EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
63 EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
64 }
65
TEST(TokenizedTrace,Data)66 TEST(TokenizedTrace, Data) {
67 PW_TRACE_SET_ENABLED(true);
68 pw::trace::ClearBuffer();
69
70 char data[] = "some test data";
71 PW_TRACE_INSTANT_DATA("Test", "test_data", data, sizeof(data));
72
73 // Check results
74 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
75
76 EXPECT_EQ(buf->EntryCount(), 1u);
77 const size_t expected_min_bytes_used =
78 1 /*varint size */ + 4 /*token*/ + 1 /* min varint time */ + sizeof(data);
79 const size_t expected_max_bytes_used = 1 /*varint size */ + 4 /*token*/ +
80 sizeof(PW_TRACE_TIME_TYPE) +
81 1 /* max varint time */ + sizeof(data);
82
83 EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
84 EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
85
86 std::byte value[expected_max_bytes_used];
87 size_t bytes_read = 0;
88 EXPECT_EQ(buf->PeekFront(pw::span<std::byte>(value), &bytes_read),
89 pw::OkStatus());
90
91 // read size is minus 1, since doesn't include varint size
92 EXPECT_GE(bytes_read, expected_min_bytes_used - 1);
93 EXPECT_LE(bytes_read, expected_max_bytes_used - 1);
94 EXPECT_STREQ(data,
95 reinterpret_cast<char*>(&value[bytes_read - sizeof(data)]));
96 }
97
TEST(TokenizedTrace,Clear)98 TEST(TokenizedTrace, Clear) {
99 PW_TRACE_SET_ENABLED(true);
100 pw::trace::ClearBuffer();
101 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
102
103 PW_TRACE_INSTANT("Test");
104 EXPECT_EQ(buf->EntryCount(), 1u);
105 pw::trace::ClearBuffer();
106 EXPECT_EQ(buf->EntryCount(), 0u);
107 }
108
TEST(TokenizedTrace,Overflow)109 TEST(TokenizedTrace, Overflow) {
110 PW_TRACE_SET_ENABLED(true);
111 pw::trace::ClearBuffer();
112 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
113
114 // Add samples until entry count stops increasing.
115 uint32_t last_entry_count = 0;
116 size_t count = 0;
117 while (buf->EntryCount() == 0 || buf->EntryCount() > last_entry_count) {
118 last_entry_count = buf->EntryCount();
119 PW_TRACE_INSTANT_DATA("Test", "count", &count, sizeof(count));
120 count++;
121 }
122 // CHECK
123 size_t expected_count = 1; // skip first (since it was lost)
124 while (buf->EntryCount() > 0) {
125 std::byte value[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
126 size_t bytes_read = 0;
127 EXPECT_EQ(buf->PeekFront(pw::span<std::byte>(value), &bytes_read),
128 pw::OkStatus());
129 EXPECT_EQ(buf->PopFront(), pw::OkStatus());
130 size_t entry_count;
131 memcpy(
132 &entry_count, &value[bytes_read - sizeof(size_t)], sizeof(entry_count));
133 EXPECT_EQ(entry_count, expected_count);
134 expected_count++;
135 }
136
137 EXPECT_EQ(count, expected_count);
138 }
139
TEST(TokenizedTrace,BlockTooLarge)140 TEST(TokenizedTrace, BlockTooLarge) {
141 PW_TRACE_SET_ENABLED(true);
142 pw::trace::ClearBuffer();
143 pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
144 uint8_t data[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
145 PW_TRACE_INSTANT_DATA("Test", "data", data, sizeof(data));
146 EXPECT_EQ(buf->EntryCount(), 0u);
147 }
148
TEST(TokenizedTrace,DeringAndViewRawBuffer)149 TEST(TokenizedTrace, DeringAndViewRawBuffer) {
150 PW_TRACE_SET_ENABLED(true);
151 pw::trace::ClearBuffer();
152
153 // Should be empty span
154 pw::ConstByteSpan buf = pw::trace::DeringAndViewRawBuffer();
155 EXPECT_EQ(buf.size(), 0u);
156
157 // Should now have data
158 PW_TRACE_INSTANT("Test");
159 buf = pw::trace::DeringAndViewRawBuffer();
160 EXPECT_GT(buf.size(), 0u);
161
162 // Should now have more data
163 PW_TRACE_INSTANT("Test");
164 size_t size_start = buf.size();
165 buf = pw::trace::DeringAndViewRawBuffer();
166 EXPECT_GT(buf.size(), size_start);
167 }
168
169 } // namespace
170