Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/lib/iolog/regress/iolog_timing/check_iolog_timing.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2018 Todd C. Miller <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*/
18
19
#include <config.h>
20
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <time.h>
25
#include <unistd.h>
26
27
#define SUDO_ERROR_WRAP 0
28
29
#include <sudo_compat.h>
30
#include <sudo_util.h>
31
#include <sudo_fatal.h>
32
#include <sudo_iolog.h>
33
34
sudo_dso_public int main(int argc, char *argv[]);
35
36
static struct parse_delay_test {
37
const char *input;
38
const char *next_field;
39
struct timespec expected_delay;
40
} parse_delay_tests[] = {
41
{ "10.99999999999 X", "X", { 10, 999999999 } }, /* clamp to nsec */
42
{ "10.999999999 X", "X", { 10, 999999999 } }, /* nsec */
43
{ "10.999999 X", "X", { 10, 999999000 } }, /* usec -> nsec */
44
{ "10.000999999 X", "X", { 10, 999999 } },
45
{ "10.9 X", "X", { 10, 900000000 } },
46
{ "10.0 X", "X", { 10, 0 } }
47
};
48
49
/*
50
* Test iolog_parse_delay()
51
*/
52
static void
53
test_parse_delay(int *ntests, int *nerrors)
54
{
55
unsigned int i;
56
57
for (i = 0; i < nitems(parse_delay_tests); i++) {
58
struct timespec delay;
59
struct parse_delay_test *test = &parse_delay_tests[i];
60
char *cp = iolog_parse_delay(test->input, &delay, ".");
61
if (cp == NULL) {
62
sudo_warnx("%s:%u failed to parse delay: %s", __func__,
63
i, test->input);
64
(*nerrors)++;
65
continue;
66
}
67
if (strcmp(cp, test->next_field) != 0) {
68
sudo_warnx("%s:%u next field (want \"%s\", got \"%s\"", __func__,
69
i, test->next_field, cp);
70
(*nerrors)++;
71
continue;
72
}
73
if (delay.tv_sec != test->expected_delay.tv_sec) {
74
sudo_warnx("%s:%u wrong seconds (want %lld, got %lld)", __func__,
75
i, (long long)test->expected_delay.tv_sec,
76
(long long)delay.tv_sec);
77
(*nerrors)++;
78
continue;
79
}
80
if (delay.tv_nsec != test->expected_delay.tv_nsec) {
81
sudo_warnx("%s:%u wrong nanoseconds (want %ld, got %ld)", __func__,
82
i, test->expected_delay.tv_nsec, delay.tv_nsec);
83
(*nerrors)++;
84
continue;
85
}
86
}
87
(*ntests) += (int)i;
88
}
89
90
static struct adjust_delay_test {
91
struct timespec in_delay;
92
struct timespec out_delay;
93
struct timespec max_delay;
94
double scale_factor;
95
} adjust_delay_tests[] = {
96
{ { 10, 300 }, { 10, 300 }, { 0, 0 }, 1.0 },
97
{ { 10, 300 }, { 5, 150 }, { 0, 0 }, 2.0 },
98
{ { 5, 300 }, { 2, 500000150 }, { 0, 0 }, 2.0 },
99
{ { 0, 1000000 }, { 0, 333333 }, { 0, 0 }, 3 },
100
{ { 10, 1000000 }, { 3, 333666666 }, { 0, 0 }, 3 },
101
{ { 5, 150 }, { 10, 300 }, { 0, 0 }, 0.5 },
102
{ { 5, 500000000 }, { 11, 0 }, { 0, 0 }, 0.5 },
103
{ { 5, 150 }, { 5, 0 }, { 5, 0 }, 0.5 }
104
};
105
106
/*
107
* Test iolog_adjust_delay()
108
*/
109
static void
110
test_adjust_delay(int *ntests, int *nerrors)
111
{
112
unsigned int i;
113
114
for (i = 0; i < nitems(adjust_delay_tests); i++) {
115
struct adjust_delay_test *test = &adjust_delay_tests[i];
116
117
iolog_adjust_delay(&test->in_delay,
118
sudo_timespecisset(&test->max_delay) ? &test->max_delay : NULL,
119
test->scale_factor);
120
if (!sudo_timespeccmp(&test->in_delay, &test->out_delay, ==)) {
121
sudo_warnx("%s:%u want {%lld, %ld}, got {%lld, %ld}", __func__, i,
122
(long long)test->out_delay.tv_sec, test->out_delay.tv_nsec,
123
(long long)test->in_delay.tv_sec, test->in_delay.tv_nsec);
124
(*nerrors)++;
125
}
126
}
127
(*ntests) += (int)i;
128
}
129
130
int
131
main(int argc, char *argv[])
132
{
133
int ch, ntests = 0, errors = 0;
134
135
initprogname(argc > 0 ? argv[0] : "check_iolog_timing");
136
137
while ((ch = getopt(argc, argv, "v")) != -1) {
138
switch (ch) {
139
case 'v':
140
/* ignore */
141
break;
142
default:
143
fprintf(stderr, "usage: %s [-v]\n", getprogname());
144
return EXIT_FAILURE;
145
}
146
}
147
argc -= optind;
148
argv += optind;
149
150
test_parse_delay(&ntests, &errors);
151
152
test_adjust_delay(&ntests, &errors);
153
154
if (ntests != 0) {
155
printf("iolog_timing: %d test%s run, %d errors, %d%% success rate\n",
156
ntests, ntests == 1 ? "" : "s", errors,
157
(ntests - errors) * 100 / ntests);
158
}
159
160
return errors;
161
}
162
163