1 /*
2 * Copyright (c) 2000-2024 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 #pragma once
30 #include "std_safe.h"
31 #include <dyld-interposing.h>
32
33 struct ut_expected_panic_s {
34 bool expect_panic;
35 jmp_buf jb;
36 const char* str_contains;
37 };
38 extern struct ut_expected_panic_s ut_expected_panic;
39
40 // Wrap a call that's expected to panic
41 // This assumes tester is single threaded
42 #define T_ASSERT_PANIC_CONTAINS(code_block, s_contains, msg) do { \
43 if (setjmp(ut_expected_panic.jb) == 0) { \
44 ut_expected_panic.expect_panic = true; \
45 ut_expected_panic.str_contains = s_contains; \
46 { \
47 code_block \
48 } \
49 T_FAIL("did not panic() %s", msg); \
50 } \
51 else { \
52 T_PASS("OK panic()ed %s", msg); \
53 } \
54 } while(false)
55
56 #define T_ASSERT_PANIC(code_block, msg) \
57 T_ASSERT_PANIC_CONTAINS(code_block, NULL, msg)
58
59 extern void ut_check_expected_panic(const char* panic_str);
60
61 static inline void raw_printf(const char *fmt, ...) __attribute__((format(printf, 1, 0)));
62
63 #define PRINT_BUF_SIZE 1024
64 static inline void
raw_printf(const char * fmt,...)65 raw_printf(const char *fmt, ...)
66 {
67 va_list listp;
68 va_start(listp, fmt);
69 char buf[PRINT_BUF_SIZE];
70 int printed = vsnprintf(buf, PRINT_BUF_SIZE, fmt, listp);
71 if (printed > PRINT_BUF_SIZE - 1) {
72 printed = PRINT_BUF_SIZE - 1;
73 }
74 write(STDOUT_FILENO, buf, printed);
75 va_end(listp);
76 }
77
78 extern void *checked_alloc_align(size_t size, size_t mask);
79
80 #define BACKTRACE_ARRAY_SIZE 100
81 struct backtrace_array {
82 void* buffer[BACKTRACE_ARRAY_SIZE];
83 int nptrs;
84 };
85 extern struct backtrace_array *collect_current_backtrace(void);
86 extern void print_collected_backtrace(struct backtrace_array *bt);
87 extern void print_current_backtrace(void);
88
89 extern void ut_set_perm_quiet(bool v);
90
91 extern int64_t run_sysctl_test(const char *t, int64_t value, int argc, char* const* argv);
92
93 #define T_MOCK(ret, name, args) \
94 extern ret name args; \
95 static ret MOCK_ ## name args; \
96 DYLD_INTERPOSE(MOCK_ ## name, name) \
97 static ret MOCK_ ## name args
98