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