Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/kern/acct/acct_test.c
39488 views
1
/*-
2
* Copyright (c) 2011 Giorgos Keramidas. All rights reserved.
3
* Copyright (c) 2007 Diomidis Spinellis. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
*
13
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
* SUCH DAMAGE.
24
*/
25
26
#include <sys/types.h>
27
28
#include <assert.h>
29
#include <errno.h>
30
#include <float.h>
31
#include <limits.h>
32
#include <math.h>
33
#include <stdio.h>
34
#include <stdint.h>
35
#include <stdlib.h>
36
#include <strings.h>
37
#include <syslog.h>
38
#include <time.h>
39
40
#include <atf-c.h>
41
42
#define KASSERT(val, msg) assert(val)
43
44
typedef u_int32_t comp_t;
45
46
#define AHZ 1000000
47
48
#include "convert.c"
49
50
union cf {
51
comp_t c;
52
float f;
53
};
54
55
static void
56
check_result(const char *name, float expected, union cf v)
57
{
58
double eps;
59
60
eps = fabs(expected - v.f) / expected;
61
ATF_CHECK(eps <= FLT_EPSILON);
62
if (eps > FLT_EPSILON) {
63
printf("Error in %s\n", name);
64
printf("Got 0x%08x %12g\n", v.c, v.f);
65
v.f = expected;
66
printf("Expected 0x%08x %12g (%.15lg)\n", v.c, v.f, expected);
67
printf("Epsilon=%lg, rather than %g\n", eps, FLT_EPSILON);
68
}
69
}
70
71
/*
72
* Test case for encoding {0 sec, 0 usec} within a reasonable epsilon.
73
*/
74
75
ATF_TC_WITHOUT_HEAD(encode_tv_zero);
76
ATF_TC_BODY(encode_tv_zero, tc)
77
{
78
union cf v;
79
struct timeval tv;
80
81
tv.tv_sec = 0;
82
tv.tv_usec = 0;
83
v.c = encode_timeval(tv);
84
ATF_CHECK(fabs(v.f - 0.0) < FLT_EPSILON);
85
}
86
87
/*
88
* Test case for encoding a random long number.
89
*/
90
91
ATF_TC_WITHOUT_HEAD(encode_long);
92
ATF_TC_BODY(encode_long, tc)
93
{
94
union cf v;
95
long l;
96
97
l = random();
98
v.c = encode_long(l);
99
check_result(atf_tc_get_ident(tc), l, v);
100
}
101
102
/*
103
* Test case for encoding a small number of seconds {1 sec, 0 usec}.
104
*/
105
106
ATF_TC_WITHOUT_HEAD(encode_tv_only_sec);
107
ATF_TC_BODY(encode_tv_only_sec, tc)
108
{
109
union cf v;
110
struct timeval tv;
111
112
tv.tv_sec = 1;
113
tv.tv_usec = 0;
114
v.c = encode_timeval(tv);
115
check_result(atf_tc_get_ident(tc),
116
(float)tv.tv_sec * AHZ + tv.tv_usec, v);
117
}
118
119
/*
120
* Test case for encoding a small number of usec {0 sec, 1 usec}.
121
*/
122
123
ATF_TC_WITHOUT_HEAD(encode_tv_only_usec);
124
ATF_TC_BODY(encode_tv_only_usec, tc)
125
{
126
union cf v;
127
struct timeval tv;
128
129
tv.tv_sec = 0;
130
tv.tv_usec = 1;
131
v.c = encode_timeval(tv);
132
check_result(atf_tc_get_ident(tc),
133
(float)tv.tv_sec * AHZ + tv.tv_usec, v);
134
}
135
136
/*
137
* Test case for encoding a large number of usec {1 sec, 999.999 usec}.
138
*/
139
140
ATF_TC_WITHOUT_HEAD(encode_tv_many_usec);
141
ATF_TC_BODY(encode_tv_many_usec, tc)
142
{
143
union cf v;
144
struct timeval tv;
145
146
tv.tv_sec = 1;
147
tv.tv_usec = 999999L;
148
v.c = encode_timeval(tv);
149
check_result(atf_tc_get_ident(tc),
150
(float)tv.tv_sec * AHZ + tv.tv_usec, v);
151
}
152
153
/*
154
* Test case for encoding a huge number of usec {1 sec, 1.000.000 usec} that
155
* overflows the usec counter and should show up as an increase in timeval's
156
* seconds instead.
157
*/
158
159
ATF_TC_WITHOUT_HEAD(encode_tv_usec_overflow);
160
ATF_TC_BODY(encode_tv_usec_overflow, tc)
161
{
162
union cf v;
163
struct timeval tv;
164
165
tv.tv_sec = 1;
166
tv.tv_usec = 1000000L;
167
v.c = encode_timeval(tv);
168
check_result(atf_tc_get_ident(tc),
169
(float)tv.tv_sec * AHZ + tv.tv_usec, v);
170
}
171
172
/*
173
* Test case for encoding a very large number of seconds, one that is very
174
* near to the limit of 32-bit signed values. With a usec value of 999.999
175
* microseconds this should result in the largest value we can represent with
176
* a timeval struct.
177
*/
178
179
ATF_TC_WITHOUT_HEAD(encode_tv_upper_limit);
180
ATF_TC_BODY(encode_tv_upper_limit, tc)
181
{
182
union cf v;
183
struct timeval tv;
184
185
tv.tv_sec = 2147483647L;
186
tv.tv_usec = 999999L;
187
v.c = encode_timeval(tv);
188
check_result(atf_tc_get_ident(tc),
189
(float)tv.tv_sec * AHZ + tv.tv_usec, v);
190
}
191
192
/*
193
* Test case for encoding a million random timeval objects, and checking that
194
* the conversion does not diverge too much from the expected values.
195
*/
196
197
ATF_TC_WITHOUT_HEAD(encode_tv_random_million);
198
ATF_TC_BODY(encode_tv_random_million, tc)
199
{
200
union cf v;
201
struct timeval tv;
202
long k;
203
204
#ifdef __LP64__
205
atf_tc_expect_fail("the testcase violates FLT_EPSILON on 64-bit "
206
"platforms, e.g. amd64");
207
#endif
208
209
ATF_REQUIRE_MSG(unsetenv("TZ") == 0, "unsetting TZ failed; errno=%d", errno);
210
211
for (k = 1; k < 1000000L; k++) {
212
tv.tv_sec = random();
213
tv.tv_usec = (random() % 1000000L);
214
v.c = encode_timeval(tv);
215
check_result(atf_tc_get_ident(tc),
216
(float)tv.tv_sec * AHZ + tv.tv_usec, v);
217
}
218
}
219
220
/* ---------------------------------------------------------------------
221
* Main.
222
* --------------------------------------------------------------------- */
223
224
ATF_TP_ADD_TCS(tp)
225
{
226
227
ATF_TP_ADD_TC(tp, encode_long);
228
ATF_TP_ADD_TC(tp, encode_tv_zero);
229
ATF_TP_ADD_TC(tp, encode_tv_only_sec);
230
ATF_TP_ADD_TC(tp, encode_tv_only_usec);
231
ATF_TP_ADD_TC(tp, encode_tv_many_usec);
232
ATF_TP_ADD_TC(tp, encode_tv_usec_overflow);
233
ATF_TP_ADD_TC(tp, encode_tv_upper_limit);
234
ATF_TP_ADD_TC(tp, encode_tv_random_million);
235
236
return atf_no_error();
237
}
238
239