diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2018-04-10 19:43:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-11 13:28:34 -0400 |
commit | 1f5bd0547654ada423b184e22f320d76c0fac49e (patch) | |
tree | 0d305b2d1f713af5bf4b9b534cb253183a58e716 | |
parent | 4f1134370a29a5f2d0f4b4be4c5e2fddd38f0f9d (diff) |
proc: selftests: test /proc/uptime
The only tests I could come up with for /proc/uptime are:
- test that values increase monotonically for 1 second,
- bounce around CPUs and test the same thing.
Avoid glibc like plague for affinity given patches like this:
https://marc.info/?l=linux-kernel&m=152130031912594&w=4
Link: http://lkml.kernel.org/r/20180317165235.GB3445@avx2
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | tools/testing/selftests/proc/.gitignore | 2 | ||||
-rw-r--r-- | tools/testing/selftests/proc/Makefile | 2 | ||||
-rw-r--r-- | tools/testing/selftests/proc/proc-uptime-001.c | 45 | ||||
-rw-r--r-- | tools/testing/selftests/proc/proc-uptime-002.c | 79 | ||||
-rw-r--r-- | tools/testing/selftests/proc/proc-uptime.h | 74 |
5 files changed, 202 insertions, 0 deletions
diff --git a/tools/testing/selftests/proc/.gitignore b/tools/testing/selftests/proc/.gitignore index 5627df81ade9..6c16f77c722c 100644 --- a/tools/testing/selftests/proc/.gitignore +++ b/tools/testing/selftests/proc/.gitignore | |||
@@ -3,4 +3,6 @@ | |||
3 | /proc-self-map-files-002 | 3 | /proc-self-map-files-002 |
4 | /proc-self-syscall | 4 | /proc-self-syscall |
5 | /proc-self-wchan | 5 | /proc-self-wchan |
6 | /proc-uptime-001 | ||
7 | /proc-uptime-002 | ||
6 | /read | 8 | /read |
diff --git a/tools/testing/selftests/proc/Makefile b/tools/testing/selftests/proc/Makefile index 312a3989820c..dbb87e56264c 100644 --- a/tools/testing/selftests/proc/Makefile +++ b/tools/testing/selftests/proc/Makefile | |||
@@ -6,6 +6,8 @@ TEST_GEN_PROGS += proc-self-map-files-001 | |||
6 | TEST_GEN_PROGS += proc-self-map-files-002 | 6 | TEST_GEN_PROGS += proc-self-map-files-002 |
7 | TEST_GEN_PROGS += proc-self-syscall | 7 | TEST_GEN_PROGS += proc-self-syscall |
8 | TEST_GEN_PROGS += proc-self-wchan | 8 | TEST_GEN_PROGS += proc-self-wchan |
9 | TEST_GEN_PROGS += proc-uptime-001 | ||
10 | TEST_GEN_PROGS += proc-uptime-002 | ||
9 | TEST_GEN_PROGS += read | 11 | TEST_GEN_PROGS += read |
10 | 12 | ||
11 | include ../lib.mk | 13 | include ../lib.mk |
diff --git a/tools/testing/selftests/proc/proc-uptime-001.c b/tools/testing/selftests/proc/proc-uptime-001.c new file mode 100644 index 000000000000..303f26092306 --- /dev/null +++ b/tools/testing/selftests/proc/proc-uptime-001.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright _ 2018 Alexey Dobriyan <adobriyan@gmail.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | // Test that values in /proc/uptime increment monotonically. | ||
17 | #undef NDEBUG | ||
18 | #include <assert.h> | ||
19 | #include <stdint.h> | ||
20 | #include <sys/types.h> | ||
21 | #include <sys/stat.h> | ||
22 | #include <fcntl.h> | ||
23 | |||
24 | #include "proc-uptime.h" | ||
25 | |||
26 | int main(void) | ||
27 | { | ||
28 | uint64_t start, u0, u1, i0, i1; | ||
29 | int fd; | ||
30 | |||
31 | fd = open("/proc/uptime", O_RDONLY); | ||
32 | assert(fd >= 0); | ||
33 | |||
34 | proc_uptime(fd, &u0, &i0); | ||
35 | start = u0; | ||
36 | do { | ||
37 | proc_uptime(fd, &u1, &i1); | ||
38 | assert(u1 >= u0); | ||
39 | assert(i1 >= i0); | ||
40 | u0 = u1; | ||
41 | i0 = i1; | ||
42 | } while (u1 - start < 100); | ||
43 | |||
44 | return 0; | ||
45 | } | ||
diff --git a/tools/testing/selftests/proc/proc-uptime-002.c b/tools/testing/selftests/proc/proc-uptime-002.c new file mode 100644 index 000000000000..0cb79e1f1674 --- /dev/null +++ b/tools/testing/selftests/proc/proc-uptime-002.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Copyright _ 2018 Alexey Dobriyan <adobriyan@gmail.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | // Test that values in /proc/uptime increment monotonically | ||
17 | // while shifting across CPUs. | ||
18 | #define _GNU_SOURCE | ||
19 | #undef NDEBUG | ||
20 | #include <assert.h> | ||
21 | #include <unistd.h> | ||
22 | #include <sys/syscall.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include <stdint.h> | ||
27 | #include <sys/types.h> | ||
28 | #include <sys/stat.h> | ||
29 | #include <fcntl.h> | ||
30 | |||
31 | #include "proc-uptime.h" | ||
32 | |||
33 | static inline int sys_sched_getaffinity(pid_t pid, unsigned int len, unsigned long *m) | ||
34 | { | ||
35 | return syscall(SYS_sched_getaffinity, pid, len, m); | ||
36 | } | ||
37 | |||
38 | static inline int sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long *m) | ||
39 | { | ||
40 | return syscall(SYS_sched_setaffinity, pid, len, m); | ||
41 | } | ||
42 | |||
43 | int main(void) | ||
44 | { | ||
45 | unsigned int len; | ||
46 | unsigned long *m; | ||
47 | unsigned int cpu; | ||
48 | uint64_t u0, u1, i0, i1; | ||
49 | int fd; | ||
50 | |||
51 | /* find out "nr_cpu_ids" */ | ||
52 | m = NULL; | ||
53 | len = 0; | ||
54 | do { | ||
55 | len += sizeof(unsigned long); | ||
56 | free(m); | ||
57 | m = malloc(len); | ||
58 | } while (sys_sched_getaffinity(0, len, m) == -EINVAL); | ||
59 | |||
60 | fd = open("/proc/uptime", O_RDONLY); | ||
61 | assert(fd >= 0); | ||
62 | |||
63 | proc_uptime(fd, &u0, &i0); | ||
64 | for (cpu = 0; cpu < len * 8; cpu++) { | ||
65 | memset(m, 0, len); | ||
66 | m[cpu / (8 * sizeof(unsigned long))] |= 1UL << (cpu % (8 * sizeof(unsigned long))); | ||
67 | |||
68 | /* CPU might not exist, ignore error */ | ||
69 | sys_sched_setaffinity(0, len, m); | ||
70 | |||
71 | proc_uptime(fd, &u1, &i1); | ||
72 | assert(u1 >= u0); | ||
73 | assert(i1 >= i0); | ||
74 | u0 = u1; | ||
75 | i0 = i1; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
diff --git a/tools/testing/selftests/proc/proc-uptime.h b/tools/testing/selftests/proc/proc-uptime.h new file mode 100644 index 000000000000..d584419f50a7 --- /dev/null +++ b/tools/testing/selftests/proc/proc-uptime.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Copyright _ 2018 Alexey Dobriyan <adobriyan@gmail.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #undef NDEBUG | ||
17 | #include <assert.h> | ||
18 | #include <errno.h> | ||
19 | #include <string.h> | ||
20 | #include <stdlib.h> | ||
21 | #include <unistd.h> | ||
22 | |||
23 | static unsigned long long xstrtoull(const char *p, char **end) | ||
24 | { | ||
25 | if (*p == '0') { | ||
26 | *end = (char *)p + 1; | ||
27 | return 0; | ||
28 | } else if ('1' <= *p && *p <= '9') { | ||
29 | unsigned long long val; | ||
30 | |||
31 | errno = 0; | ||
32 | val = strtoull(p, end, 10); | ||
33 | assert(errno == 0); | ||
34 | return val; | ||
35 | } else | ||
36 | assert(0); | ||
37 | } | ||
38 | |||
39 | static void proc_uptime(int fd, uint64_t *uptime, uint64_t *idle) | ||
40 | { | ||
41 | uint64_t val1, val2; | ||
42 | char buf[64], *p; | ||
43 | ssize_t rv; | ||
44 | |||
45 | /* save "p < end" checks */ | ||
46 | memset(buf, 0, sizeof(buf)); | ||
47 | rv = pread(fd, buf, sizeof(buf), 0); | ||
48 | assert(0 <= rv && rv <= sizeof(buf)); | ||
49 | buf[sizeof(buf) - 1] = '\0'; | ||
50 | |||
51 | p = buf; | ||
52 | |||
53 | val1 = xstrtoull(p, &p); | ||
54 | assert(p[0] == '.'); | ||
55 | assert('0' <= p[1] && p[1] <= '9'); | ||
56 | assert('0' <= p[2] && p[2] <= '9'); | ||
57 | assert(p[3] == ' '); | ||
58 | |||
59 | val2 = (p[1] - '0') * 10 + p[2] - '0'; | ||
60 | *uptime = val1 * 100 + val2; | ||
61 | |||
62 | p += 4; | ||
63 | |||
64 | val1 = xstrtoull(p, &p); | ||
65 | assert(p[0] == '.'); | ||
66 | assert('0' <= p[1] && p[1] <= '9'); | ||
67 | assert('0' <= p[2] && p[2] <= '9'); | ||
68 | assert(p[3] == '\n'); | ||
69 | |||
70 | val2 = (p[1] - '0') * 10 + p[2] - '0'; | ||
71 | *idle = val1 * 100 + val2; | ||
72 | |||
73 | assert(p + 4 == buf + rv); | ||
74 | } | ||