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) {
50 char str
[] = "\n[KTEST]\tSTART\t" KTEST_VERSION_STR
"\n";
51 EMIT((char *)&str
[0], sizeof(str
)-1);
55 ktest_emit_finish(void) {
56 char str
[] = "\n[KTEST]\tFINISH\n";
57 EMIT((char *)&str
[0], sizeof(str
)-1);
61 ktest_emit_testbegin(const char * test_name
) {
62 char * msg
= ktest_output_buf
;
63 int size
= sizeof(ktest_output_buf
);
66 /* left trim the file path for readability */
67 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
71 "\n[KTEST]\t" /* header */
72 "TESTBEGIN\t" /* type */
83 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
85 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
89 ktest_emit_testskip(const char * skip_msg
, va_list args
) {
90 char * msg
= ktest_output_buf
;
91 int size
= sizeof(ktest_output_buf
);
94 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
98 "\n[KTEST]\t" /* header */
99 "TESTSKIP\t" /* type */
106 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
108 ret
= vsnprintf(msg
, size
, skip_msg
, args
);
109 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
111 ret
= snprintf(msg
, size
, "\n");
112 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
114 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
119 ktest_emit_testend() {
120 char * msg
= ktest_output_buf
;
121 int size
= sizeof(ktest_output_buf
);
124 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
128 "\n[KTEST]\t" /* header */
129 "TESTEND\t" /* type */
140 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
142 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
147 ktest_emit_log(const char * log_msg
, va_list args
) {
148 char * msg
= ktest_output_buf
;
149 int size
= sizeof(ktest_output_buf
);
152 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
156 "\n[KTEST]\t" /* header */
164 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
166 ret
= vsnprintf(msg
, size
, log_msg
, args
);
167 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
169 ret
= snprintf(msg
, size
, "\n");
170 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
172 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
177 ktest_emit_perfdata(const char * metric
, const char * unit
, double value
, const char * desc
)
179 static const char * perfstr
= "%s\t%lld\t%s\t\"%s\"";
180 char * msg
= ktest_output_buf
;
181 int64_t print_value
= (int64_t)value
;
182 int size
= sizeof(ktest_output_buf
);
185 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
187 ret
= snprintf(msg
, size
,
188 "\n[KTEST]\t" /* header */
196 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
198 ret
= snprintf(msg
, size
, perfstr
, metric
, print_value
, unit
, desc
);
199 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
201 ret
= snprintf(msg
, size
, "\n");
202 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
204 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));
209 ktest_emit_testcase(void) {
210 char * msg
= ktest_output_buf
;
211 int size
= sizeof(ktest_output_buf
);
214 char *fname
= strnstr((char *)(uintptr_t)ktest_current_file
, "xnu", 100);
218 "\n[KTEST]\t" /* header */
225 "%s", /* current_expr */
226 ktest_testcase_result_tokens
[ktest_testcase_mode
]
227 [ktest_testcase_result
],
229 ktest_expression_index
,
234 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
236 for(int i
= 0; ktest_current_var_names
[i
][0]; i
++) {
240 ktest_current_var_names
[i
],
241 ktest_current_var_values
[i
]);
242 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
245 ret
= snprintf(msg
, size
, "\n");
246 BOUNDS_CHECK_AND_UPDATE(ret
, size
);
248 EMIT(ktest_output_buf
, (int)(msg
- ktest_output_buf
));