1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <trace-reader/reader.h>
6
7 #include <stdint.h>
8
9 #include <fbl/algorithm.h>
10 #include <fbl/vector.h>
11 #include <unittest/unittest.h>
12
13 #include <utility>
14
15 namespace {
16
17 template <typename T>
ToWord(const T & value)18 uint64_t ToWord(const T& value) {
19 return *reinterpret_cast<const uint64_t*>(&value);
20 }
21
MakeRecordConsumer(fbl::Vector<trace::Record> * out_records)22 trace::TraceReader::RecordConsumer MakeRecordConsumer(
23 fbl::Vector<trace::Record>* out_records) {
24 return [out_records](trace::Record record) {
25 out_records->push_back(std::move(record));
26 };
27 }
28
MakeErrorHandler(fbl::String * out_error)29 trace::TraceReader::ErrorHandler MakeErrorHandler(fbl::String* out_error) {
30 return [out_error](fbl::String error) {
31 *out_error = std::move(error);
32 };
33 }
34
empty_chunk_test()35 bool empty_chunk_test() {
36 BEGIN_TEST;
37
38 uint64_t value;
39 int64_t int64_value;
40 double double_value;
41 fbl::StringPiece string_value;
42 trace::Chunk subchunk;
43
44 trace::Chunk empty;
45 EXPECT_EQ(0u, empty.remaining_words());
46
47 EXPECT_FALSE(empty.ReadUint64(&value));
48
49 EXPECT_FALSE(empty.ReadInt64(&int64_value));
50
51 EXPECT_FALSE(empty.ReadDouble(&double_value));
52
53 EXPECT_TRUE(empty.ReadString(0u, &string_value));
54 EXPECT_TRUE(string_value.empty());
55 EXPECT_FALSE(empty.ReadString(1u, &string_value));
56
57 EXPECT_TRUE(empty.ReadChunk(0u, &subchunk));
58 EXPECT_EQ(0u, subchunk.remaining_words());
59 EXPECT_FALSE(empty.ReadChunk(1u, &subchunk));
60
61 END_TEST;
62 }
63
non_empty_chunk_test()64 bool non_empty_chunk_test() {
65 BEGIN_TEST;
66
67 uint64_t value;
68 int64_t int64_value;
69 double double_value;
70 fbl::StringPiece string_value;
71 trace::Chunk subchunk;
72
73 uint64_t kData[] = {
74 // uint64 values
75 0,
76 UINT64_MAX,
77 // int64 values
78 ToWord(INT64_MIN),
79 ToWord(INT64_MAX),
80 // double values
81 ToWord(1.5),
82 ToWord(-3.14),
83 // string values (will be filled in)
84 0,
85 0,
86 // sub-chunk values
87 123,
88 456,
89 // more stuff beyond sub-chunk
90 789,
91 };
92 memcpy(kData + 6, "Hello World!----", 16);
93
94 trace::Chunk chunk(kData, fbl::count_of(kData));
95 EXPECT_EQ(fbl::count_of(kData), chunk.remaining_words());
96
97 EXPECT_TRUE(chunk.ReadUint64(&value));
98 EXPECT_EQ(0, value);
99 EXPECT_EQ(10u, chunk.remaining_words());
100
101 EXPECT_TRUE(chunk.ReadUint64(&value));
102 EXPECT_EQ(UINT64_MAX, value);
103 EXPECT_EQ(9u, chunk.remaining_words());
104
105 EXPECT_TRUE(chunk.ReadInt64(&int64_value));
106 EXPECT_EQ(INT64_MIN, int64_value);
107 EXPECT_EQ(8u, chunk.remaining_words());
108
109 EXPECT_TRUE(chunk.ReadInt64(&int64_value));
110 EXPECT_EQ(INT64_MAX, int64_value);
111 EXPECT_EQ(7u, chunk.remaining_words());
112
113 EXPECT_TRUE(chunk.ReadDouble(&double_value));
114 EXPECT_EQ(1.5, double_value);
115 EXPECT_EQ(6u, chunk.remaining_words());
116
117 EXPECT_TRUE(chunk.ReadDouble(&double_value));
118 EXPECT_EQ(-3.14, double_value);
119 EXPECT_EQ(5u, chunk.remaining_words());
120
121 EXPECT_TRUE(chunk.ReadString(0u, &string_value));
122 EXPECT_TRUE(string_value.empty());
123 EXPECT_EQ(5u, chunk.remaining_words());
124
125 EXPECT_TRUE(chunk.ReadString(12u, &string_value));
126 EXPECT_EQ(12u, string_value.length());
127 EXPECT_EQ(reinterpret_cast<const char*>(kData + 6), string_value.data());
128 EXPECT_TRUE(fbl::String(string_value) == "Hello World!");
129 EXPECT_EQ(3u, chunk.remaining_words());
130
131 EXPECT_TRUE(chunk.ReadChunk(2u, &subchunk));
132 EXPECT_EQ(2u, subchunk.remaining_words());
133 EXPECT_TRUE(subchunk.ReadUint64(&value));
134
135 EXPECT_EQ(123, value);
136 EXPECT_EQ(1u, subchunk.remaining_words());
137
138 EXPECT_TRUE(chunk.ReadUint64(&value));
139 EXPECT_EQ(789, value);
140 EXPECT_EQ(0u, chunk.remaining_words());
141
142 EXPECT_TRUE(subchunk.ReadUint64(&value));
143 EXPECT_EQ(456, value);
144 EXPECT_EQ(0u, subchunk.remaining_words());
145
146 EXPECT_FALSE(subchunk.ReadUint64(&value));
147 EXPECT_FALSE(chunk.ReadUint64(&value));
148
149 END_TEST;
150 }
151
initial_state_test()152 bool initial_state_test() {
153 BEGIN_TEST;
154
155 fbl::Vector<trace::Record> records;
156 fbl::String error;
157 trace::TraceReader reader(MakeRecordConsumer(&records), MakeErrorHandler(&error));
158
159 EXPECT_EQ(0, reader.current_provider_id());
160 EXPECT_TRUE(reader.current_provider_name() == "");
161 EXPECT_TRUE(reader.GetProviderName(0) == "");
162 EXPECT_EQ(0, records.size());
163 EXPECT_TRUE(error.empty());
164
165 END_TEST;
166 }
167
empty_buffer_test()168 bool empty_buffer_test() {
169 BEGIN_TEST;
170
171 fbl::Vector<trace::Record> records;
172 fbl::String error;
173 trace::TraceReader reader(MakeRecordConsumer(&records), MakeErrorHandler(&error));
174
175 trace::Chunk empty;
176 EXPECT_TRUE(reader.ReadRecords(empty));
177 EXPECT_EQ(0, records.size());
178 EXPECT_TRUE(error.empty());
179
180 END_TEST;
181 }
182
183 // NOTE: Most of the reader is covered by the libtrace tests.
184
185 } // namespace
186
187 BEGIN_TEST_CASE(reader_tests)
188 RUN_TEST(empty_chunk_test)
189 RUN_TEST(non_empty_chunk_test)
190 RUN_TEST(initial_state_test)
191 RUN_TEST(empty_buffer_test)
192 END_TEST_CASE(reader_tests)
193