OSDN Git Service

selftests/timers: Add missing fflush(stdout) calls
[android-x86/kernel.git] / tools / testing / selftests / timers / valid-adjtimex.c
1 /* valid adjtimex test
2  *              by: John Stultz <john.stultz@linaro.org>
3  *              (C) Copyright Linaro 2015
4  *              Licensed under the GPLv2
5  *
6  *  This test validates adjtimex interface with valid
7  *  and invalid test data.
8  *
9  *  Usage: valid-adjtimex
10  *
11  *  To build:
12  *      $ gcc valid-adjtimex.c -o valid-adjtimex -lrt
13  *
14  *   This program is free software: you can redistribute it and/or modify
15  *   it under the terms of the GNU General Public License as published by
16  *   the Free Software Foundation, either version 2 of the License, or
17  *   (at your option) any later version.
18  *
19  *   This program is distributed in the hope that it will be useful,
20  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *   GNU General Public License for more details.
23  */
24
25
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <time.h>
30 #include <sys/time.h>
31 #include <sys/timex.h>
32 #include <string.h>
33 #include <signal.h>
34 #include <unistd.h>
35 #ifdef KTEST
36 #include "../kselftest.h"
37 #else
38 static inline int ksft_exit_pass(void)
39 {
40         exit(0);
41 }
42 static inline int ksft_exit_fail(void)
43 {
44         exit(1);
45 }
46 #endif
47
48 #define NSEC_PER_SEC 1000000000LL
49 #define USEC_PER_SEC 1000000LL
50
51 #define ADJ_SETOFFSET 0x0100
52
53 #include <sys/syscall.h>
54 static int clock_adjtime(clockid_t id, struct timex *tx)
55 {
56         return syscall(__NR_clock_adjtime, id, tx);
57 }
58
59
60 /* clear NTP time_status & time_state */
61 int clear_time_state(void)
62 {
63         struct timex tx;
64         int ret;
65
66         tx.modes = ADJ_STATUS;
67         tx.status = 0;
68         ret = adjtimex(&tx);
69         return ret;
70 }
71
72 #define NUM_FREQ_VALID 32
73 #define NUM_FREQ_OUTOFRANGE 4
74 #define NUM_FREQ_INVALID 2
75
76 long valid_freq[NUM_FREQ_VALID] = {
77         -499<<16,
78         -450<<16,
79         -400<<16,
80         -350<<16,
81         -300<<16,
82         -250<<16,
83         -200<<16,
84         -150<<16,
85         -100<<16,
86         -75<<16,
87         -50<<16,
88         -25<<16,
89         -10<<16,
90         -5<<16,
91         -1<<16,
92         -1000,
93         1<<16,
94         5<<16,
95         10<<16,
96         25<<16,
97         50<<16,
98         75<<16,
99         100<<16,
100         150<<16,
101         200<<16,
102         250<<16,
103         300<<16,
104         350<<16,
105         400<<16,
106         450<<16,
107         499<<16,
108 };
109
110 long outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
111         -1000<<16,
112         -550<<16,
113         550<<16,
114         1000<<16,
115 };
116
117 #define LONG_MAX (~0UL>>1)
118 #define LONG_MIN (-LONG_MAX - 1)
119
120 long invalid_freq[NUM_FREQ_INVALID] = {
121         LONG_MAX,
122         LONG_MIN,
123 };
124
125 int validate_freq(void)
126 {
127         struct timex tx;
128         int ret, pass = 0;
129         int i;
130
131         clear_time_state();
132
133         memset(&tx, 0, sizeof(struct timex));
134         /* Set the leap second insert flag */
135
136         printf("Testing ADJ_FREQ... ");
137         fflush(stdout);
138         for (i = 0; i < NUM_FREQ_VALID; i++) {
139                 tx.modes = ADJ_FREQUENCY;
140                 tx.freq = valid_freq[i];
141
142                 ret = adjtimex(&tx);
143                 if (ret < 0) {
144                         printf("[FAIL]\n");
145                         printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
146                                 valid_freq[i], valid_freq[i]>>16);
147                         pass = -1;
148                         goto out;
149                 }
150                 tx.modes = 0;
151                 ret = adjtimex(&tx);
152                 if (tx.freq != valid_freq[i]) {
153                         printf("Warning: freq value %ld not what we set it (%ld)!\n",
154                                         tx.freq, valid_freq[i]);
155                 }
156         }
157         for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) {
158                 tx.modes = ADJ_FREQUENCY;
159                 tx.freq = outofrange_freq[i];
160
161                 ret = adjtimex(&tx);
162                 if (ret < 0) {
163                         printf("[FAIL]\n");
164                         printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
165                                 outofrange_freq[i], outofrange_freq[i]>>16);
166                         pass = -1;
167                         goto out;
168                 }
169                 tx.modes = 0;
170                 ret = adjtimex(&tx);
171                 if (tx.freq == outofrange_freq[i]) {
172                         printf("[FAIL]\n");
173                         printf("ERROR: out of range value %ld actually set!\n",
174                                         tx.freq);
175                         pass = -1;
176                         goto out;
177                 }
178         }
179
180
181         if (sizeof(long) == 8) { /* this case only applies to 64bit systems */
182                 for (i = 0; i < NUM_FREQ_INVALID; i++) {
183                         tx.modes = ADJ_FREQUENCY;
184                         tx.freq = invalid_freq[i];
185                         ret = adjtimex(&tx);
186                         if (ret >= 0) {
187                                 printf("[FAIL]\n");
188                                 printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
189                                         invalid_freq[i]);
190                                 pass = -1;
191                                 goto out;
192                         }
193                 }
194         }
195
196         printf("[OK]\n");
197 out:
198         /* reset freq to zero */
199         tx.modes = ADJ_FREQUENCY;
200         tx.freq = 0;
201         ret = adjtimex(&tx);
202
203         return pass;
204 }
205
206
207 int set_offset(long long offset, int use_nano)
208 {
209         struct timex tmx = {};
210         int ret;
211
212         tmx.modes = ADJ_SETOFFSET;
213         if (use_nano) {
214                 tmx.modes |= ADJ_NANO;
215
216                 tmx.time.tv_sec = offset / NSEC_PER_SEC;
217                 tmx.time.tv_usec = offset % NSEC_PER_SEC;
218
219                 if (offset < 0 && tmx.time.tv_usec) {
220                         tmx.time.tv_sec -= 1;
221                         tmx.time.tv_usec += NSEC_PER_SEC;
222                 }
223         } else {
224                 tmx.time.tv_sec = offset / USEC_PER_SEC;
225                 tmx.time.tv_usec = offset % USEC_PER_SEC;
226
227                 if (offset < 0 && tmx.time.tv_usec) {
228                         tmx.time.tv_sec -= 1;
229                         tmx.time.tv_usec += USEC_PER_SEC;
230                 }
231         }
232
233         ret = clock_adjtime(CLOCK_REALTIME, &tmx);
234         if (ret < 0) {
235                 printf("(sec: %ld  usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
236                 printf("[FAIL]\n");
237                 return -1;
238         }
239         return 0;
240 }
241
242 int set_bad_offset(long sec, long usec, int use_nano)
243 {
244         struct timex tmx = {};
245         int ret;
246
247         tmx.modes = ADJ_SETOFFSET;
248         if (use_nano)
249                 tmx.modes |= ADJ_NANO;
250
251         tmx.time.tv_sec = sec;
252         tmx.time.tv_usec = usec;
253         ret = clock_adjtime(CLOCK_REALTIME, &tmx);
254         if (ret >= 0) {
255                 printf("Invalid (sec: %ld  usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
256                 printf("[FAIL]\n");
257                 return -1;
258         }
259         return 0;
260 }
261
262 int validate_set_offset(void)
263 {
264         printf("Testing ADJ_SETOFFSET... ");
265         fflush(stdout);
266
267         /* Test valid values */
268         if (set_offset(NSEC_PER_SEC - 1, 1))
269                 return -1;
270
271         if (set_offset(-NSEC_PER_SEC + 1, 1))
272                 return -1;
273
274         if (set_offset(-NSEC_PER_SEC - 1, 1))
275                 return -1;
276
277         if (set_offset(5 * NSEC_PER_SEC, 1))
278                 return -1;
279
280         if (set_offset(-5 * NSEC_PER_SEC, 1))
281                 return -1;
282
283         if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
284                 return -1;
285
286         if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
287                 return -1;
288
289         if (set_offset(USEC_PER_SEC - 1, 0))
290                 return -1;
291
292         if (set_offset(-USEC_PER_SEC + 1, 0))
293                 return -1;
294
295         if (set_offset(-USEC_PER_SEC - 1, 0))
296                 return -1;
297
298         if (set_offset(5 * USEC_PER_SEC, 0))
299                 return -1;
300
301         if (set_offset(-5 * USEC_PER_SEC, 0))
302                 return -1;
303
304         if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
305                 return -1;
306
307         if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
308                 return -1;
309
310         /* Test invalid values */
311         if (set_bad_offset(0, -1, 1))
312                 return -1;
313         if (set_bad_offset(0, -1, 0))
314                 return -1;
315         if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
316                 return -1;
317         if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
318                 return -1;
319         if (set_bad_offset(0, NSEC_PER_SEC, 1))
320                 return -1;
321         if (set_bad_offset(0, USEC_PER_SEC, 0))
322                 return -1;
323         if (set_bad_offset(0, -NSEC_PER_SEC, 1))
324                 return -1;
325         if (set_bad_offset(0, -USEC_PER_SEC, 0))
326                 return -1;
327
328         printf("[OK]\n");
329         return 0;
330 }
331
332 int main(int argc, char **argv)
333 {
334         if (validate_freq())
335                 return ksft_exit_fail();
336
337         if (validate_set_offset())
338                 return ksft_exit_fail();
339
340         return ksft_exit_pass();
341 }