source: test/test-tracetime-parallel.c @ 6c84681

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 6c84681 was 6c84681, checked in by Richard Sanger <rsangerarj@…>, 6 years ago

Add test for the tracetime playback option.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Richard Sanger
6 *
7 * All rights reserved.
8 *
9 * This code has been developed by the University of Waikato WAND
10 * research group. For further information please see http://www.wand.net.nz/
11 *
12 * libtrace is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * libtrace is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with libtrace; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25 *
26 * $Id$
27 *
28 */
29
30#ifndef WIN32
31#include <sys/time.h>
32#endif
33#include <stdio.h>
34#include <stdlib.h>
35#include <assert.h>
36#include <sys/types.h>
37#include <signal.h>
38#include <unistd.h>
39#include "libtrace_parallel.h"
40
41static double timeval_to_seconds(struct timeval tv) {
42        return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
43}
44
45static void iferr(libtrace_t *trace,const char *msg)
46{
47        libtrace_err_t err = trace_get_err(trace);
48        if (err.err_num==0)
49                return;
50        printf("Error: %s: %s\n", msg, err.problem);
51        exit(1);
52}
53
54static bool check_range_jitter(double test, double target, double jit) {
55        if ((test <= target + jit) && (test >= target - jit)) {
56                return true;
57        } else {
58                printf("Have:%f Expected:%f (%f-%f)", test, target, target - jit, target + jit);
59                return false;
60        }
61}
62
63
64static int totalpkts = 0;
65static int skippedpkts = 0;
66static int expected;
67
68libtrace_t *trace = NULL;
69static void signal_handler(int signal)
70{
71        int i = 0;
72        if (signal == SIGALRM) {
73                trace_ppause(trace);
74
75                /* check within 10 seconds we got 9-11 packets */
76                assert(check_range_jitter(10.0, (double) totalpkts, 1.0));
77
78                /* Now fullspeed it */
79                trace_parallel_config(trace, TRACE_OPTION_TRACETIME, &i);
80
81                /* And restart */
82                trace_pstart(trace, NULL, NULL, NULL);
83        }
84}
85
86static void report_result(libtrace_t *trace UNUSED, int mesg,
87                          libtrace_generic_t data,
88                          libtrace_thread_t *sender UNUSED) {
89
90        switch (mesg) {
91        case MESSAGE_STARTING:
92                break;
93        case MESSAGE_RESULT:
94                switch (data.res->type) {
95                case RESULT_USER:
96                        totalpkts++;
97                        break;
98                case RESULT_USER+1:
99                        skippedpkts++;
100                        break;
101                }
102                break;
103        }
104}
105
106static void* per_packet(libtrace_t *trace, libtrace_thread_t *t,
107                        int mesg, libtrace_generic_t data,
108                        libtrace_thread_t *sender UNUSED) {
109        struct timeval tv;
110        double time;
111        libtrace_message_t message;
112        static __thread bool accepting = true;
113
114        gettimeofday(&tv, NULL);
115        time = timeval_to_seconds(tv);
116
117        switch (mesg) {
118        case MESSAGE_PACKET:
119                /* In order to instantly pause a trace we don't delay any buffered packets
120                 * These are sent after MESSAGE_PAUSING has been received */
121                if (accepting) {
122                        fprintf(stderr, ".");
123                        trace_publish_result(trace, t, (uint64_t) time, (libtrace_generic_t){.rdouble = time}, RESULT_USER);
124
125                        /* Check that we are not blocking regular message delivery */
126                        message.code = MESSAGE_USER;
127                        message.sender = t;
128                        message.data.rdouble = time;
129                        trace_message_perpkts(trace, &message);
130                } else {
131                        trace_publish_result(trace, t, (uint64_t) time, (libtrace_generic_t){.rdouble = time}, RESULT_USER+1);
132                }
133                return data.pkt;
134        case MESSAGE_USER:
135                assert (check_range_jitter(data.rdouble, time, 0.01));
136                break;
137        case MESSAGE_RESUMING:
138                accepting = true;
139                break;
140        case MESSAGE_PAUSING:
141                accepting = false;
142                break;
143        }
144        return NULL;
145}
146
147/**
148 * Test that tracetime playback functions.
149 * Including:
150 * * Delaying packets
151 * * Not blocking messages
152 * * Instantly returning when paused (or stopped)
153 * * Can be switched off/on from a paused state
154 */
155int test_tracetime(const char *tracename) {
156        int error = 0;
157        int i;
158        struct timeval tv;
159        double start, end;
160        gettimeofday(&tv, NULL);
161        start = timeval_to_seconds(tv);
162        printf("Testing delay\n");
163
164        // Create the trace
165        trace = trace_create(tracename);
166        iferr(trace,tracename);
167
168        // Always use 2 threads for simplicity
169        i = 2;
170        trace_parallel_config(trace, TRACE_OPTION_SET_PERPKT_THREAD_COUNT, &i);
171        i = 1;
172        trace_parallel_config(trace, TRACE_OPTION_TRACETIME, &i);
173
174        // Start it
175        trace_pstart(trace, NULL, per_packet, report_result);
176        iferr(trace,tracename);
177        fprintf(stderr, "Running in tracetime (Will take about 10 seconds)\t");
178
179        // Timeout after 10 which should be about 10 packets seconds
180        alarm(10);
181
182        /* Wait for all threads to stop */
183        trace_join(trace);
184
185        /* Now check we have all received all the packets */
186        assert(skippedpkts <= 20); /* Note this is hard coded to the default burst_sizeX2 */
187        if (error == 0) {
188                if (totalpkts + skippedpkts == expected) {
189                        printf("success: %d packets read\n",expected);
190                } else {
191                        printf("failure: %d packets expected, %d seen\n",expected,totalpkts);
192                        error = 1;
193                }
194        } else {
195                iferr(trace,tracename);
196        }
197        /* The whole test should take about 10 seconds */
198        gettimeofday(&tv, NULL);
199        end = timeval_to_seconds(tv);
200        assert(check_range_jitter(end-start, 10.0, 1.0));
201        trace_destroy(trace);
202        return error;
203}
204
205int main() {
206        int error = 0;
207        const char *tracename;
208        expected = 100;
209
210        signal(SIGALRM, signal_handler);
211
212        tracename = "pcapfile:traces/100_seconds.pcap";
213
214        error = test_tracetime(tracename);
215
216        return error;
217}
Note: See TracBrowser for help on using the repository browser.