2 * Copyright (c) 2015 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <tests/ktest_internal.h>
30 #include <kern/misc_protos.h>
31 #include <kern/debug.h>
33 #define EMIT(buf, size) do {\
34 console_write(buf, size); \
37 /* TODO: intelligently truncate messages if possible */
38 #define BOUNDS_CHECK_AND_UPDATE(ret, size) do {\
39 if(ret < 0 || ret >= size) {\
40 panic("Internal ktest error in %s", __func__);\
46 int vsnprintf(char *, size_t, const char *, va_list);
49 ktest_emit_start(void)
51 char str
[] = "\n[KTEST]\tSTART\t" KTEST_VERSION_STR
"\n";
52 EMIT((char *)&str
[0], sizeof(str
) - 1);
56 ktest_emit_finish(void)
58 char str
[] = "\n[KTEST]\tFINISH\n";
59 EMIT((char *)&str
[0], sizeof(str
) - 1);
63 ktest_emit_testbegin(const char * test_name
)
65 char * msg
= ktest_output_buf
;
66 int size
= sizeof(ktest_output_buf
);
69 /* left trim the file path for readability */
70 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
74 "\n[KTEST]\t" /* header */
75 "TESTBEGIN\t" /* type */
86 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
88 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
92 ktest_emit_testskip(const char * skip_msg
, va_list args
)
94 char * msg
= ktest_output_buf
;
95 int size
= sizeof(ktest_output_buf
);
98 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
102 "\n[KTEST]\t" /* header */
103 "TESTSKIP\t" /* type */
110 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
112 ret
= vsnprintf(msg
, size
, skip_msg
, args
);
113 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
115 ret
= snprintf(msg
, size
, "\n");
116 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
118 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
124 char * msg
= ktest_output_buf
;
125 int size
= sizeof(ktest_output_buf
);
128 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
132 "\n[KTEST]\t" /* header */
133 "TESTEND\t" /* type */
144 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
146 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
150 ktest_emit_log(const char * log_msg
, va_list args
)
152 char * msg
= ktest_output_buf
;
153 int size
= sizeof(ktest_output_buf
);
156 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
160 "\n[KTEST]\t" /* header */
168 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
170 ret
= vsnprintf(msg
, size
, log_msg
, args
);
171 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
173 ret
= snprintf(msg
, size
, "\n");
174 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
176 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
180 ktest_emit_perfdata(const char * metric
, const char * unit
, double value
, const char * desc
)
182 static const char * perfstr
= "%s\t%lld\t%s\t\"%s\"";
183 char * msg
= ktest_output_buf
;
184 int64_t print_value
= (int64_t)value
;
185 int size
= sizeof(ktest_output_buf
);
188 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
190 ret
= snprintf(msg
, size
,
191 "\n[KTEST]\t" /* header */
199 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
201 ret
= snprintf(msg
, size
, perfstr
, metric
, print_value
, unit
, desc
);
202 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
204 ret
= snprintf(msg
, size
, "\n");
205 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
207 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
211 ktest_emit_testcase(void)
213 char * msg
= ktest_output_buf
;
214 int size
= sizeof(ktest_output_buf
);
217 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
221 "\n[KTEST]\t" /* header */
228 "%s", /* current_expr */
229 ktest_testcase_result_tokens
[ktest_testcase_mode
]
230 [ktest_testcase_result
],
232 ktest_expression_index
,
237 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
239 for (int i
= 0; ktest_current_var_names
[i
][0]; i
++) {
243 ktest_current_var_names
[i
],
244 ktest_current_var_values
[i
]);
245 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
248 ret
= snprintf(msg
, size
, "\n");
249 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
251 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));