]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - pevent/test/src/ptunit-pevent.c
Import Intel Processor Trace library.
[FreeBSD/FreeBSD.git] / pevent / test / src / ptunit-pevent.c
1 /*
2  * Copyright (c) 2014-2018, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *  * Neither the name of Intel Corporation nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "ptunit.h"
30
31 #include "pevent.h"
32
33
34 /* A test fixture. */
35 struct pev_fixture {
36         /* A memory buffer. */
37         uint8_t buffer[1024];
38
39         /* Two perf events:
40          *
41          *   event[0] is the test setup
42          *   event[1] is the event after writing and reading event[0]
43          */
44         struct pev_event event[2];
45
46         /* The perf event configuration. */
47         struct pev_config config;
48
49         /* Test samples. */
50         struct {
51                 uint32_t pid, tid;
52                 uint64_t time;
53                 uint64_t tsc;
54                 uint32_t cpu;
55         } sample;
56
57         /* The test fixture initialization and finalization functions. */
58         struct ptunit_result (*init)(struct pev_fixture *);
59         struct ptunit_result (*fini)(struct pev_fixture *);
60 };
61
62 static struct ptunit_result pfix_init(struct pev_fixture *pfix)
63 {
64         memset(pfix->buffer, 0xcd, sizeof(pfix->buffer));
65         memset(&pfix->sample, 0xcd, sizeof(pfix->sample));
66
67         pev_event_init(&pfix->event[0]);
68         pev_event_init(&pfix->event[1]);
69
70         pev_config_init(&pfix->config);
71
72         return ptu_passed();
73 }
74
75 static struct ptunit_result pfix_init_sample_time(struct pev_fixture *pfix)
76 {
77         ptu_test(pfix_init, pfix);
78
79         pfix->config.sample_type |= (uint64_t) PERF_SAMPLE_TIME;
80         pfix->config.time_zero = 0xa0b00000ull;
81         pfix->config.time_shift = 4;
82         pfix->config.time_mult = 3;
83
84         pfix->sample.time = 0xa0b00cdeull;
85         pfix->event[0].sample.time = &pfix->sample.time;
86
87         return ptu_passed();
88 }
89
90 static struct ptunit_result pfix_init_sample_who(struct pev_fixture *pfix)
91 {
92         ptu_test(pfix_init, pfix);
93
94         pfix->config.sample_type |= (uint64_t) PERF_SAMPLE_TID;
95         pfix->config.sample_type |= (uint64_t) PERF_SAMPLE_CPU;
96
97         pfix->sample.pid = 0xa0;
98         pfix->sample.tid = 0xa1;
99         pfix->sample.cpu = 0xb;
100
101         pfix->event[0].sample.pid = &pfix->sample.pid;
102         pfix->event[0].sample.tid = &pfix->sample.tid;
103         pfix->event[0].sample.cpu = &pfix->sample.cpu;
104
105         return ptu_passed();
106 }
107
108 static struct ptunit_result pfix_read_write(struct pev_fixture *pfix)
109 {
110         uint8_t *begin, *end;
111         int size[2];
112
113         begin = pfix->buffer;
114         end = begin + sizeof(pfix->buffer);
115
116         size[0] = pev_write(&pfix->event[0], begin, end, &pfix->config);
117         ptu_int_gt(size[0], 0);
118
119         size[1] = pev_read(&pfix->event[1], begin, end, &pfix->config);
120         ptu_int_gt(size[1], 0);
121
122         ptu_int_eq(size[1], size[0]);
123
124         return ptu_passed();
125 }
126
127 static struct ptunit_result pfix_check_sample_time(struct pev_fixture *pfix)
128 {
129         const uint64_t *time[2];
130         uint64_t tsc;
131         int errcode;
132
133         time[0] = pfix->event[0].sample.time;
134         time[1] = pfix->event[1].sample.time;
135
136         ptu_ptr(time[0]);
137         ptu_ptr(time[1]);
138
139         ptu_uint_eq(*time[1], *time[0]);
140
141         errcode = pev_time_to_tsc(&tsc, *time[0], &pfix->config);
142         ptu_int_eq(errcode, 0);
143         ptu_uint_eq(pfix->event[1].sample.tsc, tsc);
144
145         return ptu_passed();
146 }
147
148 static struct ptunit_result pfix_check_sample_tid(struct pev_fixture *pfix)
149 {
150         const uint32_t *pid[2], *tid[2];
151
152         pid[0] = pfix->event[0].sample.pid;
153         pid[1] = pfix->event[1].sample.pid;
154         tid[0] = pfix->event[0].sample.tid;
155         tid[1] = pfix->event[1].sample.tid;
156
157         ptu_ptr(pid[0]);
158         ptu_ptr(pid[1]);
159         ptu_ptr(tid[0]);
160         ptu_ptr(tid[1]);
161
162         ptu_uint_eq(*pid[1], *pid[0]);
163         ptu_uint_eq(*tid[1], *tid[0]);
164
165         return ptu_passed();
166 }
167
168 static struct ptunit_result pfix_check_sample_cpu(struct pev_fixture *pfix)
169 {
170         const uint32_t *cpu[2];
171
172         cpu[0] = pfix->event[0].sample.cpu;
173         cpu[1] = pfix->event[1].sample.cpu;
174
175         ptu_ptr(cpu[0]);
176         ptu_ptr(cpu[1]);
177
178         ptu_uint_eq(*cpu[1], *cpu[0]);
179
180         return ptu_passed();
181 }
182
183 static struct ptunit_result pfix_check_sample(struct pev_fixture *pfix)
184 {
185         if (pfix->config.sample_type & PERF_SAMPLE_TID)
186                 ptu_test(pfix_check_sample_tid, pfix);
187         else {
188                 ptu_null(pfix->event[1].sample.pid);
189                 ptu_null(pfix->event[1].sample.tid);
190         }
191
192         if (pfix->config.sample_type & PERF_SAMPLE_TIME)
193                 ptu_test(pfix_check_sample_time, pfix);
194         else
195                 ptu_null(pfix->event[1].sample.time);
196
197         if (pfix->config.sample_type & PERF_SAMPLE_CPU)
198                 ptu_test(pfix_check_sample_cpu, pfix);
199         else
200                 ptu_null(pfix->event[1].sample.cpu);
201
202         return ptu_passed();
203 }
204
205 static struct ptunit_result time_to_tsc_null(void)
206 {
207         struct pev_config config;
208         uint64_t tsc;
209         int errcode;
210
211         errcode = pev_time_to_tsc(NULL, 0x0ull, &config);
212         ptu_int_eq(errcode, -pte_internal);
213
214         errcode = pev_time_to_tsc(&tsc, 0x0ull, NULL);
215         ptu_int_eq(errcode, -pte_internal);
216
217         return ptu_passed();
218 }
219
220 static struct ptunit_result time_from_tsc_null(void)
221 {
222         struct pev_config config;
223         uint64_t time;
224         int errcode;
225
226         errcode = pev_time_from_tsc(NULL, 0x0ull, &config);
227         ptu_int_eq(errcode, -pte_internal);
228
229         errcode = pev_time_from_tsc(&time, 0x0ull, NULL);
230         ptu_int_eq(errcode, -pte_internal);
231
232         return ptu_passed();
233 }
234
235 static struct ptunit_result time_to_tsc(void)
236 {
237         struct pev_config config;
238         uint64_t tsc;
239         int errcode;
240
241         pev_config_init(&config);
242         config.time_shift = 4;
243         config.time_mult = 3;
244         config.time_zero = 0xa00b00ull;
245
246         errcode = pev_time_to_tsc(&tsc, 0xa00b43ull, &config);
247         ptu_int_eq(errcode, 0);
248         ptu_uint_eq(tsc, 0x165ull);
249
250         return ptu_passed();
251 }
252
253 static struct ptunit_result time_from_tsc(void)
254 {
255         struct pev_config config;
256         uint64_t time;
257         int errcode;
258
259         pev_config_init(&config);
260         config.time_shift = 4;
261         config.time_mult = 3;
262         config.time_zero = 0xa00b00ull;
263
264         errcode = pev_time_from_tsc(&time, 0x23bull, &config);
265         ptu_int_eq(errcode, 0);
266         ptu_uint_eq(time, 0xa00b6bull);
267
268         return ptu_passed();
269 }
270
271 static struct ptunit_result time_to_tsc_bad_config(void)
272 {
273         struct pev_config config;
274         uint64_t tsc;
275         int errcode;
276
277         memset(&config, 0, sizeof(config));
278         config.time_mult = 1;
279
280         errcode = pev_time_to_tsc(&tsc, 0x0ull, &config);
281         ptu_int_eq(errcode, -pte_bad_config);
282
283         config.size = sizeof(config);
284         config.time_mult = 0;
285
286         errcode = pev_time_to_tsc(&tsc, 0x0ull, &config);
287         ptu_int_eq(errcode, -pte_bad_config);
288
289         return ptu_passed();
290 }
291
292 static struct ptunit_result time_from_tsc_bad_config(void)
293 {
294         struct pev_config config;
295         uint64_t time;
296         int errcode;
297
298         memset(&config, 0, sizeof(config));
299         config.time_mult = 1;
300
301         errcode = pev_time_from_tsc(&time, 0x0ull, &config);
302         ptu_int_eq(errcode, -pte_bad_config);
303
304         config.size = sizeof(config);
305         config.time_mult = 0;
306
307         errcode = pev_time_from_tsc(&time, 0x0ull, &config);
308         ptu_int_eq(errcode, -pte_bad_config);
309
310         return ptu_passed();
311 }
312
313 static struct ptunit_result read_bad_config(void)
314 {
315         union {
316                 struct perf_event_header header;
317                 uint8_t buffer[128];
318         } input;
319         struct pev_config config;
320         struct pev_event event;
321         int errcode;
322
323         memset(input.buffer, 0, sizeof(input.buffer));
324         input.header.type = PERF_RECORD_ITRACE_START;
325         input.header.size = sizeof(event.record.itrace_start) + 0x8;
326
327         memset(&config, 0, sizeof(config));
328         config.sample_type |= (uint64_t) PERF_SAMPLE_CPU;
329
330         errcode = pev_read(&event, input.buffer,
331                            input.buffer + sizeof(input.buffer), &config);
332         ptu_int_eq(errcode, -pte_bad_config);
333
334         return ptu_passed();
335 }
336
337 static struct ptunit_result write_bad_config(void)
338 {
339         struct pev_record_itrace_start itrace_start;
340         struct pev_config config;
341         struct pev_event event;
342         uint32_t cpu;
343         uint8_t buffer[128];
344         int errcode;
345
346         memset(&itrace_start, 0, sizeof(itrace_start));
347
348         pev_event_init(&event);
349         event.type = PERF_RECORD_ITRACE_START;
350         event.record.itrace_start = &itrace_start;
351         event.sample.cpu = &cpu;
352
353         memset(&config, 0, sizeof(config));
354         config.sample_type |= (uint64_t) PERF_SAMPLE_CPU;
355
356         errcode = pev_write(&event, buffer, buffer + sizeof(buffer), &config);
357         ptu_int_eq(errcode, -pte_bad_config);
358
359         return ptu_passed();
360 }
361
362 static struct ptunit_result bad_string(uint16_t type)
363 {
364         union {
365                 struct perf_event_header header;
366                 uint8_t buffer[512];
367         } input;
368
369         struct pev_config config;
370         struct pev_event event;
371         int errcode;
372
373         pev_config_init(&config);
374
375         memset(input.buffer, 0xcc, sizeof(input.buffer));
376         input.header.type = type;
377         input.header.misc = 0;
378         input.header.size = 0x50;
379
380         errcode = pev_read(&event, input.buffer,
381                            input.buffer + sizeof(input.buffer), &config);
382         ptu_int_eq(errcode, -pte_bad_packet);
383
384         return ptu_passed();
385 }
386
387 static struct ptunit_result mmap(struct pev_fixture *pfix)
388 {
389         union {
390                 struct pev_record_mmap record;
391                 char buffer[1024];
392         } mmap;
393
394         mmap.record.pid = 0xa;
395         mmap.record.tid = 0xb;
396         mmap.record.addr = 0xa00100ull;
397         mmap.record.len = 0x110ull;
398         mmap.record.pgoff = 0xb0000ull;
399         strcpy(mmap.record.filename, "foo.so");
400
401         pfix->event[0].record.mmap = &mmap.record;
402         pfix->event[0].type = PERF_RECORD_MMAP;
403
404         ptu_test(pfix_read_write, pfix);
405         ptu_test(pfix_check_sample, pfix);
406
407         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
408         ptu_ptr(pfix->event[1].record.mmap);
409         ptu_uint_eq(pfix->event[1].record.mmap->pid, mmap.record.pid);
410         ptu_uint_eq(pfix->event[1].record.mmap->tid, mmap.record.tid);
411         ptu_uint_eq(pfix->event[1].record.mmap->addr, mmap.record.addr);
412         ptu_uint_eq(pfix->event[1].record.mmap->len, mmap.record.len);
413         ptu_uint_eq(pfix->event[1].record.mmap->pgoff, mmap.record.pgoff);
414         ptu_str_eq(pfix->event[1].record.mmap->filename, mmap.record.filename);
415
416         return ptu_passed();
417 }
418
419 static struct ptunit_result lost(struct pev_fixture *pfix)
420 {
421         struct pev_record_lost lost;
422
423         lost.id = 0xa042ull;
424         lost.lost = 0xeull;
425
426         pfix->event[0].record.lost = &lost;
427         pfix->event[0].type = PERF_RECORD_LOST;
428
429         ptu_test(pfix_read_write, pfix);
430         ptu_test(pfix_check_sample, pfix);
431
432         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
433         ptu_ptr(pfix->event[1].record.lost);
434         ptu_uint_eq(pfix->event[1].record.lost->id, lost.id);
435         ptu_uint_eq(pfix->event[1].record.lost->lost, lost.lost);
436
437         return ptu_passed();
438 }
439
440 static struct ptunit_result comm(struct pev_fixture *pfix)
441 {
442         union {
443                 struct pev_record_comm record;
444                 char buffer[1024];
445         } comm;
446
447         comm.record.pid = 0xa;
448         comm.record.tid = 0xb;
449         strcpy(comm.record.comm, "foo -b ar");
450
451         pfix->event[0].record.comm = &comm.record;
452         pfix->event[0].type = PERF_RECORD_COMM;
453
454         ptu_test(pfix_read_write, pfix);
455         ptu_test(pfix_check_sample, pfix);
456
457         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
458         ptu_ptr(pfix->event[1].record.comm);
459         ptu_uint_eq(pfix->event[1].record.comm->pid, comm.record.pid);
460         ptu_uint_eq(pfix->event[1].record.comm->tid, comm.record.tid);
461         ptu_str_eq(pfix->event[1].record.comm->comm, comm.record.comm);
462
463         return ptu_passed();
464 }
465
466 static struct ptunit_result record_exit(struct pev_fixture *pfix)
467 {
468         struct pev_record_exit exit;
469
470         exit.pid = 0xa;
471         exit.ppid = 0xaa;
472         exit.tid = 0xb;
473         exit.ptid = 0xab;
474         exit.time = 0xabcdefull;
475
476         pfix->event[0].record.exit = &exit;
477         pfix->event[0].type = PERF_RECORD_EXIT;
478
479         ptu_test(pfix_read_write, pfix);
480         ptu_test(pfix_check_sample, pfix);
481
482         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
483         ptu_ptr(pfix->event[1].record.exit);
484         ptu_uint_eq(pfix->event[1].record.exit->pid, exit.pid);
485         ptu_uint_eq(pfix->event[1].record.exit->ppid, exit.ppid);
486         ptu_uint_eq(pfix->event[1].record.exit->tid, exit.tid);
487         ptu_uint_eq(pfix->event[1].record.exit->ptid, exit.ptid);
488         ptu_uint_eq(pfix->event[1].record.exit->time, exit.time);
489
490         return ptu_passed();
491 }
492
493 static struct ptunit_result throttle(struct pev_fixture *pfix)
494 {
495         struct pev_record_throttle throttle;
496
497         throttle.time = 0xabcdeull;
498         throttle.id = 0xa042ull;
499         throttle.stream_id = 0xb00ull;
500
501         pfix->event[0].record.throttle = &throttle;
502         pfix->event[0].type = PERF_RECORD_THROTTLE;
503
504         ptu_test(pfix_read_write, pfix);
505         ptu_test(pfix_check_sample, pfix);
506
507         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
508         ptu_ptr(pfix->event[1].record.throttle);
509         ptu_uint_eq(pfix->event[1].record.throttle->time, throttle.time);
510         ptu_uint_eq(pfix->event[1].record.throttle->id, throttle.id);
511         ptu_uint_eq(pfix->event[1].record.throttle->stream_id,
512                     throttle.stream_id);
513
514         return ptu_passed();
515 }
516
517 static struct ptunit_result unthrottle(struct pev_fixture *pfix)
518 {
519         struct pev_record_throttle throttle;
520
521         throttle.time = 0xc00042ull;
522         throttle.id = 0x23ull;
523         throttle.stream_id = 0x0ull;
524
525         pfix->event[0].record.throttle = &throttle;
526         pfix->event[0].type = PERF_RECORD_UNTHROTTLE;
527
528         ptu_test(pfix_read_write, pfix);
529         ptu_test(pfix_check_sample, pfix);
530
531         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
532         ptu_ptr(pfix->event[1].record.throttle);
533         ptu_uint_eq(pfix->event[1].record.throttle->time, throttle.time);
534         ptu_uint_eq(pfix->event[1].record.throttle->id, throttle.id);
535         ptu_uint_eq(pfix->event[1].record.throttle->stream_id,
536                     throttle.stream_id);
537
538         return ptu_passed();
539 }
540
541 static struct ptunit_result fork(struct pev_fixture *pfix)
542 {
543         struct pev_record_fork fork;
544
545         fork.pid = 0xa;
546         fork.ppid = 0xaa;
547         fork.tid = 0xb;
548         fork.ptid = 0xab;
549         fork.time = 0xabcdefull;
550
551         pfix->event[0].record.fork = ⋔
552         pfix->event[0].type = PERF_RECORD_FORK;
553
554         ptu_test(pfix_read_write, pfix);
555         ptu_test(pfix_check_sample, pfix);
556
557         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
558         ptu_ptr(pfix->event[1].record.fork);
559         ptu_uint_eq(pfix->event[1].record.fork->pid, fork.pid);
560         ptu_uint_eq(pfix->event[1].record.fork->ppid, fork.ppid);
561         ptu_uint_eq(pfix->event[1].record.fork->tid, fork.tid);
562         ptu_uint_eq(pfix->event[1].record.fork->ptid, fork.ptid);
563         ptu_uint_eq(pfix->event[1].record.fork->time, fork.time);
564
565         return ptu_passed();
566 }
567
568 static struct ptunit_result mmap2(struct pev_fixture *pfix)
569 {
570         union {
571                 struct pev_record_mmap2 record;
572                 char buffer[1024];
573         } mmap2;
574
575         mmap2.record.pid = 0xa;
576         mmap2.record.tid = 0xb;
577         mmap2.record.addr = 0xa00100ull;
578         mmap2.record.len = 0x110ull;
579         mmap2.record.pgoff = 0xb0000ull;
580         mmap2.record.maj = 7;
581         mmap2.record.min = 2;
582         mmap2.record.ino = 0x8080ull;
583         mmap2.record.ino_generation = 0x4ull;
584         mmap2.record.prot = 0x755;
585         mmap2.record.flags = 0;
586         strcpy(mmap2.record.filename, "foo.so");
587
588         pfix->event[0].record.mmap2 = &mmap2.record;
589         pfix->event[0].type = PERF_RECORD_MMAP2;
590
591         ptu_test(pfix_read_write, pfix);
592         ptu_test(pfix_check_sample, pfix);
593
594         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
595         ptu_ptr(pfix->event[1].record.mmap2);
596         ptu_uint_eq(pfix->event[1].record.mmap2->pid, mmap2.record.pid);
597         ptu_uint_eq(pfix->event[1].record.mmap2->tid, mmap2.record.tid);
598         ptu_uint_eq(pfix->event[1].record.mmap2->addr, mmap2.record.addr);
599         ptu_uint_eq(pfix->event[1].record.mmap2->len, mmap2.record.len);
600         ptu_uint_eq(pfix->event[1].record.mmap2->pgoff, mmap2.record.pgoff);
601         ptu_uint_eq(pfix->event[1].record.mmap2->maj, mmap2.record.maj);
602         ptu_uint_eq(pfix->event[1].record.mmap2->min, mmap2.record.min);
603         ptu_uint_eq(pfix->event[1].record.mmap2->ino, mmap2.record.ino);
604         ptu_uint_eq(pfix->event[1].record.mmap2->ino_generation,
605                     mmap2.record.ino_generation);
606         ptu_uint_eq(pfix->event[1].record.mmap2->prot, mmap2.record.prot);
607         ptu_uint_eq(pfix->event[1].record.mmap2->flags, mmap2.record.flags);
608         ptu_str_eq(pfix->event[1].record.mmap2->filename,
609                    mmap2.record.filename);
610
611         return ptu_passed();
612 }
613
614 static struct ptunit_result aux(struct pev_fixture *pfix)
615 {
616         struct pev_record_aux aux;
617
618         aux.aux_offset = 0xc00042ull;
619         aux.aux_size = 0x23ull;
620         aux.flags = 0x0ull;
621
622         pfix->event[0].record.aux = &aux;
623         pfix->event[0].type = PERF_RECORD_AUX;
624
625         ptu_test(pfix_read_write, pfix);
626         ptu_test(pfix_check_sample, pfix);
627
628         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
629         ptu_ptr(pfix->event[1].record.aux);
630         ptu_uint_eq(pfix->event[1].record.aux->aux_offset, aux.aux_offset);
631         ptu_uint_eq(pfix->event[1].record.aux->aux_size, aux.aux_size);
632         ptu_uint_eq(pfix->event[1].record.aux->flags, aux.flags);
633
634         return ptu_passed();
635 }
636
637 static struct ptunit_result itrace_start(struct pev_fixture *pfix)
638 {
639         struct pev_record_itrace_start itrace_start;
640
641         itrace_start.pid = 0xa;
642         itrace_start.tid = 0xb;
643
644         pfix->event[0].record.itrace_start = &itrace_start;
645         pfix->event[0].type = PERF_RECORD_ITRACE_START;
646
647         ptu_test(pfix_read_write, pfix);
648         ptu_test(pfix_check_sample, pfix);
649
650         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
651         ptu_ptr(pfix->event[1].record.itrace_start);
652         ptu_uint_eq(pfix->event[1].record.itrace_start->pid, itrace_start.pid);
653         ptu_uint_eq(pfix->event[1].record.itrace_start->tid, itrace_start.tid);
654
655         return ptu_passed();
656 }
657
658 static struct ptunit_result lost_samples(struct pev_fixture *pfix)
659 {
660         struct pev_record_lost_samples lost_samples;
661
662         lost_samples.lost = 0xc00042ull;
663
664         pfix->event[0].record.lost_samples = &lost_samples;
665         pfix->event[0].type = PERF_RECORD_LOST_SAMPLES;
666
667         ptu_test(pfix_read_write, pfix);
668         ptu_test(pfix_check_sample, pfix);
669
670         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
671         ptu_ptr(pfix->event[1].record.lost_samples);
672         ptu_uint_eq(pfix->event[1].record.lost_samples->lost,
673                     lost_samples.lost);
674
675         return ptu_passed();
676 }
677
678 static struct ptunit_result switch_task(struct pev_fixture *pfix,
679                                         int switch_out)
680 {
681         pfix->event[0].type = PERF_RECORD_SWITCH;
682         pfix->event[0].misc = switch_out ? PERF_RECORD_MISC_SWITCH_OUT : 0;
683
684         ptu_test(pfix_read_write, pfix);
685         ptu_test(pfix_check_sample, pfix);
686
687         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
688         ptu_int_eq(pfix->event[1].misc, pfix->event[0].misc);
689
690         return ptu_passed();
691 }
692
693 static struct ptunit_result switch_cpu_wide(struct pev_fixture *pfix,
694                                             int switch_out)
695 {
696         struct pev_record_switch_cpu_wide switch_cpu_wide;
697
698         switch_cpu_wide.next_prev_pid = 0xa;
699         switch_cpu_wide.next_prev_tid = 0xb;
700
701         pfix->event[0].record.switch_cpu_wide = &switch_cpu_wide;
702         pfix->event[0].type = PERF_RECORD_SWITCH_CPU_WIDE;
703         pfix->event[0].misc = switch_out ? PERF_RECORD_MISC_SWITCH_OUT : 0;
704
705         ptu_test(pfix_read_write, pfix);
706         ptu_test(pfix_check_sample, pfix);
707
708         ptu_int_eq(pfix->event[1].type, pfix->event[0].type);
709         ptu_int_eq(pfix->event[1].misc, pfix->event[0].misc);
710         ptu_ptr(pfix->event[1].record.switch_cpu_wide);
711         ptu_uint_eq(pfix->event[1].record.switch_cpu_wide->next_prev_pid,
712                     switch_cpu_wide.next_prev_pid);
713         ptu_uint_eq(pfix->event[1].record.switch_cpu_wide->next_prev_tid,
714                     switch_cpu_wide.next_prev_tid);
715
716         return ptu_passed();
717 }
718
719 int main(int argc, char **argv)
720 {
721         struct pev_fixture pfix, pfix_time, pfix_who;
722         struct ptunit_suite suite;
723
724         pfix.init = pfix_init;
725         pfix.fini = NULL;
726
727         pfix_time.init = pfix_init_sample_time;
728         pfix_time.fini = NULL;
729
730         pfix_who.init = pfix_init_sample_who;
731         pfix_who.fini = NULL;
732
733         suite = ptunit_mk_suite(argc, argv);
734
735         ptu_run(suite, time_to_tsc_null);
736         ptu_run(suite, time_from_tsc_null);
737
738         ptu_run(suite, time_to_tsc);
739         ptu_run(suite, time_from_tsc);
740
741         ptu_run(suite, time_to_tsc_bad_config);
742         ptu_run(suite, time_from_tsc_bad_config);
743         ptu_run(suite, read_bad_config);
744         ptu_run(suite, write_bad_config);
745
746         ptu_run_p(suite, bad_string, PERF_RECORD_MMAP);
747         ptu_run_p(suite, bad_string, PERF_RECORD_COMM);
748         ptu_run_p(suite, bad_string, PERF_RECORD_MMAP2);
749
750         ptu_run_f(suite, mmap, pfix);
751         ptu_run_f(suite, lost, pfix);
752         ptu_run_f(suite, comm, pfix);
753         ptu_run_f(suite, record_exit, pfix);
754         ptu_run_f(suite, throttle, pfix);
755         ptu_run_f(suite, unthrottle, pfix);
756         ptu_run_f(suite, fork, pfix);
757         ptu_run_f(suite, mmap2, pfix);
758         ptu_run_f(suite, aux, pfix);
759         ptu_run_f(suite, itrace_start, pfix);
760         ptu_run_f(suite, lost_samples, pfix);
761         ptu_run_fp(suite, switch_task, pfix, 0);
762         ptu_run_fp(suite, switch_task, pfix, 1);
763         ptu_run_fp(suite, switch_cpu_wide, pfix, 0);
764         ptu_run_fp(suite, switch_cpu_wide, pfix, 1);
765
766         ptu_run_f(suite, mmap, pfix_time);
767         ptu_run_f(suite, lost, pfix_time);
768         ptu_run_f(suite, comm, pfix_time);
769         ptu_run_f(suite, record_exit, pfix_time);
770         ptu_run_f(suite, throttle, pfix_time);
771         ptu_run_f(suite, unthrottle, pfix_time);
772         ptu_run_f(suite, fork, pfix_time);
773         ptu_run_f(suite, mmap2, pfix_time);
774         ptu_run_f(suite, aux, pfix_time);
775         ptu_run_f(suite, itrace_start, pfix_time);
776         ptu_run_f(suite, lost_samples, pfix_time);
777         ptu_run_fp(suite, switch_task, pfix_time, 0);
778         ptu_run_fp(suite, switch_task, pfix_time, 1);
779         ptu_run_fp(suite, switch_cpu_wide, pfix_time, 0);
780         ptu_run_fp(suite, switch_cpu_wide, pfix_time, 1);
781
782         ptu_run_f(suite, mmap, pfix_who);
783         ptu_run_f(suite, lost, pfix_who);
784         ptu_run_f(suite, comm, pfix_who);
785         ptu_run_f(suite, record_exit, pfix_who);
786         ptu_run_f(suite, throttle, pfix_who);
787         ptu_run_f(suite, unthrottle, pfix_who);
788         ptu_run_f(suite, fork, pfix_who);
789         ptu_run_f(suite, mmap2, pfix_who);
790         ptu_run_f(suite, aux, pfix_who);
791         ptu_run_f(suite, itrace_start, pfix_who);
792         ptu_run_f(suite, lost_samples, pfix_who);
793         ptu_run_fp(suite, switch_task, pfix_who, 0);
794         ptu_run_fp(suite, switch_task, pfix_who, 1);
795         ptu_run_fp(suite, switch_cpu_wide, pfix_who, 0);
796         ptu_run_fp(suite, switch_cpu_wide, pfix_who, 1);
797
798         return ptunit_report(&suite);
799 }