root/tools/testing/selftests/timers/valid-adjtimex.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clock_adjtime
  2. clear_time_state
  3. validate_freq
  4. set_offset
  5. set_bad_offset
  6. validate_set_offset
  7. main

   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 #include "../kselftest.h"
  36 
  37 #define NSEC_PER_SEC 1000000000LL
  38 #define USEC_PER_SEC 1000000LL
  39 
  40 #define ADJ_SETOFFSET 0x0100
  41 
  42 #include <sys/syscall.h>
  43 static int clock_adjtime(clockid_t id, struct timex *tx)
  44 {
  45         return syscall(__NR_clock_adjtime, id, tx);
  46 }
  47 
  48 
  49 /* clear NTP time_status & time_state */
  50 int clear_time_state(void)
  51 {
  52         struct timex tx;
  53         int ret;
  54 
  55         tx.modes = ADJ_STATUS;
  56         tx.status = 0;
  57         ret = adjtimex(&tx);
  58         return ret;
  59 }
  60 
  61 #define NUM_FREQ_VALID 32
  62 #define NUM_FREQ_OUTOFRANGE 4
  63 #define NUM_FREQ_INVALID 2
  64 
  65 long valid_freq[NUM_FREQ_VALID] = {
  66         -499<<16,
  67         -450<<16,
  68         -400<<16,
  69         -350<<16,
  70         -300<<16,
  71         -250<<16,
  72         -200<<16,
  73         -150<<16,
  74         -100<<16,
  75         -75<<16,
  76         -50<<16,
  77         -25<<16,
  78         -10<<16,
  79         -5<<16,
  80         -1<<16,
  81         -1000,
  82         1<<16,
  83         5<<16,
  84         10<<16,
  85         25<<16,
  86         50<<16,
  87         75<<16,
  88         100<<16,
  89         150<<16,
  90         200<<16,
  91         250<<16,
  92         300<<16,
  93         350<<16,
  94         400<<16,
  95         450<<16,
  96         499<<16,
  97 };
  98 
  99 long outofrange_freq[NUM_FREQ_OUTOFRANGE] = {
 100         -1000<<16,
 101         -550<<16,
 102         550<<16,
 103         1000<<16,
 104 };
 105 
 106 #define LONG_MAX (~0UL>>1)
 107 #define LONG_MIN (-LONG_MAX - 1)
 108 
 109 long invalid_freq[NUM_FREQ_INVALID] = {
 110         LONG_MAX,
 111         LONG_MIN,
 112 };
 113 
 114 int validate_freq(void)
 115 {
 116         struct timex tx;
 117         int ret, pass = 0;
 118         int i;
 119 
 120         clear_time_state();
 121 
 122         memset(&tx, 0, sizeof(struct timex));
 123         /* Set the leap second insert flag */
 124 
 125         printf("Testing ADJ_FREQ... ");
 126         fflush(stdout);
 127         for (i = 0; i < NUM_FREQ_VALID; i++) {
 128                 tx.modes = ADJ_FREQUENCY;
 129                 tx.freq = valid_freq[i];
 130 
 131                 ret = adjtimex(&tx);
 132                 if (ret < 0) {
 133                         printf("[FAIL]\n");
 134                         printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
 135                                 valid_freq[i], valid_freq[i]>>16);
 136                         pass = -1;
 137                         goto out;
 138                 }
 139                 tx.modes = 0;
 140                 ret = adjtimex(&tx);
 141                 if (tx.freq != valid_freq[i]) {
 142                         printf("Warning: freq value %ld not what we set it (%ld)!\n",
 143                                         tx.freq, valid_freq[i]);
 144                 }
 145         }
 146         for (i = 0; i < NUM_FREQ_OUTOFRANGE; i++) {
 147                 tx.modes = ADJ_FREQUENCY;
 148                 tx.freq = outofrange_freq[i];
 149 
 150                 ret = adjtimex(&tx);
 151                 if (ret < 0) {
 152                         printf("[FAIL]\n");
 153                         printf("Error: adjtimex(ADJ_FREQ, %ld - %ld ppm\n",
 154                                 outofrange_freq[i], outofrange_freq[i]>>16);
 155                         pass = -1;
 156                         goto out;
 157                 }
 158                 tx.modes = 0;
 159                 ret = adjtimex(&tx);
 160                 if (tx.freq == outofrange_freq[i]) {
 161                         printf("[FAIL]\n");
 162                         printf("ERROR: out of range value %ld actually set!\n",
 163                                         tx.freq);
 164                         pass = -1;
 165                         goto out;
 166                 }
 167         }
 168 
 169 
 170         if (sizeof(long) == 8) { /* this case only applies to 64bit systems */
 171                 for (i = 0; i < NUM_FREQ_INVALID; i++) {
 172                         tx.modes = ADJ_FREQUENCY;
 173                         tx.freq = invalid_freq[i];
 174                         ret = adjtimex(&tx);
 175                         if (ret >= 0) {
 176                                 printf("[FAIL]\n");
 177                                 printf("Error: No failure on invalid ADJ_FREQUENCY %ld\n",
 178                                         invalid_freq[i]);
 179                                 pass = -1;
 180                                 goto out;
 181                         }
 182                 }
 183         }
 184 
 185         printf("[OK]\n");
 186 out:
 187         /* reset freq to zero */
 188         tx.modes = ADJ_FREQUENCY;
 189         tx.freq = 0;
 190         ret = adjtimex(&tx);
 191 
 192         return pass;
 193 }
 194 
 195 
 196 int set_offset(long long offset, int use_nano)
 197 {
 198         struct timex tmx = {};
 199         int ret;
 200 
 201         tmx.modes = ADJ_SETOFFSET;
 202         if (use_nano) {
 203                 tmx.modes |= ADJ_NANO;
 204 
 205                 tmx.time.tv_sec = offset / NSEC_PER_SEC;
 206                 tmx.time.tv_usec = offset % NSEC_PER_SEC;
 207 
 208                 if (offset < 0 && tmx.time.tv_usec) {
 209                         tmx.time.tv_sec -= 1;
 210                         tmx.time.tv_usec += NSEC_PER_SEC;
 211                 }
 212         } else {
 213                 tmx.time.tv_sec = offset / USEC_PER_SEC;
 214                 tmx.time.tv_usec = offset % USEC_PER_SEC;
 215 
 216                 if (offset < 0 && tmx.time.tv_usec) {
 217                         tmx.time.tv_sec -= 1;
 218                         tmx.time.tv_usec += USEC_PER_SEC;
 219                 }
 220         }
 221 
 222         ret = clock_adjtime(CLOCK_REALTIME, &tmx);
 223         if (ret < 0) {
 224                 printf("(sec: %ld  usec: %ld) ", tmx.time.tv_sec, tmx.time.tv_usec);
 225                 printf("[FAIL]\n");
 226                 return -1;
 227         }
 228         return 0;
 229 }
 230 
 231 int set_bad_offset(long sec, long usec, int use_nano)
 232 {
 233         struct timex tmx = {};
 234         int ret;
 235 
 236         tmx.modes = ADJ_SETOFFSET;
 237         if (use_nano)
 238                 tmx.modes |= ADJ_NANO;
 239 
 240         tmx.time.tv_sec = sec;
 241         tmx.time.tv_usec = usec;
 242         ret = clock_adjtime(CLOCK_REALTIME, &tmx);
 243         if (ret >= 0) {
 244                 printf("Invalid (sec: %ld  usec: %ld) did not fail! ", tmx.time.tv_sec, tmx.time.tv_usec);
 245                 printf("[FAIL]\n");
 246                 return -1;
 247         }
 248         return 0;
 249 }
 250 
 251 int validate_set_offset(void)
 252 {
 253         printf("Testing ADJ_SETOFFSET... ");
 254         fflush(stdout);
 255 
 256         /* Test valid values */
 257         if (set_offset(NSEC_PER_SEC - 1, 1))
 258                 return -1;
 259 
 260         if (set_offset(-NSEC_PER_SEC + 1, 1))
 261                 return -1;
 262 
 263         if (set_offset(-NSEC_PER_SEC - 1, 1))
 264                 return -1;
 265 
 266         if (set_offset(5 * NSEC_PER_SEC, 1))
 267                 return -1;
 268 
 269         if (set_offset(-5 * NSEC_PER_SEC, 1))
 270                 return -1;
 271 
 272         if (set_offset(5 * NSEC_PER_SEC + NSEC_PER_SEC / 2, 1))
 273                 return -1;
 274 
 275         if (set_offset(-5 * NSEC_PER_SEC - NSEC_PER_SEC / 2, 1))
 276                 return -1;
 277 
 278         if (set_offset(USEC_PER_SEC - 1, 0))
 279                 return -1;
 280 
 281         if (set_offset(-USEC_PER_SEC + 1, 0))
 282                 return -1;
 283 
 284         if (set_offset(-USEC_PER_SEC - 1, 0))
 285                 return -1;
 286 
 287         if (set_offset(5 * USEC_PER_SEC, 0))
 288                 return -1;
 289 
 290         if (set_offset(-5 * USEC_PER_SEC, 0))
 291                 return -1;
 292 
 293         if (set_offset(5 * USEC_PER_SEC + USEC_PER_SEC / 2, 0))
 294                 return -1;
 295 
 296         if (set_offset(-5 * USEC_PER_SEC - USEC_PER_SEC / 2, 0))
 297                 return -1;
 298 
 299         /* Test invalid values */
 300         if (set_bad_offset(0, -1, 1))
 301                 return -1;
 302         if (set_bad_offset(0, -1, 0))
 303                 return -1;
 304         if (set_bad_offset(0, 2 * NSEC_PER_SEC, 1))
 305                 return -1;
 306         if (set_bad_offset(0, 2 * USEC_PER_SEC, 0))
 307                 return -1;
 308         if (set_bad_offset(0, NSEC_PER_SEC, 1))
 309                 return -1;
 310         if (set_bad_offset(0, USEC_PER_SEC, 0))
 311                 return -1;
 312         if (set_bad_offset(0, -NSEC_PER_SEC, 1))
 313                 return -1;
 314         if (set_bad_offset(0, -USEC_PER_SEC, 0))
 315                 return -1;
 316 
 317         printf("[OK]\n");
 318         return 0;
 319 }
 320 
 321 int main(int argc, char **argv)
 322 {
 323         if (validate_freq())
 324                 return ksft_exit_fail();
 325 
 326         if (validate_set_offset())
 327                 return ksft_exit_fail();
 328 
 329         return ksft_exit_pass();
 330 }

/* [<][>][^][v][top][bottom][index][help] */