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/records.h>
6 
7 #include <stdint.h>
8 
9 #include <fbl/algorithm.h>
10 #include <fbl/string_printf.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 
process_thread_test()22 bool process_thread_test() {
23     BEGIN_TEST;
24 
25     trace::ProcessThread pt;
26     EXPECT_EQ(ZX_KOID_INVALID, pt.process_koid());
27     EXPECT_EQ(ZX_KOID_INVALID, pt.thread_koid());
28     EXPECT_FALSE(!!pt);
29 
30     pt = trace::ProcessThread(0, 1);
31     EXPECT_EQ(0, pt.process_koid());
32     EXPECT_EQ(1, pt.thread_koid());
33     EXPECT_TRUE(!!pt);
34 
35     pt = trace::ProcessThread(1, 0);
36     EXPECT_EQ(1, pt.process_koid());
37     EXPECT_EQ(0, pt.thread_koid());
38     EXPECT_TRUE(!!pt);
39 
40     pt = trace::ProcessThread(trace::ProcessThread(4, 5));
41     EXPECT_EQ(4, pt.process_koid());
42     EXPECT_EQ(5, pt.thread_koid());
43     EXPECT_TRUE(!!pt);
44 
45     EXPECT_TRUE(trace::ProcessThread(1, 2) == trace::ProcessThread(1, 2));
46     EXPECT_FALSE(trace::ProcessThread(1, 2) == trace::ProcessThread(1, 4));
47     EXPECT_FALSE(trace::ProcessThread(1, 2) == trace::ProcessThread(3, 2));
48     EXPECT_FALSE(trace::ProcessThread(1, 2) == trace::ProcessThread(3, 4));
49 
50     EXPECT_FALSE(trace::ProcessThread(1, 2) != trace::ProcessThread(1, 2));
51     EXPECT_TRUE(trace::ProcessThread(1, 2) != trace::ProcessThread(1, 4));
52     EXPECT_TRUE(trace::ProcessThread(1, 2) != trace::ProcessThread(3, 2));
53     EXPECT_TRUE(trace::ProcessThread(1, 2) != trace::ProcessThread(3, 4));
54 
55     EXPECT_FALSE(trace::ProcessThread(1, 2) < trace::ProcessThread(1, 2));
56     EXPECT_FALSE(trace::ProcessThread(1, 2) < trace::ProcessThread(1, 1));
57     EXPECT_TRUE(trace::ProcessThread(1, 2) < trace::ProcessThread(1, 3));
58     EXPECT_TRUE(trace::ProcessThread(1, 2) < trace::ProcessThread(2, 2));
59     EXPECT_TRUE(trace::ProcessThread(1, 2) < trace::ProcessThread(2, 3));
60 
61     EXPECT_FALSE(trace::ProcessThread() < trace::ProcessThread());
62     EXPECT_TRUE(trace::ProcessThread() < trace::ProcessThread(1, 2));
63     EXPECT_FALSE(trace::ProcessThread(1, 2) < trace::ProcessThread());
64 
65     EXPECT_STR_EQ("1/2", trace::ProcessThread(1, 2).ToString().c_str());
66 
67     END_TEST;
68 }
69 
argument_value_test()70 bool argument_value_test() {
71     BEGIN_TEST;
72 
73     // null
74 
75     trace::ArgumentValue av = trace::ArgumentValue::MakeNull();
76     EXPECT_EQ(trace::ArgumentType::kNull, av.type());
77 
78     {
79         trace::ArgumentValue m(std::move(av));
80         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
81         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
82 
83         av = std::move(m);
84         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
85         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
86     }
87 
88     EXPECT_STR_EQ("null", av.ToString().c_str());
89 
90     // int32
91 
92     av = trace::ArgumentValue::MakeInt32(INT32_MIN);
93     EXPECT_EQ(trace::ArgumentType::kInt32, av.type());
94     EXPECT_EQ(INT32_MIN, av.GetInt32());
95 
96     av = trace::ArgumentValue::MakeInt32(INT32_MAX);
97     EXPECT_EQ(trace::ArgumentType::kInt32, av.type());
98     EXPECT_EQ(INT32_MAX, av.GetInt32());
99 
100     {
101         trace::ArgumentValue m(std::move(av));
102         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
103         EXPECT_EQ(trace::ArgumentType::kInt32, m.type());
104         EXPECT_EQ(INT32_MAX, m.GetInt32());
105 
106         av = std::move(m);
107         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
108         EXPECT_EQ(trace::ArgumentType::kInt32, av.type());
109         EXPECT_EQ(INT32_MAX, av.GetInt32());
110     }
111 
112     EXPECT_STR_EQ("int32(2147483647)", av.ToString().c_str());
113 
114     // uint32
115 
116     av = trace::ArgumentValue::MakeUint32(0);
117     EXPECT_EQ(trace::ArgumentType::kUint32, av.type());
118     EXPECT_EQ(0, av.GetUint32());
119 
120     av = trace::ArgumentValue::MakeUint32(UINT32_MAX);
121     EXPECT_EQ(trace::ArgumentType::kUint32, av.type());
122     EXPECT_EQ(UINT32_MAX, av.GetUint32());
123 
124     {
125         trace::ArgumentValue m(std::move(av));
126         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
127         EXPECT_EQ(trace::ArgumentType::kUint32, m.type());
128         EXPECT_EQ(UINT32_MAX, m.GetUint32());
129 
130         av = std::move(m);
131         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
132         EXPECT_EQ(trace::ArgumentType::kUint32, av.type());
133         EXPECT_EQ(UINT32_MAX, av.GetUint32());
134     }
135 
136     EXPECT_STR_EQ("uint32(4294967295)", av.ToString().c_str());
137 
138     // int64
139 
140     av = trace::ArgumentValue::MakeInt64(INT64_MIN);
141     EXPECT_EQ(trace::ArgumentType::kInt64, av.type());
142     EXPECT_EQ(INT64_MIN, av.GetInt64());
143 
144     av = trace::ArgumentValue::MakeInt64(INT64_MAX);
145     EXPECT_EQ(trace::ArgumentType::kInt64, av.type());
146     EXPECT_EQ(INT64_MAX, av.GetInt64());
147 
148     {
149         trace::ArgumentValue m(std::move(av));
150         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
151         EXPECT_EQ(trace::ArgumentType::kInt64, m.type());
152         EXPECT_EQ(INT64_MAX, m.GetInt64());
153 
154         av = std::move(m);
155         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
156         EXPECT_EQ(trace::ArgumentType::kInt64, av.type());
157         EXPECT_EQ(INT64_MAX, av.GetInt64());
158     }
159 
160     EXPECT_STR_EQ("int64(9223372036854775807)", av.ToString().c_str());
161 
162     // uint64
163 
164     av = trace::ArgumentValue::MakeUint64(0);
165     EXPECT_EQ(trace::ArgumentType::kUint64, av.type());
166     EXPECT_EQ(0, av.GetUint64());
167 
168     av = trace::ArgumentValue::MakeUint64(UINT64_MAX);
169     EXPECT_EQ(trace::ArgumentType::kUint64, av.type());
170     EXPECT_EQ(UINT64_MAX, av.GetUint64());
171 
172     {
173         trace::ArgumentValue m(std::move(av));
174         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
175         EXPECT_EQ(trace::ArgumentType::kUint64, m.type());
176         EXPECT_EQ(UINT64_MAX, m.GetUint64());
177 
178         av = std::move(m);
179         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
180         EXPECT_EQ(trace::ArgumentType::kUint64, av.type());
181         EXPECT_EQ(UINT64_MAX, av.GetUint64());
182     }
183 
184     EXPECT_STR_EQ("uint64(18446744073709551615)", av.ToString().c_str());
185 
186     // double
187 
188     av = trace::ArgumentValue::MakeDouble(-3.14);
189     EXPECT_EQ(trace::ArgumentType::kDouble, av.type());
190     EXPECT_EQ(-3.14, av.GetDouble());
191 
192     {
193         trace::ArgumentValue m(std::move(av));
194         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
195         EXPECT_EQ(trace::ArgumentType::kDouble, m.type());
196         EXPECT_EQ(-3.14, m.GetDouble());
197 
198         av = std::move(m);
199         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
200         EXPECT_EQ(trace::ArgumentType::kDouble, av.type());
201         EXPECT_EQ(-3.14, av.GetDouble());
202     }
203 
204     EXPECT_STR_EQ("double(-3.140000)", av.ToString().c_str());
205 
206     // string
207 
208     av = trace::ArgumentValue::MakeString("Hello World!");
209     EXPECT_EQ(trace::ArgumentType::kString, av.type());
210     EXPECT_TRUE(av.GetString() == "Hello World!");
211 
212     {
213         trace::ArgumentValue m(std::move(av));
214         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
215         EXPECT_EQ(trace::ArgumentType::kString, m.type());
216         EXPECT_TRUE(m.GetString() == "Hello World!");
217 
218         av = std::move(m);
219         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
220         EXPECT_EQ(trace::ArgumentType::kString, av.type());
221         EXPECT_TRUE(av.GetString() == "Hello World!");
222     }
223 
224     EXPECT_STR_EQ("string(\"Hello World!\")", av.ToString().c_str());
225 
226     // pointer
227 
228     av = trace::ArgumentValue::MakePointer(0);
229     EXPECT_EQ(trace::ArgumentType::kPointer, av.type());
230     EXPECT_EQ(0, av.GetPointer());
231 
232     av = trace::ArgumentValue::MakePointer(UINTPTR_MAX);
233     EXPECT_EQ(trace::ArgumentType::kPointer, av.type());
234     EXPECT_EQ(UINTPTR_MAX, av.GetPointer());
235 
236     {
237         trace::ArgumentValue m(std::move(av));
238         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
239         EXPECT_EQ(trace::ArgumentType::kPointer, m.type());
240         EXPECT_EQ(UINTPTR_MAX, m.GetPointer());
241 
242         av = std::move(m);
243         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
244         EXPECT_EQ(trace::ArgumentType::kPointer, av.type());
245         EXPECT_EQ(UINTPTR_MAX, av.GetPointer());
246     }
247 
248     EXPECT_STR_EQ("pointer(0xffffffffffffffff)", av.ToString().c_str());
249 
250     // koid
251 
252     av = trace::ArgumentValue::MakeKoid(ZX_KOID_INVALID);
253     EXPECT_EQ(trace::ArgumentType::kKoid, av.type());
254     EXPECT_EQ(ZX_KOID_INVALID, av.GetKoid());
255 
256     av = trace::ArgumentValue::MakeKoid(UINT64_MAX);
257     EXPECT_EQ(trace::ArgumentType::kKoid, av.type());
258     EXPECT_EQ(UINT64_MAX, av.GetKoid());
259 
260     {
261         trace::ArgumentValue m(std::move(av));
262         EXPECT_EQ(trace::ArgumentType::kNull, av.type());
263         EXPECT_EQ(trace::ArgumentType::kKoid, m.type());
264         EXPECT_EQ(UINT64_MAX, m.GetKoid());
265 
266         av = std::move(m);
267         EXPECT_EQ(trace::ArgumentType::kNull, m.type());
268         EXPECT_EQ(trace::ArgumentType::kKoid, av.type());
269         EXPECT_EQ(UINT64_MAX, av.GetKoid());
270     }
271 
272     EXPECT_STR_EQ("koid(18446744073709551615)", av.ToString().c_str());
273 
274     END_TEST;
275 }
276 
argument_test()277 bool argument_test() {
278     BEGIN_TEST;
279 
280     trace::Argument a("name", trace::ArgumentValue::MakeInt32(123));
281     EXPECT_TRUE(a.name() == "name");
282     EXPECT_EQ(123, a.value().GetInt32());
283 
284     trace::Argument m(std::move(a));
285     EXPECT_TRUE(a.name().empty());
286     EXPECT_EQ(trace::ArgumentType::kNull, a.value().type());
287     EXPECT_TRUE(m.name() == "name");
288     EXPECT_EQ(123, m.value().GetInt32());
289 
290     a = std::move(m);
291     EXPECT_TRUE(m.name().empty());
292     EXPECT_EQ(trace::ArgumentType::kNull, m.value().type());
293     EXPECT_TRUE(a.name() == "name");
294     EXPECT_EQ(123, a.value().GetInt32());
295 
296     EXPECT_STR_EQ("name: int32(123)", a.ToString().c_str());
297 
298     END_TEST;
299 }
300 
metadata_data_test()301 bool metadata_data_test() {
302     BEGIN_TEST;
303 
304     // provider info
305 
306     {
307         trace::MetadataContent d(trace::MetadataContent::ProviderInfo{1, "provider"});
308         EXPECT_EQ(trace::MetadataType::kProviderInfo, d.type());
309         EXPECT_EQ(1, d.GetProviderInfo().id);
310         EXPECT_TRUE(d.GetProviderInfo().name == "provider");
311 
312         trace::MetadataContent m(std::move(d));
313         EXPECT_EQ(trace::MetadataType::kProviderInfo, m.type());
314         EXPECT_EQ(1, m.GetProviderInfo().id);
315         EXPECT_TRUE(m.GetProviderInfo().name == "provider");
316 
317         d = std::move(m);
318         EXPECT_EQ(trace::MetadataType::kProviderInfo, d.type());
319         EXPECT_EQ(1, d.GetProviderInfo().id);
320         EXPECT_TRUE(d.GetProviderInfo().name == "provider");
321 
322         EXPECT_STR_EQ("ProviderInfo(id: 1, name: \"provider\")", d.ToString().c_str());
323     }
324 
325     // provider section
326 
327     {
328         trace::MetadataContent d(trace::MetadataContent::ProviderSection{1});
329         EXPECT_EQ(trace::MetadataType::kProviderSection, d.type());
330         EXPECT_EQ(1, d.GetProviderSection().id);
331 
332         trace::MetadataContent m(std::move(d));
333         EXPECT_EQ(trace::MetadataType::kProviderSection, m.type());
334         EXPECT_EQ(1, m.GetProviderSection().id);
335 
336         d = std::move(m);
337         EXPECT_EQ(trace::MetadataType::kProviderSection, d.type());
338         EXPECT_EQ(1, d.GetProviderSection().id);
339 
340         EXPECT_STR_EQ("ProviderSection(id: 1)", d.ToString().c_str());
341     }
342 
343     END_TEST;
344 }
345 
event_data_test()346 bool event_data_test() {
347     BEGIN_TEST;
348 
349     // instant
350 
351     {
352         trace::EventData d(trace::EventData::Instant{trace::EventScope::kGlobal});
353         EXPECT_EQ(trace::EventType::kInstant, d.type());
354         EXPECT_EQ(trace::EventScope::kGlobal, d.GetInstant().scope);
355 
356         trace::EventData m(std::move(d));
357         EXPECT_EQ(trace::EventType::kInstant, m.type());
358         EXPECT_EQ(trace::EventScope::kGlobal, m.GetInstant().scope);
359 
360         d = std::move(m);
361         EXPECT_EQ(trace::EventType::kInstant, d.type());
362         EXPECT_EQ(trace::EventScope::kGlobal, d.GetInstant().scope);
363 
364         EXPECT_STR_EQ("Instant(scope: global)", d.ToString().c_str());
365     }
366 
367     // counter
368 
369     {
370         trace::EventData d(trace::EventData::Counter{123});
371         EXPECT_EQ(trace::EventType::kCounter, d.type());
372         EXPECT_EQ(123, d.GetCounter().id);
373 
374         trace::EventData m(std::move(d));
375         EXPECT_EQ(trace::EventType::kCounter, m.type());
376         EXPECT_EQ(123, m.GetCounter().id);
377 
378         d = std::move(m);
379         EXPECT_EQ(trace::EventType::kCounter, d.type());
380         EXPECT_EQ(123, d.GetCounter().id);
381 
382         EXPECT_STR_EQ("Counter(id: 123)", d.ToString().c_str());
383     }
384 
385     // duration begin
386 
387     {
388         trace::EventData d(trace::EventData::DurationBegin{});
389         EXPECT_EQ(trace::EventType::kDurationBegin, d.type());
390         EXPECT_NONNULL(&d.GetDurationBegin());
391 
392         trace::EventData m(std::move(d));
393         EXPECT_EQ(trace::EventType::kDurationBegin, m.type());
394         EXPECT_NONNULL(&m.GetDurationBegin());
395 
396         d = std::move(m);
397         EXPECT_EQ(trace::EventType::kDurationBegin, d.type());
398         EXPECT_NONNULL(&d.GetDurationBegin());
399 
400         EXPECT_STR_EQ("DurationBegin", d.ToString().c_str());
401     }
402 
403     // duration end
404 
405     {
406         trace::EventData d(trace::EventData::DurationEnd{});
407         EXPECT_EQ(trace::EventType::kDurationEnd, d.type());
408         EXPECT_NONNULL(&d.GetDurationEnd());
409 
410         trace::EventData m(std::move(d));
411         EXPECT_EQ(trace::EventType::kDurationEnd, m.type());
412         EXPECT_NONNULL(&m.GetDurationEnd());
413 
414         d = std::move(m);
415         EXPECT_EQ(trace::EventType::kDurationEnd, d.type());
416         EXPECT_NONNULL(&d.GetDurationEnd());
417 
418         EXPECT_STR_EQ("DurationEnd", d.ToString().c_str());
419     }
420 
421     // duration complete
422 
423     {
424         trace::EventData d(trace::EventData::DurationComplete{123});
425         EXPECT_EQ(trace::EventType::kDurationComplete, d.type());
426         EXPECT_EQ(123, d.GetDurationComplete().end_time);
427 
428         trace::EventData m(std::move(d));
429         EXPECT_EQ(trace::EventType::kDurationComplete, m.type());
430         EXPECT_EQ(123, m.GetDurationComplete().end_time);
431 
432         d = std::move(m);
433         EXPECT_EQ(trace::EventType::kDurationComplete, d.type());
434         EXPECT_EQ(123, d.GetDurationComplete().end_time);
435 
436         EXPECT_STR_EQ("DurationComplete(end_time: 123)", d.ToString().c_str());
437     }
438 
439     // async begin
440 
441     {
442         trace::EventData d(trace::EventData::AsyncBegin{123});
443         EXPECT_EQ(trace::EventType::kAsyncBegin, d.type());
444         EXPECT_EQ(123, d.GetAsyncBegin().id);
445 
446         trace::EventData m(std::move(d));
447         EXPECT_EQ(trace::EventType::kAsyncBegin, m.type());
448         EXPECT_EQ(123, m.GetAsyncBegin().id);
449 
450         d = std::move(m);
451         EXPECT_EQ(trace::EventType::kAsyncBegin, d.type());
452         EXPECT_EQ(123, d.GetAsyncBegin().id);
453 
454         EXPECT_STR_EQ("AsyncBegin(id: 123)", d.ToString().c_str());
455     }
456 
457     // async instant
458 
459     {
460         trace::EventData d(trace::EventData::AsyncInstant{123});
461         EXPECT_EQ(trace::EventType::kAsyncInstant, d.type());
462         EXPECT_EQ(123, d.GetAsyncInstant().id);
463 
464         trace::EventData m(std::move(d));
465         EXPECT_EQ(trace::EventType::kAsyncInstant, m.type());
466         EXPECT_EQ(123, m.GetAsyncInstant().id);
467 
468         d = std::move(m);
469         EXPECT_EQ(trace::EventType::kAsyncInstant, d.type());
470         EXPECT_EQ(123, d.GetAsyncInstant().id);
471 
472         EXPECT_STR_EQ("AsyncInstant(id: 123)", d.ToString().c_str());
473     }
474 
475     // async end
476 
477     {
478         trace::EventData d(trace::EventData::AsyncEnd{123});
479         EXPECT_EQ(trace::EventType::kAsyncEnd, d.type());
480         EXPECT_EQ(123, d.GetAsyncEnd().id);
481 
482         trace::EventData m(std::move(d));
483         EXPECT_EQ(trace::EventType::kAsyncEnd, m.type());
484         EXPECT_EQ(123, m.GetAsyncEnd().id);
485 
486         d = std::move(m);
487         EXPECT_EQ(trace::EventType::kAsyncEnd, d.type());
488         EXPECT_EQ(123, d.GetAsyncEnd().id);
489 
490         EXPECT_STR_EQ("AsyncEnd(id: 123)", d.ToString().c_str());
491     }
492 
493     // flow begin
494 
495     {
496         trace::EventData d(trace::EventData::FlowBegin{123});
497         EXPECT_EQ(trace::EventType::kFlowBegin, d.type());
498         EXPECT_EQ(123, d.GetFlowBegin().id);
499 
500         trace::EventData m(std::move(d));
501         EXPECT_EQ(trace::EventType::kFlowBegin, m.type());
502         EXPECT_EQ(123, m.GetFlowBegin().id);
503 
504         d = std::move(m);
505         EXPECT_EQ(trace::EventType::kFlowBegin, d.type());
506         EXPECT_EQ(123, d.GetFlowBegin().id);
507 
508         EXPECT_STR_EQ("FlowBegin(id: 123)", d.ToString().c_str());
509     }
510 
511     // flow step
512 
513     {
514         trace::EventData d(trace::EventData::FlowStep{123});
515         EXPECT_EQ(trace::EventType::kFlowStep, d.type());
516         EXPECT_EQ(123, d.GetFlowStep().id);
517 
518         trace::EventData m(std::move(d));
519         EXPECT_EQ(trace::EventType::kFlowStep, m.type());
520         EXPECT_EQ(123, m.GetFlowStep().id);
521 
522         d = std::move(m);
523         EXPECT_EQ(trace::EventType::kFlowStep, d.type());
524         EXPECT_EQ(123, d.GetFlowStep().id);
525 
526         EXPECT_STR_EQ("FlowStep(id: 123)", d.ToString().c_str());
527     }
528 
529     // flow end
530 
531     {
532         trace::EventData d(trace::EventData::FlowEnd{123});
533         EXPECT_EQ(trace::EventType::kFlowEnd, d.type());
534         EXPECT_EQ(123, d.GetFlowEnd().id);
535 
536         trace::EventData m(std::move(d));
537         EXPECT_EQ(trace::EventType::kFlowEnd, m.type());
538         EXPECT_EQ(123, m.GetFlowEnd().id);
539 
540         d = std::move(m);
541         EXPECT_EQ(trace::EventType::kFlowEnd, d.type());
542         EXPECT_EQ(123, d.GetFlowEnd().id);
543 
544         EXPECT_STR_EQ("FlowEnd(id: 123)", d.ToString().c_str());
545     }
546 
547     END_TEST;
548 }
549 
record_test()550 bool record_test() {
551     BEGIN_TEST;
552 
553     // metadata
554 
555     {
556         trace::Record r(trace::Record::Metadata{trace::MetadataContent(
557             trace::MetadataContent::ProviderSection{123})});
558         EXPECT_EQ(trace::RecordType::kMetadata, r.type());
559         EXPECT_EQ(trace::MetadataType::kProviderSection, r.GetMetadata().type());
560         EXPECT_EQ(123, r.GetMetadata().content.GetProviderSection().id);
561 
562         trace::Record m(std::move(r));
563         EXPECT_EQ(trace::RecordType::kMetadata, m.type());
564         EXPECT_EQ(trace::MetadataType::kProviderSection, m.GetMetadata().type());
565         EXPECT_EQ(123, m.GetMetadata().content.GetProviderSection().id);
566 
567         r = std::move(m);
568         EXPECT_EQ(trace::RecordType::kMetadata, r.type());
569         EXPECT_EQ(trace::MetadataType::kProviderSection, r.GetMetadata().type());
570         EXPECT_EQ(123, r.GetMetadata().content.GetProviderSection().id);
571 
572         EXPECT_STR_EQ("Metadata(content: ProviderSection(id: 123))", r.ToString().c_str());
573     }
574 
575     // initialization
576 
577     {
578         trace::Record r(trace::Record::Initialization{123});
579         EXPECT_EQ(trace::RecordType::kInitialization, r.type());
580         EXPECT_EQ(123, r.GetInitialization().ticks_per_second);
581 
582         trace::Record m(std::move(r));
583         EXPECT_EQ(trace::RecordType::kInitialization, m.type());
584         EXPECT_EQ(123, m.GetInitialization().ticks_per_second);
585 
586         r = std::move(m);
587         EXPECT_EQ(trace::RecordType::kInitialization, r.type());
588         EXPECT_EQ(123, r.GetInitialization().ticks_per_second);
589 
590         EXPECT_STR_EQ("Initialization(ticks_per_second: 123)", r.ToString().c_str());
591     }
592 
593     // string
594 
595     {
596         trace::Record r(trace::Record::String{123, "hi!"});
597         EXPECT_EQ(trace::RecordType::kString, r.type());
598         EXPECT_EQ(123, r.GetString().index);
599         EXPECT_TRUE(r.GetString().string == "hi!");
600 
601         trace::Record m(std::move(r));
602         EXPECT_EQ(trace::RecordType::kString, m.type());
603         EXPECT_EQ(123, m.GetString().index);
604         EXPECT_TRUE(m.GetString().string == "hi!");
605 
606         r = std::move(m);
607         EXPECT_EQ(trace::RecordType::kString, r.type());
608         EXPECT_EQ(123, r.GetString().index);
609         EXPECT_TRUE(r.GetString().string == "hi!");
610 
611         EXPECT_STR_EQ("String(index: 123, \"hi!\")", r.ToString().c_str());
612     }
613 
614     // thread
615 
616     {
617         trace::Record r(trace::Record::Thread{123, trace::ProcessThread(4, 5)});
618         EXPECT_EQ(trace::RecordType::kThread, r.type());
619         EXPECT_EQ(123, r.GetThread().index);
620         EXPECT_EQ(4, r.GetThread().process_thread.process_koid());
621         EXPECT_EQ(5, r.GetThread().process_thread.thread_koid());
622 
623         trace::Record m(std::move(r));
624         EXPECT_EQ(trace::RecordType::kThread, m.type());
625         EXPECT_EQ(123, m.GetThread().index);
626         EXPECT_EQ(4, m.GetThread().process_thread.process_koid());
627         EXPECT_EQ(5, m.GetThread().process_thread.thread_koid());
628 
629         r = std::move(m);
630         EXPECT_EQ(trace::RecordType::kThread, r.type());
631         EXPECT_EQ(123, r.GetThread().index);
632         EXPECT_EQ(4, r.GetThread().process_thread.process_koid());
633         EXPECT_EQ(5, r.GetThread().process_thread.thread_koid());
634 
635         EXPECT_STR_EQ("Thread(index: 123, 4/5)", r.ToString().c_str());
636     }
637 
638     // event
639 
640     {
641         fbl::Vector<trace::Argument> args;
642         args.push_back(trace::Argument("arg1", trace::ArgumentValue::MakeInt32(11)));
643         args.push_back(trace::Argument("arg2", trace::ArgumentValue::MakeDouble(-3.14)));
644 
645         trace::Record r(trace::Record::Event{
646             123, trace::ProcessThread(4, 5),
647             "category", "name", std::move(args),
648             trace::EventData(trace::EventData::AsyncBegin{678})});
649         EXPECT_EQ(trace::RecordType::kEvent, r.type());
650         EXPECT_EQ(trace::EventType::kAsyncBegin, r.GetEvent().type());
651         EXPECT_EQ(123, r.GetEvent().timestamp);
652         EXPECT_EQ(4, r.GetEvent().process_thread.process_koid());
653         EXPECT_EQ(5, r.GetEvent().process_thread.thread_koid());
654         EXPECT_TRUE(r.GetEvent().category == "category");
655         EXPECT_TRUE(r.GetEvent().name == "name");
656         EXPECT_EQ(678, r.GetEvent().data.GetAsyncBegin().id);
657         EXPECT_EQ(2, r.GetEvent().arguments.size());
658         EXPECT_TRUE(r.GetEvent().arguments[0].name() == "arg1");
659         EXPECT_EQ(11, r.GetEvent().arguments[0].value().GetInt32());
660         EXPECT_TRUE(r.GetEvent().arguments[1].name() == "arg2");
661         EXPECT_EQ(-3.14, r.GetEvent().arguments[1].value().GetDouble());
662 
663         trace::Record m(std::move(r));
664         EXPECT_EQ(trace::RecordType::kEvent, m.type());
665         EXPECT_EQ(trace::EventType::kAsyncBegin, m.GetEvent().type());
666         EXPECT_EQ(123, m.GetEvent().timestamp);
667         EXPECT_EQ(4, m.GetEvent().process_thread.process_koid());
668         EXPECT_EQ(5, m.GetEvent().process_thread.thread_koid());
669         EXPECT_TRUE(m.GetEvent().category == "category");
670         EXPECT_TRUE(m.GetEvent().name == "name");
671         EXPECT_EQ(678, m.GetEvent().data.GetAsyncBegin().id);
672         EXPECT_EQ(2, m.GetEvent().arguments.size());
673         EXPECT_TRUE(m.GetEvent().arguments[0].name() == "arg1");
674         EXPECT_EQ(11, m.GetEvent().arguments[0].value().GetInt32());
675         EXPECT_TRUE(m.GetEvent().arguments[1].name() == "arg2");
676         EXPECT_EQ(-3.14, m.GetEvent().arguments[1].value().GetDouble());
677 
678         r = std::move(m);
679         EXPECT_EQ(trace::RecordType::kEvent, r.type());
680         EXPECT_EQ(trace::EventType::kAsyncBegin, r.GetEvent().type());
681         EXPECT_EQ(123, r.GetEvent().timestamp);
682         EXPECT_EQ(4, r.GetEvent().process_thread.process_koid());
683         EXPECT_EQ(5, r.GetEvent().process_thread.thread_koid());
684         EXPECT_TRUE(r.GetEvent().category == "category");
685         EXPECT_TRUE(r.GetEvent().name == "name");
686         EXPECT_EQ(678, r.GetEvent().data.GetAsyncBegin().id);
687         EXPECT_EQ(2, r.GetEvent().arguments.size());
688         EXPECT_TRUE(r.GetEvent().arguments[0].name() == "arg1");
689         EXPECT_EQ(11, r.GetEvent().arguments[0].value().GetInt32());
690         EXPECT_TRUE(r.GetEvent().arguments[1].name() == "arg2");
691         EXPECT_EQ(-3.14, r.GetEvent().arguments[1].value().GetDouble());
692 
693         EXPECT_STR_EQ("Event(ts: 123, pt: 4/5, category: \"category\", name: \"name\", "
694                       "AsyncBegin(id: 678), {arg1: int32(11), arg2: double(-3.140000)})",
695                       r.ToString().c_str());
696     }
697 
698     // blobs
699 
700     {
701         const char name[] = "name";
702         const char blob[] = "abc";
703         trace::Record r(trace::Record::Blob{
704             TRACE_BLOB_TYPE_DATA, "name", blob, sizeof(blob)});
705         EXPECT_EQ(trace::RecordType::kBlob, r.type());
706         EXPECT_EQ(TRACE_BLOB_TYPE_DATA, r.GetBlob().type);
707         EXPECT_EQ(sizeof(blob), r.GetBlob().blob_size);
708         EXPECT_STR_EQ(blob, reinterpret_cast<const char*>(r.GetBlob().blob));
709 
710         trace::Record m(std::move(r));
711         EXPECT_EQ(trace::RecordType::kBlob, m.type());
712         EXPECT_EQ(TRACE_BLOB_TYPE_DATA, m.GetBlob().type);
713         EXPECT_EQ(sizeof(blob), m.GetBlob().blob_size);
714         EXPECT_STR_EQ(blob, reinterpret_cast<const char*>(m.GetBlob().blob));
715 
716         r = std::move(m);
717         EXPECT_EQ(trace::RecordType::kBlob, r.type());
718         EXPECT_EQ(TRACE_BLOB_TYPE_DATA, r.GetBlob().type);
719         EXPECT_EQ(sizeof(blob), r.GetBlob().blob_size);
720         EXPECT_STR_EQ(blob, reinterpret_cast<const char*>(r.GetBlob().blob));
721 
722         auto expected = fbl::StringPrintf("Blob(name: %s, size: %zu)",
723                                           name, sizeof(blob));
724         EXPECT_STR_EQ(expected.c_str(), r.ToString().c_str());
725     }
726 
727     // kernel object
728 
729     {
730         fbl::Vector<trace::Argument> args;
731         args.push_back(trace::Argument("arg1", trace::ArgumentValue::MakeInt32(11)));
732         args.push_back(trace::Argument("arg2", trace::ArgumentValue::MakeDouble(-3.14)));
733 
734         trace::Record r(trace::Record::KernelObject{
735             123, ZX_OBJ_TYPE_VMO, "name", std::move(args)});
736         EXPECT_EQ(trace::RecordType::kKernelObject, r.type());
737         EXPECT_EQ(123, r.GetKernelObject().koid);
738         EXPECT_EQ(ZX_OBJ_TYPE_VMO, r.GetKernelObject().object_type);
739         EXPECT_TRUE(r.GetKernelObject().name == "name");
740         EXPECT_EQ(2, r.GetKernelObject().arguments.size());
741         EXPECT_TRUE(r.GetKernelObject().arguments[0].name() == "arg1");
742         EXPECT_EQ(11, r.GetKernelObject().arguments[0].value().GetInt32());
743         EXPECT_TRUE(r.GetKernelObject().arguments[1].name() == "arg2");
744         EXPECT_EQ(-3.14, r.GetKernelObject().arguments[1].value().GetDouble());
745 
746         trace::Record m(std::move(r));
747         EXPECT_EQ(trace::RecordType::kKernelObject, m.type());
748         EXPECT_EQ(123, m.GetKernelObject().koid);
749         EXPECT_EQ(ZX_OBJ_TYPE_VMO, m.GetKernelObject().object_type);
750         EXPECT_TRUE(m.GetKernelObject().name == "name");
751         EXPECT_EQ(2, m.GetKernelObject().arguments.size());
752         EXPECT_TRUE(m.GetKernelObject().arguments[0].name() == "arg1");
753         EXPECT_EQ(11, m.GetKernelObject().arguments[0].value().GetInt32());
754         EXPECT_TRUE(m.GetKernelObject().arguments[1].name() == "arg2");
755         EXPECT_EQ(-3.14, m.GetKernelObject().arguments[1].value().GetDouble());
756 
757         r = std::move(m);
758         EXPECT_EQ(trace::RecordType::kKernelObject, r.type());
759         EXPECT_EQ(123, r.GetKernelObject().koid);
760         EXPECT_EQ(ZX_OBJ_TYPE_VMO, r.GetKernelObject().object_type);
761         EXPECT_TRUE(r.GetKernelObject().name == "name");
762         EXPECT_EQ(2, r.GetKernelObject().arguments.size());
763         EXPECT_TRUE(r.GetKernelObject().arguments[0].name() == "arg1");
764         EXPECT_EQ(11, r.GetKernelObject().arguments[0].value().GetInt32());
765         EXPECT_TRUE(r.GetKernelObject().arguments[1].name() == "arg2");
766         EXPECT_EQ(-3.14, r.GetKernelObject().arguments[1].value().GetDouble());
767 
768         EXPECT_STR_EQ("KernelObject(koid: 123, type: vmo, name: \"name\", "
769                       "{arg1: int32(11), arg2: double(-3.140000)})",
770                       r.ToString().c_str());
771     }
772 
773     // context switch
774 
775     {
776         trace::Record r(trace::Record::ContextSwitch{
777             123, 4, trace::ThreadState::kSuspended,
778             trace::ProcessThread(5, 6), trace::ProcessThread(7, 8),
779             9, 10});
780         EXPECT_EQ(trace::RecordType::kContextSwitch, r.type());
781         EXPECT_EQ(123, r.GetContextSwitch().timestamp);
782         EXPECT_EQ(4, r.GetContextSwitch().cpu_number);
783         EXPECT_EQ(trace::ThreadState::kSuspended, r.GetContextSwitch().outgoing_thread_state);
784         EXPECT_EQ(5, r.GetContextSwitch().outgoing_thread.process_koid());
785         EXPECT_EQ(6, r.GetContextSwitch().outgoing_thread.thread_koid());
786         EXPECT_EQ(7, r.GetContextSwitch().incoming_thread.process_koid());
787         EXPECT_EQ(8, r.GetContextSwitch().incoming_thread.thread_koid());
788         EXPECT_EQ(9, r.GetContextSwitch().outgoing_thread_priority);
789         EXPECT_EQ(10, r.GetContextSwitch().incoming_thread_priority);
790 
791         trace::Record m(std::move(r));
792         EXPECT_EQ(trace::RecordType::kContextSwitch, m.type());
793         EXPECT_EQ(123, m.GetContextSwitch().timestamp);
794         EXPECT_EQ(4, m.GetContextSwitch().cpu_number);
795         EXPECT_EQ(trace::ThreadState::kSuspended, m.GetContextSwitch().outgoing_thread_state);
796         EXPECT_EQ(5, m.GetContextSwitch().outgoing_thread.process_koid());
797         EXPECT_EQ(6, m.GetContextSwitch().outgoing_thread.thread_koid());
798         EXPECT_EQ(7, m.GetContextSwitch().incoming_thread.process_koid());
799         EXPECT_EQ(8, m.GetContextSwitch().incoming_thread.thread_koid());
800         EXPECT_EQ(9, m.GetContextSwitch().outgoing_thread_priority);
801         EXPECT_EQ(10, m.GetContextSwitch().incoming_thread_priority);
802 
803         r = std::move(m);
804         EXPECT_EQ(trace::RecordType::kContextSwitch, r.type());
805         EXPECT_EQ(123, r.GetContextSwitch().timestamp);
806         EXPECT_EQ(4, r.GetContextSwitch().cpu_number);
807         EXPECT_EQ(trace::ThreadState::kSuspended, r.GetContextSwitch().outgoing_thread_state);
808         EXPECT_EQ(5, r.GetContextSwitch().outgoing_thread.process_koid());
809         EXPECT_EQ(6, r.GetContextSwitch().outgoing_thread.thread_koid());
810         EXPECT_EQ(7, r.GetContextSwitch().incoming_thread.process_koid());
811         EXPECT_EQ(8, r.GetContextSwitch().incoming_thread.thread_koid());
812         EXPECT_EQ(9, r.GetContextSwitch().outgoing_thread_priority);
813         EXPECT_EQ(10, r.GetContextSwitch().incoming_thread_priority);
814 
815         EXPECT_STR_EQ("ContextSwitch(ts: 123, cpu: 4, os: suspended, opt: 5/6, ipt: 7/8, oprio: 9, iprio: 10)", r.ToString().c_str());
816     }
817 
818     // log
819 
820     {
821         trace::Record r(trace::Record::Log{
822             123, trace::ProcessThread(4, 5), "log message"});
823         EXPECT_EQ(trace::RecordType::kLog, r.type());
824         EXPECT_EQ(123, r.GetLog().timestamp);
825         EXPECT_EQ(4, r.GetLog().process_thread.process_koid());
826         EXPECT_EQ(5, r.GetLog().process_thread.thread_koid());
827         EXPECT_TRUE(r.GetLog().message == "log message");
828 
829         trace::Record m(std::move(r));
830         EXPECT_EQ(trace::RecordType::kLog, m.type());
831         EXPECT_EQ(123, m.GetLog().timestamp);
832         EXPECT_EQ(4, m.GetLog().process_thread.process_koid());
833         EXPECT_EQ(5, m.GetLog().process_thread.thread_koid());
834         EXPECT_TRUE(m.GetLog().message == "log message");
835 
836         r = std::move(m);
837         EXPECT_EQ(trace::RecordType::kLog, r.type());
838         EXPECT_EQ(123, r.GetLog().timestamp);
839         EXPECT_EQ(4, r.GetLog().process_thread.process_koid());
840         EXPECT_EQ(5, r.GetLog().process_thread.thread_koid());
841         EXPECT_TRUE(r.GetLog().message == "log message");
842 
843         EXPECT_STR_EQ("Log(ts: 123, pt: 4/5, \"log message\")", r.ToString().c_str());
844     }
845 
846     END_TEST;
847 }
848 
849 } // namespace
850 
851 BEGIN_TEST_CASE(types_tests)
852 RUN_TEST(process_thread_test)
853 RUN_TEST(argument_value_test)
854 RUN_TEST(argument_test)
855 RUN_TEST(metadata_data_test)
856 RUN_TEST(event_data_test)
857 RUN_TEST(record_test)
858 END_TEST_CASE(types_tests)
859