2 * by: John Stultz <john.stultz@linaro.org>
3 * (C) Copyright Linaro 2015
4 * Licensed under the GPLv2
6 * This test validates adjtimex interface with valid
7 * and invalid test data.
9 * Usage: valid-adjtimex
12 * $ gcc valid-adjtimex.c -o valid-adjtimex -lrt
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.
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.
31 #include <sys/timex.h>
36 #include "../kselftest.h"
38 static inline int ksft_exit_pass(void)
42 static inline int ksft_exit_fail(void)
48 #define NSEC_PER_SEC 1000000000LL
49 #define USEC_PER_SEC 1000000LL
51 #define ADJ_SETOFFSET 0x0100
53 #include <sys/syscall.h>
54 static int clock_adjtime(clockid_t id, struct timex *tx)
56 return syscall(__NR_clock_adjtime, id, tx);
60 /* clear NTP time_status & time_state */
61 int clear_time_state(void)
66 tx.modes = ADJ_STATUS;
72 #define NUM_FREQ_VALID 32
73 #define NUM_FREQ_OUTOFRANGE 4
74 #define NUM_FREQ_INVALID 2
76 long valid_freq[NUM_FREQ_VALID] = {
110 long outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
117 #define LONG_MAX (~0UL>>1)
118 #define LONG_MIN (-LONG_MAX - 1)
120 long invalid_freq[NUM_FREQ_INVALID] = {
125 int validate_freq(void)
133 memset(&tx, 0, sizeof(struct timex));
134 /* Set the leap second insert flag */
136 printf("Testing ADJ_FREQ... ");
138 for (i = 0; i < NUM_FREQ_VALID; i++) {
139 tx.modes = ADJ_FREQUENCY;
140 tx.freq = valid_freq[i];
145 printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
146 valid_freq[i], valid_freq[i]>>16);
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]);
157 for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) {
158 tx.modes = ADJ_FREQUENCY;
159 tx.freq = outofrange_freq[i];
164 printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
165 outofrange_freq[i], outofrange_freq[i]>>16);
171 if (tx.freq == outofrange_freq[i]) {
173 printf("ERROR: out of range value %ld actually set!\n",
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];
188 printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
198 /* reset freq to zero */
199 tx.modes = ADJ_FREQUENCY;
207 int set_offset(long long offset, int use_nano)
209 struct timex tmx = {};
212 tmx.modes = ADJ_SETOFFSET;
214 tmx.modes |= ADJ_NANO;
216 tmx.time.tv_sec = offset / NSEC_PER_SEC;
217 tmx.time.tv_usec = offset % NSEC_PER_SEC;
219 if (offset < 0 && tmx.time.tv_usec) {
220 tmx.time.tv_sec -= 1;
221 tmx.time.tv_usec += NSEC_PER_SEC;
224 tmx.time.tv_sec = offset / USEC_PER_SEC;
225 tmx.time.tv_usec = offset % USEC_PER_SEC;
227 if (offset < 0 && tmx.time.tv_usec) {
228 tmx.time.tv_sec -= 1;
229 tmx.time.tv_usec += USEC_PER_SEC;
233 ret = clock_adjtime(CLOCK_REALTIME, &tmx);
235 printf("(sec: %ld usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
242 int set_bad_offset(long sec, long usec, int use_nano)
244 struct timex tmx = {};
247 tmx.modes = ADJ_SETOFFSET;
249 tmx.modes |= ADJ_NANO;
251 tmx.time.tv_sec = sec;
252 tmx.time.tv_usec = usec;
253 ret = clock_adjtime(CLOCK_REALTIME, &tmx);
255 printf("Invalid (sec: %ld usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
262 int validate_set_offset(void)
264 printf("Testing ADJ_SETOFFSET... ");
267 /* Test valid values */
268 if (set_offset(NSEC_PER_SEC - 1, 1))
271 if (set_offset(-NSEC_PER_SEC + 1, 1))
274 if (set_offset(-NSEC_PER_SEC - 1, 1))
277 if (set_offset(5 * NSEC_PER_SEC, 1))
280 if (set_offset(-5 * NSEC_PER_SEC, 1))
283 if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
286 if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
289 if (set_offset(USEC_PER_SEC - 1, 0))
292 if (set_offset(-USEC_PER_SEC + 1, 0))
295 if (set_offset(-USEC_PER_SEC - 1, 0))
298 if (set_offset(5 * USEC_PER_SEC, 0))
301 if (set_offset(-5 * USEC_PER_SEC, 0))
304 if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
307 if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
310 /* Test invalid values */
311 if (set_bad_offset(0, -1, 1))
313 if (set_bad_offset(0, -1, 0))
315 if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
317 if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
319 if (set_bad_offset(0, NSEC_PER_SEC, 1))
321 if (set_bad_offset(0, USEC_PER_SEC, 0))
323 if (set_bad_offset(0, -NSEC_PER_SEC, 1))
325 if (set_bad_offset(0, -USEC_PER_SEC, 0))
332 int main(int argc, char **argv)
335 return ksft_exit_fail();
337 if (validate_set_offset())
338 return ksft_exit_fail();
340 return ksft_exit_pass();