• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 #include "src/trace_processor/tables/macros.h"
18 
19 #include "test/gtest_and_gmock.h"
20 
21 namespace perfetto {
22 namespace trace_processor {
23 namespace {
24 
25 // @param arg_set_id {@joinable args.arg_set_id}
26 #define PERFETTO_TP_TEST_EVENT_TABLE_DEF(NAME, PARENT, C) \
27   NAME(TestEventTable, "event")                           \
28   PARENT(PERFETTO_TP_ROOT_TABLE_PARENT_DEF, C)            \
29   C(int64_t, ts, Column::Flag::kSorted)                   \
30   C(int64_t, arg_set_id)
31 PERFETTO_TP_TABLE(PERFETTO_TP_TEST_EVENT_TABLE_DEF);
32 
33 #define PERFETTO_TP_TEST_COUNTER_TABLE_DEF(NAME, PARENT, C) \
34   NAME(TestCounterTable, "counter")                         \
35   PARENT(PERFETTO_TP_TEST_EVENT_TABLE_DEF, C)               \
36   C(base::Optional<double>, value)
37 PERFETTO_TP_TABLE(PERFETTO_TP_TEST_COUNTER_TABLE_DEF);
38 
39 #define PERFETTO_TP_TEST_SLICE_TABLE_DEF(NAME, PARENT, C) \
40   NAME(TestSliceTable, "slice")                           \
41   PARENT(PERFETTO_TP_TEST_EVENT_TABLE_DEF, C)             \
42   C(base::Optional<int64_t>, dur)                         \
43   C(int64_t, depth)
44 PERFETTO_TP_TABLE(PERFETTO_TP_TEST_SLICE_TABLE_DEF);
45 
46 #define PERFETTO_TP_TEST_CPU_SLICE_TABLE_DEF(NAME, PARENT, C) \
47   NAME(TestCpuSliceTable, "cpu_slice")                        \
48   PARENT(PERFETTO_TP_TEST_SLICE_TABLE_DEF, C)                 \
49   C(int64_t, cpu)                                             \
50   C(int64_t, priority)                                        \
51   C(StringPool::Id, end_state)
52 PERFETTO_TP_TABLE(PERFETTO_TP_TEST_CPU_SLICE_TABLE_DEF);
53 
54 TestEventTable::~TestEventTable() = default;
55 TestCounterTable::~TestCounterTable() = default;
56 TestSliceTable::~TestSliceTable() = default;
57 TestCpuSliceTable::~TestCpuSliceTable() = default;
58 
59 class TableMacrosUnittest : public ::testing::Test {
60  protected:
61   StringPool pool_;
62 
63   TestEventTable event_{&pool_, nullptr};
64   TestCounterTable counter_{&pool_, &event_};
65   TestSliceTable slice_{&pool_, &event_};
66   TestCpuSliceTable cpu_slice_{&pool_, &slice_};
67 };
68 
TEST_F(TableMacrosUnittest,Name)69 TEST_F(TableMacrosUnittest, Name) {
70   ASSERT_STREQ(event_.table_name(), "event");
71   ASSERT_STREQ(slice_.table_name(), "slice");
72   ASSERT_STREQ(cpu_slice_.table_name(), "cpu_slice");
73 }
74 
TEST_F(TableMacrosUnittest,InsertParent)75 TEST_F(TableMacrosUnittest, InsertParent) {
76   auto id = event_.Insert(TestEventTable::Row(100, 0)).id;
77   ASSERT_EQ(id.value, 0u);
78   ASSERT_EQ(event_.type().GetString(0), "event");
79   ASSERT_EQ(event_.ts()[0], 100);
80   ASSERT_EQ(event_.arg_set_id()[0], 0);
81 
82   id = slice_.Insert(TestSliceTable::Row(200, 123, 10, 0)).id;
83   ASSERT_EQ(id.value, 1u);
84 
85   ASSERT_EQ(event_.type().GetString(1), "slice");
86   ASSERT_EQ(event_.ts()[1], 200);
87   ASSERT_EQ(event_.arg_set_id()[1], 123);
88   ASSERT_EQ(slice_.type().GetString(0), "slice");
89   ASSERT_EQ(slice_.ts()[0], 200);
90   ASSERT_EQ(slice_.arg_set_id()[0], 123);
91   ASSERT_EQ(slice_.dur()[0], 10);
92   ASSERT_EQ(slice_.depth()[0], 0);
93 
94   id = slice_.Insert(TestSliceTable::Row(210, 456, base::nullopt, 0)).id;
95   ASSERT_EQ(id.value, 2u);
96 
97   ASSERT_EQ(event_.type().GetString(2), "slice");
98   ASSERT_EQ(event_.ts()[2], 210);
99   ASSERT_EQ(event_.arg_set_id()[2], 456);
100   ASSERT_EQ(slice_.type().GetString(1), "slice");
101   ASSERT_EQ(slice_.ts()[1], 210);
102   ASSERT_EQ(slice_.arg_set_id()[1], 456);
103   ASSERT_EQ(slice_.dur()[1], base::nullopt);
104   ASSERT_EQ(slice_.depth()[1], 0);
105 }
106 
TEST_F(TableMacrosUnittest,InsertChild)107 TEST_F(TableMacrosUnittest, InsertChild) {
108   event_.Insert(TestEventTable::Row(100, 0));
109   slice_.Insert(TestSliceTable::Row(200, 123, 10, 0));
110 
111   auto reason = pool_.InternString("R");
112   auto id =
113       cpu_slice_.Insert(TestCpuSliceTable::Row(205, 456, 5, 1, 4, 1024, reason))
114           .id;
115   ASSERT_EQ(id.value, 2u);
116   ASSERT_EQ(event_.type().GetString(2), "cpu_slice");
117   ASSERT_EQ(event_.ts()[2], 205);
118   ASSERT_EQ(event_.arg_set_id()[2], 456);
119 
120   ASSERT_EQ(slice_.type().GetString(1), "cpu_slice");
121   ASSERT_EQ(slice_.ts()[1], 205);
122   ASSERT_EQ(slice_.arg_set_id()[1], 456);
123   ASSERT_EQ(slice_.dur()[1], 5);
124   ASSERT_EQ(slice_.depth()[1], 1);
125 
126   ASSERT_EQ(cpu_slice_.type().GetString(0), "cpu_slice");
127   ASSERT_EQ(cpu_slice_.ts()[0], 205);
128   ASSERT_EQ(cpu_slice_.arg_set_id()[0], 456);
129   ASSERT_EQ(cpu_slice_.dur()[0], 5);
130   ASSERT_EQ(cpu_slice_.depth()[0], 1);
131   ASSERT_EQ(cpu_slice_.cpu()[0], 4);
132   ASSERT_EQ(cpu_slice_.priority()[0], 1024);
133   ASSERT_EQ(cpu_slice_.end_state()[0], reason);
134   ASSERT_EQ(cpu_slice_.end_state().GetString(0), "R");
135 }
136 
TEST_F(TableMacrosUnittest,NullableLongComparision)137 TEST_F(TableMacrosUnittest, NullableLongComparision) {
138   slice_.Insert({});
139 
140   TestSliceTable::Row row;
141   row.dur = 100;
142   slice_.Insert(row);
143 
144   row.dur = 101;
145   slice_.Insert(row);
146 
147   row.dur = 200;
148   slice_.Insert(row);
149 
150   slice_.Insert({});
151 
152   Table out = slice_.Filter({slice_.dur().is_null()});
153   const auto* dur = out.GetColumnByName("dur");
154   ASSERT_EQ(out.row_count(), 2u);
155   ASSERT_EQ(dur->Get(0).type, SqlValue::kNull);
156   ASSERT_EQ(dur->Get(1).type, SqlValue::kNull);
157 
158   out = slice_.Filter({slice_.dur().is_not_null()});
159   dur = out.GetColumnByName("dur");
160   ASSERT_EQ(out.row_count(), 3u);
161   ASSERT_EQ(dur->Get(0).long_value, 100);
162   ASSERT_EQ(dur->Get(1).long_value, 101);
163   ASSERT_EQ(dur->Get(2).long_value, 200);
164 
165   out = slice_.Filter({slice_.dur().lt(101)});
166   dur = out.GetColumnByName("dur");
167   ASSERT_EQ(out.row_count(), 1u);
168   ASSERT_EQ(dur->Get(0).long_value, 100);
169 
170   out = slice_.Filter({slice_.dur().eq(101)});
171   dur = out.GetColumnByName("dur");
172   ASSERT_EQ(out.row_count(), 1u);
173   ASSERT_EQ(dur->Get(0).long_value, 101);
174 
175   out = slice_.Filter({slice_.dur().gt(101)});
176   dur = out.GetColumnByName("dur");
177   ASSERT_EQ(out.row_count(), 1u);
178   ASSERT_EQ(dur->Get(0).long_value, 200);
179 
180   out = slice_.Filter({slice_.dur().ne(100)});
181   dur = out.GetColumnByName("dur");
182   ASSERT_EQ(out.row_count(), 2u);
183   ASSERT_EQ(dur->Get(0).long_value, 101);
184   ASSERT_EQ(dur->Get(1).long_value, 200);
185 
186   out = slice_.Filter({slice_.dur().le(101)});
187   dur = out.GetColumnByName("dur");
188   ASSERT_EQ(out.row_count(), 2u);
189   ASSERT_EQ(dur->Get(0).long_value, 100);
190   ASSERT_EQ(dur->Get(1).long_value, 101);
191 
192   out = slice_.Filter({slice_.dur().ge(101)});
193   dur = out.GetColumnByName("dur");
194   ASSERT_EQ(out.row_count(), 2u);
195   ASSERT_EQ(dur->Get(0).long_value, 101);
196   ASSERT_EQ(dur->Get(1).long_value, 200);
197 }
198 
TEST_F(TableMacrosUnittest,NullableLongCompareWithDouble)199 TEST_F(TableMacrosUnittest, NullableLongCompareWithDouble) {
200   slice_.Insert({});
201 
202   TestSliceTable::Row row;
203   row.dur = 100;
204   slice_.Insert(row);
205 
206   row.dur = std::numeric_limits<int64_t>::max();
207   slice_.Insert(row);
208 
209   row.dur = std::numeric_limits<int64_t>::min();
210   slice_.Insert(row);
211 
212   Table out = slice_.Filter({slice_.dur().eq_value(SqlValue::Double(100.0))});
213   const Column* dur = out.GetColumnByName("dur");
214   ASSERT_EQ(out.row_count(), 1u);
215   ASSERT_EQ(dur->Get(0).long_value, 100);
216 
217   out = slice_.Filter({slice_.dur().le_value(SqlValue::Double(99.9999))});
218   dur = out.GetColumnByName("dur");
219   ASSERT_EQ(out.row_count(), 1u);
220   ASSERT_EQ(dur->Get(0).long_value, std::numeric_limits<int64_t>::min());
221 
222   out = slice_.Filter({slice_.dur().ge_value(SqlValue::Double(99.9999))});
223   dur = out.GetColumnByName("dur");
224   ASSERT_EQ(out.row_count(), 2u);
225   ASSERT_EQ(dur->Get(0).long_value, 100);
226   ASSERT_EQ(dur->Get(1).long_value, std::numeric_limits<int64_t>::max());
227 
228   out = slice_.Filter({slice_.dur().eq_value(
229       SqlValue::Double(std::numeric_limits<int64_t>::min()))});
230   dur = out.GetColumnByName("dur");
231   ASSERT_EQ(out.row_count(), 1u);
232   ASSERT_EQ(dur->Get(0).long_value, std::numeric_limits<int64_t>::min());
233 }
234 
TEST_F(TableMacrosUnittest,NullableLongCompareWrongType)235 TEST_F(TableMacrosUnittest, NullableLongCompareWrongType) {
236   slice_.Insert({});
237 
238   TestSliceTable::Row row;
239   row.dur = 100;
240   slice_.Insert(row);
241 
242   row.dur = 101;
243   slice_.Insert(row);
244 
245   row.dur = 200;
246   slice_.Insert(row);
247 
248   slice_.Insert({});
249 
250   Table out = slice_.Filter({slice_.dur().ne_value(SqlValue())});
251   ASSERT_EQ(out.row_count(), 0u);
252 
253   out = slice_.Filter({slice_.dur().eq_value(SqlValue::String("100"))});
254   ASSERT_EQ(out.row_count(), 0u);
255 }
256 
TEST_F(TableMacrosUnittest,NullableDoubleComparision)257 TEST_F(TableMacrosUnittest, NullableDoubleComparision) {
258   counter_.Insert({});
259 
260   TestCounterTable::Row row;
261   row.value = 100.0;
262   counter_.Insert(row);
263 
264   row.value = 101.0;
265   counter_.Insert(row);
266 
267   row.value = 200.0;
268   counter_.Insert(row);
269 
270   counter_.Insert({});
271 
272   Table out = counter_.Filter({counter_.value().is_null()});
273   const auto* value = out.GetColumnByName("value");
274   ASSERT_EQ(out.row_count(), 2u);
275   ASSERT_EQ(value->Get(0).type, SqlValue::kNull);
276   ASSERT_EQ(value->Get(1).type, SqlValue::kNull);
277 
278   out = counter_.Filter({counter_.value().is_not_null()});
279   value = out.GetColumnByName("value");
280   ASSERT_EQ(out.row_count(), 3u);
281   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
282   ASSERT_DOUBLE_EQ(value->Get(1).double_value, 101);
283   ASSERT_DOUBLE_EQ(value->Get(2).double_value, 200);
284 
285   out = counter_.Filter({counter_.value().lt(101)});
286   value = out.GetColumnByName("value");
287   ASSERT_EQ(out.row_count(), 1u);
288   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
289 
290   out = counter_.Filter({counter_.value().eq(101)});
291   value = out.GetColumnByName("value");
292   ASSERT_EQ(out.row_count(), 1u);
293   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
294 
295   out = counter_.Filter({counter_.value().gt(101)});
296   value = out.GetColumnByName("value");
297   ASSERT_EQ(out.row_count(), 1u);
298   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 200);
299 
300   out = counter_.Filter({counter_.value().ne(100)});
301   value = out.GetColumnByName("value");
302   ASSERT_EQ(out.row_count(), 2u);
303   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
304   ASSERT_DOUBLE_EQ(value->Get(1).double_value, 200);
305 
306   out = counter_.Filter({counter_.value().le(101)});
307   value = out.GetColumnByName("value");
308   ASSERT_EQ(out.row_count(), 2u);
309   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100);
310   ASSERT_DOUBLE_EQ(value->Get(1).double_value, 101);
311 
312   out = counter_.Filter({counter_.value().ge(101)});
313   value = out.GetColumnByName("value");
314   ASSERT_EQ(out.row_count(), 2u);
315   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 101);
316   ASSERT_DOUBLE_EQ(value->Get(1).double_value, 200);
317 }
318 
TEST_F(TableMacrosUnittest,NullableDoubleCompareWithLong)319 TEST_F(TableMacrosUnittest, NullableDoubleCompareWithLong) {
320   counter_.Insert({});
321 
322   TestCounterTable::Row row;
323   row.value = 100.0;
324   counter_.Insert(row);
325 
326   row.value = 99.9999;
327   counter_.Insert(row);
328 
329   row.value = static_cast<double>(std::numeric_limits<int64_t>::min());
330   counter_.Insert(row);
331 
332   Table out = counter_.Filter({counter_.value().eq_value(SqlValue::Long(100))});
333   const Column* value = out.GetColumnByName("value");
334   ASSERT_EQ(out.row_count(), 1u);
335   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 100.0);
336 
337   out = counter_.Filter({counter_.value().lt_value(SqlValue::Long(100))});
338   value = out.GetColumnByName("value");
339   ASSERT_EQ(out.row_count(), 2u);
340   ASSERT_DOUBLE_EQ(value->Get(0).double_value, 99.9999);
341   ASSERT_DOUBLE_EQ(value->Get(1).double_value,
342                    std::numeric_limits<int64_t>::min());
343 
344   out = counter_.Filter({counter_.value().eq_value(
345       SqlValue::Long(std::numeric_limits<int64_t>::min()))});
346   value = out.GetColumnByName("value");
347   ASSERT_EQ(out.row_count(), 1u);
348   ASSERT_DOUBLE_EQ(value->Get(0).double_value,
349                    std::numeric_limits<int64_t>::min());
350 }
351 
TEST_F(TableMacrosUnittest,StringComparision)352 TEST_F(TableMacrosUnittest, StringComparision) {
353   cpu_slice_.Insert({});
354 
355   TestCpuSliceTable::Row row;
356   row.end_state = pool_.InternString("R");
357   cpu_slice_.Insert(row);
358 
359   row.end_state = pool_.InternString("D");
360   cpu_slice_.Insert(row);
361 
362   cpu_slice_.Insert({});
363 
364   Table out = cpu_slice_.Filter({cpu_slice_.end_state().is_null()});
365   const auto* end_state = out.GetColumnByName("end_state");
366   ASSERT_EQ(out.row_count(), 2u);
367   ASSERT_EQ(end_state->Get(0).type, SqlValue::kNull);
368   ASSERT_EQ(end_state->Get(1).type, SqlValue::kNull);
369 
370   out = cpu_slice_.Filter({cpu_slice_.end_state().is_not_null()});
371   end_state = out.GetColumnByName("end_state");
372   ASSERT_EQ(out.row_count(), 2u);
373   ASSERT_STREQ(end_state->Get(0).string_value, "R");
374   ASSERT_STREQ(end_state->Get(1).string_value, "D");
375 
376   out = cpu_slice_.Filter({cpu_slice_.end_state().lt("R")});
377   end_state = out.GetColumnByName("end_state");
378   ASSERT_EQ(out.row_count(), 1u);
379   ASSERT_STREQ(end_state->Get(0).string_value, "D");
380 
381   out = cpu_slice_.Filter({cpu_slice_.end_state().eq("D")});
382   end_state = out.GetColumnByName("end_state");
383   ASSERT_EQ(out.row_count(), 1u);
384   ASSERT_STREQ(end_state->Get(0).string_value, "D");
385 
386   out = cpu_slice_.Filter({cpu_slice_.end_state().gt("D")});
387   end_state = out.GetColumnByName("end_state");
388   ASSERT_EQ(out.row_count(), 1u);
389   ASSERT_STREQ(end_state->Get(0).string_value, "R");
390 
391   out = cpu_slice_.Filter({cpu_slice_.end_state().ne("D")});
392   end_state = out.GetColumnByName("end_state");
393   ASSERT_EQ(out.row_count(), 1u);
394   ASSERT_STREQ(end_state->Get(0).string_value, "R");
395 
396   out = cpu_slice_.Filter({cpu_slice_.end_state().le("R")});
397   end_state = out.GetColumnByName("end_state");
398   ASSERT_EQ(out.row_count(), 2u);
399   ASSERT_STREQ(end_state->Get(0).string_value, "R");
400   ASSERT_STREQ(end_state->Get(1).string_value, "D");
401 
402   out = cpu_slice_.Filter({cpu_slice_.end_state().ge("D")});
403   end_state = out.GetColumnByName("end_state");
404   ASSERT_EQ(out.row_count(), 2u);
405   ASSERT_STREQ(end_state->Get(0).string_value, "R");
406   ASSERT_STREQ(end_state->Get(1).string_value, "D");
407 }
408 
TEST_F(TableMacrosUnittest,FilterIdThenOther)409 TEST_F(TableMacrosUnittest, FilterIdThenOther) {
410   TestCpuSliceTable::Row row;
411   row.cpu = 1;
412   row.end_state = pool_.InternString("D");
413 
414   cpu_slice_.Insert(row);
415   cpu_slice_.Insert(row);
416   cpu_slice_.Insert(row);
417 
418   auto out =
419       cpu_slice_.Filter({cpu_slice_.id().eq(0), cpu_slice_.end_state().eq("D"),
420                          cpu_slice_.cpu().eq(1)});
421   const auto* end_state = out.GetColumnByName("end_state");
422   const auto* cpu = out.GetColumnByName("cpu");
423 
424   ASSERT_EQ(out.row_count(), 1u);
425   ASSERT_EQ(cpu->Get(0).long_value, 1u);
426   ASSERT_STREQ(end_state->Get(0).string_value, "D");
427 }
428 
TEST_F(TableMacrosUnittest,Sort)429 TEST_F(TableMacrosUnittest, Sort) {
430   ASSERT_TRUE(event_.ts().IsSorted());
431 
432   event_.Insert(TestEventTable::Row(0 /* ts */, 100 /* arg_set_id */));
433   event_.Insert(TestEventTable::Row(1 /* ts */, 1 /* arg_set_id */));
434   event_.Insert(TestEventTable::Row(2 /* ts */, 3 /* arg_set_id */));
435 
436   Table out = event_.Sort({event_.arg_set_id().ascending()});
437   const auto* ts = out.GetColumnByName("ts");
438   const auto* arg_set_id = out.GetColumnByName("arg_set_id");
439 
440   ASSERT_FALSE(ts->IsSorted());
441   ASSERT_TRUE(arg_set_id->IsSorted());
442 
443   ASSERT_EQ(arg_set_id->Get(0).long_value, 1);
444   ASSERT_EQ(arg_set_id->Get(1).long_value, 3);
445   ASSERT_EQ(arg_set_id->Get(2).long_value, 100);
446 }
447 
448 }  // namespace
449 }  // namespace trace_processor
450 }  // namespace perfetto
451