diff options
author | Alexei Starovoitov <ast@kernel.org> | 2019-08-06 20:17:52 -0400 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2019-08-06 20:17:53 -0400 |
commit | 682cdbdc216028f5340e48e92e59e3e9503957bb (patch) | |
tree | 1822c880732872e2ffb4a9496a4bfaf221da58ce | |
parent | 8c30396074c131765b19eb3cb7ff764a4f2f2913 (diff) | |
parent | 16e910d4467ccdf1cae5035e71035e5f7197e77d (diff) |
Merge branch 'test_progs-stdio'
Stanislav Fomichev says:
====================
I was looking into converting test_sockops* to test_progs framework
and that requires using cgroup_helpers.c which rely on stdio/stderr.
Let's use open_memstream to override stdout into buffer during
subtests instead of custom test_{v,}printf wrappers. That lets
us continue to use stdio in the subtests and dump it on failure
if required.
That would also fix bpf_find_map which currently uses printf to
signal failure (missed during test_printf conversion).
====================
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
10 files changed, 84 insertions, 94 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c index 0caf8eafa9eb..1a1eae356f81 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c | |||
@@ -5,13 +5,13 @@ static int libbpf_debug_print(enum libbpf_print_level level, | |||
5 | const char *format, va_list args) | 5 | const char *format, va_list args) |
6 | { | 6 | { |
7 | if (level != LIBBPF_DEBUG) { | 7 | if (level != LIBBPF_DEBUG) { |
8 | test__vprintf(format, args); | 8 | vprintf(format, args); |
9 | return 0; | 9 | return 0; |
10 | } | 10 | } |
11 | 11 | ||
12 | if (!strstr(format, "verifier log")) | 12 | if (!strstr(format, "verifier log")) |
13 | return 0; | 13 | return 0; |
14 | test__vprintf("%s", args); | 14 | vprintf("%s", args); |
15 | return 0; | 15 | return 0; |
16 | } | 16 | } |
17 | 17 | ||
diff --git a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c index 5ce572c03a5f..20ddca830e68 100644 --- a/tools/testing/selftests/bpf/prog_tests/l4lb_all.c +++ b/tools/testing/selftests/bpf/prog_tests/l4lb_all.c | |||
@@ -74,7 +74,7 @@ static void test_l4lb(const char *file) | |||
74 | } | 74 | } |
75 | if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { | 75 | if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { |
76 | error_cnt++; | 76 | error_cnt++; |
77 | test__printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); | 77 | printf("test_l4lb:FAIL:stats %lld %lld\n", bytes, pkts); |
78 | } | 78 | } |
79 | out: | 79 | out: |
80 | bpf_object__close(obj); | 80 | bpf_object__close(obj); |
diff --git a/tools/testing/selftests/bpf/prog_tests/map_lock.c b/tools/testing/selftests/bpf/prog_tests/map_lock.c index 2e78217ed3fd..ee99368c595c 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/map_lock.c | |||
@@ -9,12 +9,12 @@ static void *parallel_map_access(void *arg) | |||
9 | for (i = 0; i < 10000; i++) { | 9 | for (i = 0; i < 10000; i++) { |
10 | err = bpf_map_lookup_elem_flags(map_fd, &key, vars, BPF_F_LOCK); | 10 | err = bpf_map_lookup_elem_flags(map_fd, &key, vars, BPF_F_LOCK); |
11 | if (err) { | 11 | if (err) { |
12 | test__printf("lookup failed\n"); | 12 | printf("lookup failed\n"); |
13 | error_cnt++; | 13 | error_cnt++; |
14 | goto out; | 14 | goto out; |
15 | } | 15 | } |
16 | if (vars[0] != 0) { | 16 | if (vars[0] != 0) { |
17 | test__printf("lookup #%d var[0]=%d\n", i, vars[0]); | 17 | printf("lookup #%d var[0]=%d\n", i, vars[0]); |
18 | error_cnt++; | 18 | error_cnt++; |
19 | goto out; | 19 | goto out; |
20 | } | 20 | } |
@@ -22,8 +22,8 @@ static void *parallel_map_access(void *arg) | |||
22 | for (j = 2; j < 17; j++) { | 22 | for (j = 2; j < 17; j++) { |
23 | if (vars[j] == rnd) | 23 | if (vars[j] == rnd) |
24 | continue; | 24 | continue; |
25 | test__printf("lookup #%d var[1]=%d var[%d]=%d\n", | 25 | printf("lookup #%d var[1]=%d var[%d]=%d\n", |
26 | i, rnd, j, vars[j]); | 26 | i, rnd, j, vars[j]); |
27 | error_cnt++; | 27 | error_cnt++; |
28 | goto out; | 28 | goto out; |
29 | } | 29 | } |
@@ -43,7 +43,7 @@ void test_map_lock(void) | |||
43 | 43 | ||
44 | err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); | 44 | err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); |
45 | if (err) { | 45 | if (err) { |
46 | test__printf("test_map_lock:bpf_prog_load errno %d\n", errno); | 46 | printf("test_map_lock:bpf_prog_load errno %d\n", errno); |
47 | goto close_prog; | 47 | goto close_prog; |
48 | } | 48 | } |
49 | map_fd[0] = bpf_find_map(__func__, obj, "hash_map"); | 49 | map_fd[0] = bpf_find_map(__func__, obj, "hash_map"); |
diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 461b423d0584..1575f0a1f586 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c | |||
@@ -202,8 +202,8 @@ static int test_send_signal_nmi(void) | |||
202 | -1 /* cpu */, -1 /* group_fd */, 0 /* flags */); | 202 | -1 /* cpu */, -1 /* group_fd */, 0 /* flags */); |
203 | if (pmu_fd == -1) { | 203 | if (pmu_fd == -1) { |
204 | if (errno == ENOENT) { | 204 | if (errno == ENOENT) { |
205 | test__printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", | 205 | printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", |
206 | __func__); | 206 | __func__); |
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | /* Let the test fail with a more informative message */ | 209 | /* Let the test fail with a more informative message */ |
diff --git a/tools/testing/selftests/bpf/prog_tests/spinlock.c b/tools/testing/selftests/bpf/prog_tests/spinlock.c index deb2db5b85b0..114ebe6a438e 100644 --- a/tools/testing/selftests/bpf/prog_tests/spinlock.c +++ b/tools/testing/selftests/bpf/prog_tests/spinlock.c | |||
@@ -12,7 +12,7 @@ void test_spinlock(void) | |||
12 | 12 | ||
13 | err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); | 13 | err = bpf_prog_load(file, BPF_PROG_TYPE_CGROUP_SKB, &obj, &prog_fd); |
14 | if (err) { | 14 | if (err) { |
15 | test__printf("test_spin_lock:bpf_prog_load errno %d\n", errno); | 15 | printf("test_spin_lock:bpf_prog_load errno %d\n", errno); |
16 | goto close_prog; | 16 | goto close_prog; |
17 | } | 17 | } |
18 | for (i = 0; i < 4; i++) | 18 | for (i = 0; i < 4; i++) |
diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c index 356d2c017a9c..ac44fda84833 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id.c | |||
@@ -109,8 +109,8 @@ retry: | |||
109 | if (build_id_matches < 1 && retry--) { | 109 | if (build_id_matches < 1 && retry--) { |
110 | bpf_link__destroy(link); | 110 | bpf_link__destroy(link); |
111 | bpf_object__close(obj); | 111 | bpf_object__close(obj); |
112 | test__printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", | 112 | printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", |
113 | __func__); | 113 | __func__); |
114 | goto retry; | 114 | goto retry; |
115 | } | 115 | } |
116 | 116 | ||
diff --git a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c index f44f2c159714..9557b7dfb782 100644 --- a/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c +++ b/tools/testing/selftests/bpf/prog_tests/stacktrace_build_id_nmi.c | |||
@@ -140,8 +140,8 @@ retry: | |||
140 | if (build_id_matches < 1 && retry--) { | 140 | if (build_id_matches < 1 && retry--) { |
141 | bpf_link__destroy(link); | 141 | bpf_link__destroy(link); |
142 | bpf_object__close(obj); | 142 | bpf_object__close(obj); |
143 | test__printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", | 143 | printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", |
144 | __func__); | 144 | __func__); |
145 | goto retry; | 145 | goto retry; |
146 | } | 146 | } |
147 | 147 | ||
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c index b5404494b8aa..15f7c272edb0 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_noinline.c | |||
@@ -75,8 +75,8 @@ void test_xdp_noinline(void) | |||
75 | } | 75 | } |
76 | if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { | 76 | if (bytes != MAGIC_BYTES * NUM_ITER * 2 || pkts != NUM_ITER * 2) { |
77 | error_cnt++; | 77 | error_cnt++; |
78 | test__printf("test_xdp_noinline:FAIL:stats %lld %lld\n", | 78 | printf("test_xdp_noinline:FAIL:stats %lld %lld\n", |
79 | bytes, pkts); | 79 | bytes, pkts); |
80 | } | 80 | } |
81 | out: | 81 | out: |
82 | bpf_object__close(obj); | 82 | bpf_object__close(obj); |
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index db00196c8315..12895d03d58b 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c | |||
@@ -40,14 +40,20 @@ static bool should_run(struct test_selector *sel, int num, const char *name) | |||
40 | 40 | ||
41 | static void dump_test_log(const struct prog_test_def *test, bool failed) | 41 | static void dump_test_log(const struct prog_test_def *test, bool failed) |
42 | { | 42 | { |
43 | if (stdout == env.stdout) | ||
44 | return; | ||
45 | |||
46 | fflush(stdout); /* exports env.log_buf & env.log_cnt */ | ||
47 | |||
43 | if (env.verbose || test->force_log || failed) { | 48 | if (env.verbose || test->force_log || failed) { |
44 | if (env.log_cnt) { | 49 | if (env.log_cnt) { |
45 | fprintf(stdout, "%s", env.log_buf); | 50 | fprintf(env.stdout, "%s", env.log_buf); |
46 | if (env.log_buf[env.log_cnt - 1] != '\n') | 51 | if (env.log_buf[env.log_cnt - 1] != '\n') |
47 | fprintf(stdout, "\n"); | 52 | fprintf(env.stdout, "\n"); |
48 | } | 53 | } |
49 | } | 54 | } |
50 | env.log_cnt = 0; | 55 | |
56 | fseeko(stdout, 0, SEEK_SET); /* rewind */ | ||
51 | } | 57 | } |
52 | 58 | ||
53 | void test__end_subtest() | 59 | void test__end_subtest() |
@@ -62,7 +68,7 @@ void test__end_subtest() | |||
62 | 68 | ||
63 | dump_test_log(test, sub_error_cnt); | 69 | dump_test_log(test, sub_error_cnt); |
64 | 70 | ||
65 | printf("#%d/%d %s:%s\n", | 71 | fprintf(env.stdout, "#%d/%d %s:%s\n", |
66 | test->test_num, test->subtest_num, | 72 | test->test_num, test->subtest_num, |
67 | test->subtest_name, sub_error_cnt ? "FAIL" : "OK"); | 73 | test->subtest_name, sub_error_cnt ? "FAIL" : "OK"); |
68 | } | 74 | } |
@@ -79,7 +85,8 @@ bool test__start_subtest(const char *name) | |||
79 | test->subtest_num++; | 85 | test->subtest_num++; |
80 | 86 | ||
81 | if (!name || !name[0]) { | 87 | if (!name || !name[0]) { |
82 | fprintf(stderr, "Subtest #%d didn't provide sub-test name!\n", | 88 | fprintf(env.stderr, |
89 | "Subtest #%d didn't provide sub-test name!\n", | ||
83 | test->subtest_num); | 90 | test->subtest_num); |
84 | return false; | 91 | return false; |
85 | } | 92 | } |
@@ -98,66 +105,6 @@ void test__force_log() { | |||
98 | env.test->force_log = true; | 105 | env.test->force_log = true; |
99 | } | 106 | } |
100 | 107 | ||
101 | void test__vprintf(const char *fmt, va_list args) | ||
102 | { | ||
103 | size_t rem_sz; | ||
104 | int ret = 0; | ||
105 | |||
106 | if (env.verbose || (env.test && env.test->force_log)) { | ||
107 | vfprintf(stderr, fmt, args); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | try_again: | ||
112 | rem_sz = env.log_cap - env.log_cnt; | ||
113 | if (rem_sz) { | ||
114 | va_list ap; | ||
115 | |||
116 | va_copy(ap, args); | ||
117 | /* we reserved extra byte for \0 at the end */ | ||
118 | ret = vsnprintf(env.log_buf + env.log_cnt, rem_sz + 1, fmt, ap); | ||
119 | va_end(ap); | ||
120 | |||
121 | if (ret < 0) { | ||
122 | env.log_buf[env.log_cnt] = '\0'; | ||
123 | fprintf(stderr, "failed to log w/ fmt '%s'\n", fmt); | ||
124 | return; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | if (!rem_sz || ret > rem_sz) { | ||
129 | size_t new_sz = env.log_cap * 3 / 2; | ||
130 | char *new_buf; | ||
131 | |||
132 | if (new_sz < 4096) | ||
133 | new_sz = 4096; | ||
134 | if (new_sz < ret + env.log_cnt) | ||
135 | new_sz = ret + env.log_cnt; | ||
136 | |||
137 | /* +1 for guaranteed space for terminating \0 */ | ||
138 | new_buf = realloc(env.log_buf, new_sz + 1); | ||
139 | if (!new_buf) { | ||
140 | fprintf(stderr, "failed to realloc log buffer: %d\n", | ||
141 | errno); | ||
142 | return; | ||
143 | } | ||
144 | env.log_buf = new_buf; | ||
145 | env.log_cap = new_sz; | ||
146 | goto try_again; | ||
147 | } | ||
148 | |||
149 | env.log_cnt += ret; | ||
150 | } | ||
151 | |||
152 | void test__printf(const char *fmt, ...) | ||
153 | { | ||
154 | va_list args; | ||
155 | |||
156 | va_start(args, fmt); | ||
157 | test__vprintf(fmt, args); | ||
158 | va_end(args); | ||
159 | } | ||
160 | |||
161 | struct ipv4_packet pkt_v4 = { | 108 | struct ipv4_packet pkt_v4 = { |
162 | .eth.h_proto = __bpf_constant_htons(ETH_P_IP), | 109 | .eth.h_proto = __bpf_constant_htons(ETH_P_IP), |
163 | .iph.ihl = 5, | 110 | .iph.ihl = 5, |
@@ -331,7 +278,7 @@ enum ARG_KEYS { | |||
331 | ARG_VERIFIER_STATS = 's', | 278 | ARG_VERIFIER_STATS = 's', |
332 | ARG_VERBOSE = 'v', | 279 | ARG_VERBOSE = 'v', |
333 | }; | 280 | }; |
334 | 281 | ||
335 | static const struct argp_option opts[] = { | 282 | static const struct argp_option opts[] = { |
336 | { "num", ARG_TEST_NUM, "NUM", 0, | 283 | { "num", ARG_TEST_NUM, "NUM", 0, |
337 | "Run test number NUM only " }, | 284 | "Run test number NUM only " }, |
@@ -349,7 +296,7 @@ static int libbpf_print_fn(enum libbpf_print_level level, | |||
349 | { | 296 | { |
350 | if (!env.very_verbose && level == LIBBPF_DEBUG) | 297 | if (!env.very_verbose && level == LIBBPF_DEBUG) |
351 | return 0; | 298 | return 0; |
352 | test__vprintf(format, args); | 299 | vprintf(format, args); |
353 | return 0; | 300 | return 0; |
354 | } | 301 | } |
355 | 302 | ||
@@ -477,6 +424,48 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) | |||
477 | return 0; | 424 | return 0; |
478 | } | 425 | } |
479 | 426 | ||
427 | static void stdio_hijack(void) | ||
428 | { | ||
429 | #ifdef __GLIBC__ | ||
430 | env.stdout = stdout; | ||
431 | env.stderr = stderr; | ||
432 | |||
433 | if (env.verbose) { | ||
434 | /* nothing to do, output to stdout by default */ | ||
435 | return; | ||
436 | } | ||
437 | |||
438 | /* stdout and stderr -> buffer */ | ||
439 | fflush(stdout); | ||
440 | |||
441 | stdout = open_memstream(&env.log_buf, &env.log_cnt); | ||
442 | if (!stdout) { | ||
443 | stdout = env.stdout; | ||
444 | perror("open_memstream"); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | stderr = stdout; | ||
449 | #endif | ||
450 | } | ||
451 | |||
452 | static void stdio_restore(void) | ||
453 | { | ||
454 | #ifdef __GLIBC__ | ||
455 | if (stdout == env.stdout) | ||
456 | return; | ||
457 | |||
458 | fclose(stdout); | ||
459 | free(env.log_buf); | ||
460 | |||
461 | env.log_buf = NULL; | ||
462 | env.log_cnt = 0; | ||
463 | |||
464 | stdout = env.stdout; | ||
465 | stderr = env.stderr; | ||
466 | #endif | ||
467 | } | ||
468 | |||
480 | int main(int argc, char **argv) | 469 | int main(int argc, char **argv) |
481 | { | 470 | { |
482 | static const struct argp argp = { | 471 | static const struct argp argp = { |
@@ -496,6 +485,7 @@ int main(int argc, char **argv) | |||
496 | 485 | ||
497 | env.jit_enabled = is_jit_enabled(); | 486 | env.jit_enabled = is_jit_enabled(); |
498 | 487 | ||
488 | stdio_hijack(); | ||
499 | for (i = 0; i < prog_test_cnt; i++) { | 489 | for (i = 0; i < prog_test_cnt; i++) { |
500 | struct prog_test_def *test = &prog_test_defs[i]; | 490 | struct prog_test_def *test = &prog_test_defs[i]; |
501 | int old_pass_cnt = pass_cnt; | 491 | int old_pass_cnt = pass_cnt; |
@@ -523,13 +513,14 @@ int main(int argc, char **argv) | |||
523 | 513 | ||
524 | dump_test_log(test, test->error_cnt); | 514 | dump_test_log(test, test->error_cnt); |
525 | 515 | ||
526 | printf("#%d %s:%s\n", test->test_num, test->test_name, | 516 | fprintf(env.stdout, "#%d %s:%s\n", |
527 | test->error_cnt ? "FAIL" : "OK"); | 517 | test->test_num, test->test_name, |
518 | test->error_cnt ? "FAIL" : "OK"); | ||
528 | } | 519 | } |
520 | stdio_restore(); | ||
529 | printf("Summary: %d/%d PASSED, %d FAILED\n", | 521 | printf("Summary: %d/%d PASSED, %d FAILED\n", |
530 | env.succ_cnt, env.sub_succ_cnt, env.fail_cnt); | 522 | env.succ_cnt, env.sub_succ_cnt, env.fail_cnt); |
531 | 523 | ||
532 | free(env.log_buf); | ||
533 | free(env.test_selector.num_set); | 524 | free(env.test_selector.num_set); |
534 | free(env.subtest_selector.num_set); | 525 | free(env.subtest_selector.num_set); |
535 | 526 | ||
diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index afd14962456f..37d427f5a1e5 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h | |||
@@ -56,9 +56,10 @@ struct test_env { | |||
56 | bool jit_enabled; | 56 | bool jit_enabled; |
57 | 57 | ||
58 | struct prog_test_def *test; | 58 | struct prog_test_def *test; |
59 | FILE *stdout; | ||
60 | FILE *stderr; | ||
59 | char *log_buf; | 61 | char *log_buf; |
60 | size_t log_cnt; | 62 | size_t log_cnt; |
61 | size_t log_cap; | ||
62 | 63 | ||
63 | int succ_cnt; /* successful tests */ | 64 | int succ_cnt; /* successful tests */ |
64 | int sub_succ_cnt; /* successful sub-tests */ | 65 | int sub_succ_cnt; /* successful sub-tests */ |
@@ -69,8 +70,6 @@ extern int error_cnt; | |||
69 | extern int pass_cnt; | 70 | extern int pass_cnt; |
70 | extern struct test_env env; | 71 | extern struct test_env env; |
71 | 72 | ||
72 | extern void test__printf(const char *fmt, ...); | ||
73 | extern void test__vprintf(const char *fmt, va_list args); | ||
74 | extern void test__force_log(); | 73 | extern void test__force_log(); |
75 | extern bool test__start_subtest(const char *name); | 74 | extern bool test__start_subtest(const char *name); |
76 | 75 | ||
@@ -96,12 +95,12 @@ extern struct ipv6_packet pkt_v6; | |||
96 | int __ret = !!(condition); \ | 95 | int __ret = !!(condition); \ |
97 | if (__ret) { \ | 96 | if (__ret) { \ |
98 | error_cnt++; \ | 97 | error_cnt++; \ |
99 | test__printf("%s:FAIL:%s ", __func__, tag); \ | 98 | printf("%s:FAIL:%s ", __func__, tag); \ |
100 | test__printf(format); \ | 99 | printf(format); \ |
101 | } else { \ | 100 | } else { \ |
102 | pass_cnt++; \ | 101 | pass_cnt++; \ |
103 | test__printf("%s:PASS:%s %d nsec\n", \ | 102 | printf("%s:PASS:%s %d nsec\n", \ |
104 | __func__, tag, duration); \ | 103 | __func__, tag, duration); \ |
105 | } \ | 104 | } \ |
106 | __ret; \ | 105 | __ret; \ |
107 | }) | 106 | }) |