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

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

Removes pconfig_input() and replaces trace_config() with trace_set_<option>

  • Removes trace_pconfig completely - only trace_set_hasher is left now in trace_config
  • Rework user configuration so this is no longer modified directly. Now we just apply it directly to a trace.
  • Many minor documentation fixes and additions
  • Property mode set to 100644
File size: 5.4 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        if (signal == SIGALRM) {
72                trace_ppause(trace);
73
74                /* check within 10 seconds we got 9-11 packets */
75                assert(check_range_jitter(10.0, (double) totalpkts, 1.0));
76
77                /* Now fullspeed it */
78                trace_set_tracetime(trace, false);
79
80                /* And restart */
81                trace_pstart(trace, NULL, NULL, NULL);
82        }
83}
84
85static void report_result(libtrace_t *trace UNUSED, int mesg,
86                          libtrace_generic_t data,
87                          libtrace_thread_t *sender UNUSED) {
88
89        switch (mesg) {
90        case MESSAGE_STARTING:
91                break;
92        case MESSAGE_RESULT:
93                switch (data.res->type) {
94                case RESULT_USER:
95                        totalpkts++;
96                        break;
97                case RESULT_USER+1:
98                        skippedpkts++;
99                        break;
100                }
101                break;
102        }
103}
104
105static void* per_packet(libtrace_t *trace, libtrace_thread_t *t,
106                        int mesg, libtrace_generic_t data,
107                        libtrace_thread_t *sender UNUSED) {
108        struct timeval tv;
109        double time;
110        libtrace_message_t message;
111        static __thread bool accepting = true;
112
113        gettimeofday(&tv, NULL);
114        time = timeval_to_seconds(tv);
115
116        switch (mesg) {
117        case MESSAGE_PACKET:
118                /* In order to instantly pause a trace we don't delay any buffered packets
119                 * These are sent after MESSAGE_PAUSING has been received */
120                if (accepting) {
121                        fprintf(stderr, ".");
122                        trace_publish_result(trace, t, (uint64_t) time, (libtrace_generic_t){.rdouble = time}, RESULT_USER);
123
124                        /* Check that we are not blocking regular message delivery */
125                        message.code = MESSAGE_USER;
126                        message.sender = t;
127                        message.data.rdouble = time;
128                        trace_message_perpkts(trace, &message);
129                } else {
130                        trace_publish_result(trace, t, (uint64_t) time, (libtrace_generic_t){.rdouble = time}, RESULT_USER+1);
131                }
132                return data.pkt;
133        case MESSAGE_USER:
134                assert (check_range_jitter(data.rdouble, time, 0.01));
135                break;
136        case MESSAGE_RESUMING:
137                accepting = true;
138                break;
139        case MESSAGE_PAUSING:
140                accepting = false;
141                break;
142        }
143        return NULL;
144}
145
146/**
147 * Test that tracetime playback functions.
148 * Including:
149 * * Delaying packets
150 * * Not blocking messages
151 * * Instantly returning when paused (or stopped)
152 * * Can be switched off/on from a paused state
153 */
154int test_tracetime(const char *tracename) {
155        int error = 0;
156        struct timeval tv;
157        double start, end;
158        gettimeofday(&tv, NULL);
159        start = timeval_to_seconds(tv);
160        printf("Testing delay\n");
161
162        // Create the trace
163        trace = trace_create(tracename);
164        iferr(trace,tracename);
165
166        // Always use 2 threads for simplicity
167        trace_set_perpkt_threads(trace, 2);
168        trace_set_tracetime(trace, true);
169
170        // Start it
171        trace_pstart(trace, NULL, per_packet, report_result);
172        iferr(trace,tracename);
173        fprintf(stderr, "Running in tracetime (Will take about 10 seconds)\t");
174
175        // Timeout after 10 which should be about 10 packets seconds
176        alarm(10);
177
178        /* Wait for all threads to stop */
179        trace_join(trace);
180
181        /* Now check we have all received all the packets */
182        assert(skippedpkts <= 20); /* Note this is hard coded to the default burst_sizeX2 */
183        if (error == 0) {
184                if (totalpkts + skippedpkts == expected) {
185                        printf("success: %d packets read\n",expected);
186                } else {
187                        printf("failure: %d packets expected, %d seen\n",expected,totalpkts);
188                        error = 1;
189                }
190        } else {
191                iferr(trace,tracename);
192        }
193        /* The whole test should take about 10 seconds */
194        gettimeofday(&tv, NULL);
195        end = timeval_to_seconds(tv);
196        assert(check_range_jitter(end-start, 10.0, 1.0));
197        trace_destroy(trace);
198        return error;
199}
200
201int main() {
202        int error = 0;
203        const char *tracename;
204        expected = 100;
205
206        signal(SIGALRM, signal_handler);
207
208        tracename = "pcapfile:traces/100_seconds.pcap";
209
210        error = test_tracetime(tracename);
211
212        return error;
213}
Note: See TracBrowser for help on using the repository browser.