]> git.saurik.com Git - apple/xnu.git/blame - osfmk/tests/ktest_emit.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / tests / ktest_emit.c
CommitLineData
d9a64523
A
1/*
2 * Copyright (c) 2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <tests/ktest_internal.h>
30#include <kern/misc_protos.h>
31#include <kern/debug.h>
32
0a7de745 33#define EMIT(buf, size) do {\
d9a64523
A
34 console_write(buf, size); \
35 } while(0)
36
37/* TODO: intelligently truncate messages if possible */
38#define BOUNDS_CHECK_AND_UPDATE(ret, size) do {\
39 if(ret < 0 || ret >= size) {\
0a7de745 40 panic("Internal ktest error in %s", __func__);\
d9a64523
A
41 }\
42 size -= ret;\
43 msg += ret;\
44} while(0)
45
46int vsnprintf(char *, size_t, const char *, va_list);
47
48void
0a7de745
A
49ktest_emit_start(void)
50{
d9a64523 51 char str[] = "\n[KTEST]\tSTART\t" KTEST_VERSION_STR "\n";
0a7de745 52 EMIT((char *)&str[0], sizeof(str) - 1);
d9a64523
A
53}
54
55void
0a7de745
A
56ktest_emit_finish(void)
57{
d9a64523 58 char str[] = "\n[KTEST]\tFINISH\n";
0a7de745 59 EMIT((char *)&str[0], sizeof(str) - 1);
d9a64523
A
60}
61
62void
0a7de745
A
63ktest_emit_testbegin(const char * test_name)
64{
d9a64523
A
65 char * msg = ktest_output_buf;
66 int size = sizeof(ktest_output_buf);
67 int ret;
68
69 /* left trim the file path for readability */
f427ee49 70 const char *fname = strnstr((char *)(uintptr_t)ktest_current_file, "xnu", 100);
d9a64523
A
71
72 ret = snprintf(msg,
0a7de745
A
73 size,
74 "\n[KTEST]\t" /* header */
75 "TESTBEGIN\t" /* type */
76 "%lld\t" /* time */
77 "%d\t" /* index */
78 "%s\t" /* file */
79 "%d\t" /* line */
80 "%s\n", /* name */
81 ktest_current_time,
82 ktest_test_index,
83 fname,
84 ktest_current_line,
85 test_name);
d9a64523
A
86 BOUNDS_CHECK_AND_UPDATE(ret, size);
87
88 EMIT(ktest_output_buf, (int)(msg - ktest_output_buf));
89}
90
91void
0a7de745
A
92ktest_emit_testskip(const char * skip_msg, va_list args)
93{
d9a64523
A
94 char * msg = ktest_output_buf;
95 int size = sizeof(ktest_output_buf);
96 int ret;
97
f427ee49 98 const char *fname = strnstr((char *)(uintptr_t)ktest_current_file, "xnu", 100);
d9a64523
A
99
100 ret = snprintf(msg,
0a7de745
A
101 size,
102 "\n[KTEST]\t" /* header */
103 "TESTSKIP\t" /* type */
104 "%lld\t" /* time */
105 "%s\t" /* file */
106 "%d\t", /* line */
107 ktest_current_time,
108 fname,
109 ktest_current_line);
d9a64523
A
110 BOUNDS_CHECK_AND_UPDATE(ret, size);
111
112 ret = vsnprintf(msg, size, skip_msg, args);
113 BOUNDS_CHECK_AND_UPDATE(ret, size);
114
115 ret = snprintf(msg, size, "\n");
116 BOUNDS_CHECK_AND_UPDATE(ret, size);
117
118 EMIT(ktest_output_buf, (int)(msg - ktest_output_buf));
d9a64523
A
119}
120
121void
0a7de745
A
122ktest_emit_testend()
123{
d9a64523
A
124 char * msg = ktest_output_buf;
125 int size = sizeof(ktest_output_buf);
126 int ret;
127
f427ee49 128 const char *fname = strnstr((char *)(uintptr_t)ktest_current_file, "xnu", 100);
d9a64523
A
129
130 ret = snprintf(msg,
0a7de745
A
131 size,
132 "\n[KTEST]\t" /* header */
133 "TESTEND\t" /* type */
134 "%lld\t" /* time */
135 "%d\t" /* index */
136 "%s\t" /* file */
137 "%d\t" /* line */
138 "%s\n", /* name */
139 ktest_current_time,
140 ktest_test_index,
141 fname,
142 ktest_current_line,
143 ktest_test_name);
d9a64523
A
144 BOUNDS_CHECK_AND_UPDATE(ret, size);
145
146 EMIT(ktest_output_buf, (int)(msg - ktest_output_buf));
d9a64523
A
147}
148
149void
0a7de745
A
150ktest_emit_log(const char * log_msg, va_list args)
151{
d9a64523
A
152 char * msg = ktest_output_buf;
153 int size = sizeof(ktest_output_buf);
154 int ret;
155
f427ee49 156 const char *fname = strnstr((char *)(uintptr_t)ktest_current_file, "xnu", 100);
d9a64523
A
157
158 ret = snprintf(msg,
0a7de745
A
159 size,
160 "\n[KTEST]\t" /* header */
161 "LOG\t" /* type */
162 "%lld\t" /* time */
163 "%s\t" /* file */
164 "%d\t", /* line */
165 ktest_current_time,
166 fname,
167 ktest_current_line);
d9a64523
A
168 BOUNDS_CHECK_AND_UPDATE(ret, size);
169
170 ret = vsnprintf(msg, size, log_msg, args);
171 BOUNDS_CHECK_AND_UPDATE(ret, size);
172
173 ret = snprintf(msg, size, "\n");
174 BOUNDS_CHECK_AND_UPDATE(ret, size);
175
176 EMIT(ktest_output_buf, (int)(msg - ktest_output_buf));
d9a64523
A
177}
178
179void
180ktest_emit_perfdata(const char * metric, const char * unit, double value, const char * desc)
181{
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);
186 int ret;
187
f427ee49 188 const char *fname = strnstr((char *)(uintptr_t)ktest_current_file, "xnu", 100);
d9a64523
A
189
190 ret = snprintf(msg, size,
0a7de745
A
191 "\n[KTEST]\t" /* header */
192 "PERF\t" /* type */
193 "%lld\t" /* time */
194 "%s\t" /* file */
195 "%d\t", /* line */
196 ktest_current_time,
197 fname,
198 ktest_current_line);
d9a64523
A
199 BOUNDS_CHECK_AND_UPDATE(ret, size);
200
201 ret = snprintf(msg, size, perfstr, metric, print_value, unit, desc);
202 BOUNDS_CHECK_AND_UPDATE(ret, size);
203
204 ret = snprintf(msg, size, "\n");
205 BOUNDS_CHECK_AND_UPDATE(ret, size);
206
207 EMIT(ktest_output_buf, (int)(msg - ktest_output_buf));
d9a64523
A
208}
209
210void
0a7de745
A
211ktest_emit_testcase(void)
212{
d9a64523
A
213 char * msg = ktest_output_buf;
214 int size = sizeof(ktest_output_buf);
215 int ret;
216
f427ee49 217 const char *fname = strnstr((char *)(uintptr_t)ktest_current_file, "xnu", 100);
d9a64523
A
218
219 ret = snprintf(msg,
0a7de745
A
220 size,
221 "\n[KTEST]\t" /* header */
222 "%s\t" /* type */
223 "%lld\t" /* time */
224 "%d\t" /* index */
225 "%s\t" /* file */
226 "%d\t" /* line */
227 "%s\t" /* message */
228 "%s", /* current_expr */
229 ktest_testcase_result_tokens[ktest_testcase_mode]
230 [ktest_testcase_result],
231 ktest_current_time,
232 ktest_expression_index,
233 fname,
234 ktest_current_line,
235 ktest_current_msg,
236 ktest_current_expr);
d9a64523
A
237 BOUNDS_CHECK_AND_UPDATE(ret, size);
238
0a7de745 239 for (int i = 0; ktest_current_var_names[i][0]; i++) {
d9a64523 240 ret = snprintf(msg,
0a7de745
A
241 size,
242 "\t%s\t%s",
243 ktest_current_var_names[i],
244 ktest_current_var_values[i]);
d9a64523
A
245 BOUNDS_CHECK_AND_UPDATE(ret, size);
246 }
247
248 ret = snprintf(msg, size, "\n");
249 BOUNDS_CHECK_AND_UPDATE(ret, size);
250
251 EMIT(ktest_output_buf, (int)(msg - ktest_output_buf));
252}