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