1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2019 Linaro Limited. All rights reserved.
4 * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
5 */
6
7 /*
8 * Basic test for clock_settime(2) on REALTIME clock:
9 *
10 * 1) advance DELTA_SEC seconds
11 * 2) go backwards DELTA_SEC seconds
12 *
13 * Restore wall clock at the end of test.
14 */
15
16 #include "config.h"
17 #include "tst_timer.h"
18 #include "tst_safe_clocks.h"
19 #include "tst_test.h"
20 #include "lapi/syscalls.h"
21
22 #define DELTA_SEC 10
23 #define DELTA_US (long long) (DELTA_SEC * 1000000)
24 #define DELTA_EPS (long long) (DELTA_US * 0.1)
25
26 static struct timespec *begin, *change, *end;
27
verify_clock_settime(void)28 static void verify_clock_settime(void)
29 {
30 long long elapsed;
31
32 /* test 01: move forward */
33
34 SAFE_CLOCK_GETTIME(CLOCK_REALTIME, begin);
35
36 *change = tst_timespec_add_us(*begin, DELTA_US);
37
38 if (clock_settime(CLOCK_REALTIME, change) != 0)
39 tst_brk(TBROK | TTERRNO, "could not set realtime change");
40
41 SAFE_CLOCK_GETTIME(CLOCK_REALTIME, end);
42
43 elapsed = tst_timespec_diff_us(*end, *begin);
44
45 if (elapsed >= DELTA_US && elapsed < (DELTA_US + DELTA_EPS))
46 tst_res(TPASS, "clock_settime(2): was able to advance time");
47 else
48 tst_res(TFAIL, "clock_settime(2): could not advance time");
49
50 /* test 02: move backward */
51
52 SAFE_CLOCK_GETTIME(CLOCK_REALTIME, begin);
53
54 *change = tst_timespec_sub_us(*begin, DELTA_US);
55
56 if (clock_settime(CLOCK_REALTIME, change) != 0)
57 tst_brk(TBROK | TTERRNO, "could not set realtime change");
58
59 SAFE_CLOCK_GETTIME(CLOCK_REALTIME, end);
60
61 elapsed = tst_timespec_diff_us(*end, *begin);
62
63 if (~(elapsed) <= DELTA_US && ~(elapsed) > (DELTA_US - DELTA_EPS))
64 tst_res(TPASS, "clock_settime(2): was able to recede time");
65 else
66 tst_res(TFAIL, "clock_settime(2): could not recede time");
67 }
68
69 static struct tst_test test = {
70 .test_all = verify_clock_settime,
71 .needs_root = 1,
72 .restore_wallclock = 1,
73 .bufs = (struct tst_buffers []) {
74 {&begin, .size = sizeof(*begin)},
75 {&change, .size = sizeof(*change)},
76 {&end, .size = sizeof(*end)},
77 {},
78 }
79 };
80