]>
git.saurik.com Git - apple/security.git/blob - OSX/regressions/test/testmore.c
2 * Copyright (c) 2005-2007,2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
31 #include <sys/types.h>
33 #include <AvailabilityMacros.h>
38 static int test_fails
= 0;
39 static int test_todo_pass
= 0;
40 static int test_todo
= 0;
41 static int test_num
= 0;
42 static int test_cases
= 0;
43 static int test_plan_line
= 0;
44 static const char *test_plan_file
= NULL
;
46 const char *test_directive
= NULL
;
47 const char *test_reason
= NULL
;
49 static void fprint_string(FILE *file
, CFStringRef string
) {
51 CFRange range
= { .location
= 0 };
52 range
.length
= CFStringGetLength(string
);
53 while (range
.length
> 0) {
54 CFIndex bytesUsed
= 0;
55 CFIndex converted
= CFStringGetBytes(string
, range
, kCFStringEncodingUTF8
, 0, false, buf
, sizeof(buf
), &bytesUsed
);
56 fwrite(buf
, 1, bytesUsed
, file
);
57 range
.length
-= converted
;
58 range
.location
+= converted
;
62 static void cffprint(FILE *file
, CFStringRef fmt
, ...) CF_FORMAT_FUNCTION(2,0);
64 static void cffprint_v(FILE *file
, CFStringRef fmt
, va_list args
);
65 static void cffprint_c_v(FILE *file
, const char *fmt
, va_list args
);
67 static void cffprint_v(FILE *file
, CFStringRef fmt
, va_list args
) {
68 CFStringRef line
= CFStringCreateWithFormatAndArguments(NULL
, NULL
, fmt
, args
);
69 fprint_string(file
, line
);
73 static void cffprint_c_v(FILE *file
, const char *fmt
, va_list args
) {
74 CFStringRef cffmt
= CFStringCreateWithCString(kCFAllocatorDefault
, fmt
, kCFStringEncodingUTF8
);
75 cffprint_v(file
, cffmt
, args
);
79 static void cffprint(FILE *file
, CFStringRef fmt
, ...) {
82 cffprint_v(file
, fmt
, args
);
86 void test_skip(const char *reason
, int how_many
, int unless
)
92 for (done
= 0; done
< how_many
; ++done
)
93 test_ok(1, NULL
, "skip", reason
, __FILE__
, __LINE__
, NULL
);
96 void test_bail_out(const char *reason
, const char *file
, unsigned line
)
98 fprintf(stdout
, "[FAIL] BAIL OUT! (%s at line %u) %s\n", file
, line
, reason
);
103 void test_plan_skip_all(const char *reason
)
105 if (test_num
< test_cases
)
107 test_skip(reason
, test_cases
- test_num
, 0);
111 static const char *test_plan_name(void) {
112 const char *plan_name
= strrchr(test_plan_file
, '/');
113 plan_name
= plan_name
? plan_name
+ 1 : test_plan_file
;
117 static int test_plan_pass(void) {
119 const char *name
= test_plan_name();
120 fprintf(stdout
, "[BEGIN] %s plan\n[PASS] %s plan\n", name
, name
);
121 // Update counts for summary
128 static int test_plan_fail(CFStringRef reason
, ...) {
129 const char *name
= test_plan_name();
131 va_start(ap
, reason
);
132 CFStringRef desc
= CFStringCreateWithFormatAndArguments(kCFAllocatorDefault
, NULL
, reason
, ap
);
133 cffprint(stdout
, CFSTR("[BEGIN] %s plan\n%@[WARN] %s plan\n"), name
, desc
, name
);
135 // Update counts for summary. We consider test_plan_ok itself an unscheduled testcase for counts.
142 int test_plan_ok(void) {
145 const char *name
= test_plan_name();
151 status
= test_plan_fail(CFSTR("No tests run!\n"));
155 status
= test_plan_fail(CFSTR("Looks like your test died before it could output anything.\n"));
158 else if (test_num
< test_cases
)
160 status
= test_plan_fail(CFSTR("Looks like you planned %d tests but only ran %d.\n"), test_cases
, test_num
);
162 else if (test_num
> test_cases
)
164 status
= test_plan_fail(CFSTR("Looks like you planned %d tests but ran %d.\n"), test_cases
, test_num
);
165 } else if (!test_fails
) {
166 status
= test_plan_pass();
170 fprintf(stdout
, "%s failed %d tests of %d.\n", name
, test_fails
, test_num
);
178 static void test_plan_reset(void) {
184 test_plan_file
= NULL
;
188 void test_plan_final(int *failed
, int *todo_pass
, int *todo
, int *actual
, int *planned
, const char **file
, int *line
) {
190 *failed
= test_fails
;
192 *todo_pass
= test_todo_pass
;
198 *planned
= test_cases
;
200 *file
= test_plan_file
;
202 *line
= test_plan_line
;
207 void test_plan_tests(int count
, const char *file
, unsigned line
) {
211 "[FAIL] You tried to plan twice!\n");
220 fprintf(stdout
, "[BEGIN] plan_tests\nYou said to run 0 tests! "
221 "You've got to run something.\n[WARN] plan_tests\n");
233 test_diag(const char *directive
, const char *reason
,
234 const char *file
, unsigned line
, const char *fmt
, ...)
236 int is_todo
= directive
&& !strcmp(directive
, "TODO");
253 vfprintf(stdout
, fmt
, args
);
264 test_ok(int passed
, __attribute((cf_consumed
)) CFStringRef description
, const char *directive
,
265 const char *reason
, const char *file
, unsigned line
,
266 const char *fmt
, ...)
268 int is_todo
= directive
&& !strcmp(directive
, "TODO");
269 int is_setup
= directive
&& !is_todo
&& !strcmp(directive
, "SETUP");
276 fprintf(stdout
, "[BEGIN] SETUP\n");
280 cffprint_c_v(stdout
, fmt
, args
);
283 cffprint(stdout
, CFSTR("[WARN] SETUP%s%@%s%s\n"),
284 description
? " - " : "",
285 description
? description
: CFSTR(""),
287 reason
? reason
: "");
295 // Make having a plan optional? Commenting out the next 3 lines does - mb
296 //fprintf(stdout, "[FAIL] You tried to run a test without a plan! "
297 // "Gotta have a plan. at %s line %u\n", file, line);
306 } else if (is_todo
) {
312 /* We only print this when a test fails, unless verbose is enabled */
313 if ((!passed
&& !is_todo
) || test_verbose
> 0) {
315 if (test_strict_bats
) {
316 cffprint(stdout
, CFSTR("[BEGIN] %d%s%@\n"),
318 description
? " - " : "",
319 description
? description
: CFSTR(""));
321 if (is_todo
&& passed
) {
322 fprintf(stdout
, "%s:%d: warning: Unexpectedly passed (TODO) test\n", file
, line
);
323 } else if (is_todo
&& !passed
) {
324 /* Enable this to output TODO as warning */
325 fprintf(stdout
, "%s:%d: ok: Failed (TODO) test\n", file
, line
);
326 } else if (!passed
) {
327 fprintf(stdout
, "%s:%d: error: Failed test\n", file
, line
);
332 cffprint_c_v(stdout
, fmt
, args
);
335 cffprint(stdout
, CFSTR("[%s] %d%s%@%s%s%s%s\n"), passed
? (is_todo
? "PASS" : "PASS") : (is_todo
? "PASS" : "FAIL"),
337 description
? " - " : "",
338 description
? description
: CFSTR(""),
339 directive
? " # " : "",
340 directive
? directive
: "",
342 reason
? reason
: "");
348 CFRelease(description
);
353 // TODO: Move this to testsec.h so that testmore and testenv can be shared
358 static int bufnum
= 0;
359 static char buf
[2][20];
360 bufnum
= bufnum
? 0 : 1;
361 sprintf(buf
[bufnum
], "0x%X", err
);
364 if (err
>= errSecErrnoBase
&& err
<= errSecErrnoLimit
)
365 return strerror(err
- 100000);
367 #ifdef MAC_OS_X_VERSION_10_4
368 /* AvailabilityMacros.h would only define this if we are on a
369 Tiger or later machine. */
370 extern const char *cssmErrorString(long);
371 return cssmErrorString(err
);
372 #else /* !defined(MAC_OS_X_VERSION_10_4) */
373 extern const char *_ZN8Security15cssmErrorStringEl(long);
374 return _ZN8Security15cssmErrorStringEl(err
);
375 #endif /* MAC_OS_X_VERSION_10_4 */