1/* 2 * Copyright (c) 2005-2007,2012-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 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. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 * 23 * testmore.h 24 */ 25 26#ifndef _TESTMORE_H_ 27#define _TESTMORE_H_ 1 28 29#include <errno.h> 30#include <inttypes.h> 31#include <string.h> 32#include <stdio.h> 33#include <CoreFoundation/CFString.h> 34 35__BEGIN_DECLS 36 37/* Macros to be used in testlist.h style headers. */ 38#define ONE_TEST(x) int x(int argc, char *const *argv); 39#define DISABLED_ONE_TEST(x) ONE_TEST(x) 40#define OFF_ONE_TEST(x) ONE_TEST(x) 41 42typedef int (*one_test_entry)(int argc, char *const *argv); 43 44#define ONE_TEST_ENTRY(x) int x(int argc, char *const *argv) 45 46struct one_test_s { 47 char *name; /* test name */ 48 one_test_entry entry; /* entry point */ 49 int off; /* off by default */ 50 int sub_tests; /* number of subtests */ 51 int failed_tests; /* number of failed tests*/ 52 unsigned long duration; /* test duration in msecs */ 53 /* add more later: timing, etc... */ 54}; 55 56extern struct one_test_s testlist[]; 57 58int run_one_test(struct one_test_s *test, int argc, char * const *argv); 59 60/* this test harnes rely on shadowing for TODO, SKIP and SETUP blocks */ 61#pragma GCC diagnostic ignored "-Wshadow" 62 63#define test_create_description(TESTNAME, ...) \ 64 CFStringCreateWithFormat(NULL, NULL, CFSTR(TESTNAME), ## __VA_ARGS__) 65 66#define ok(THIS, ...) \ 67({ \ 68 bool is_ok = !!(THIS); \ 69 test_ok(is_ok, test_create_description(__VA_ARGS__), test_directive, \ 70 test_reason, __FILE__, __LINE__, NULL); \ 71}) 72#define is(THIS, THAT, ...) \ 73({ \ 74 __typeof__(THIS) _this = (THIS); \ 75 __typeof__(THAT) _that = (THAT); \ 76 test_ok((_this == _that), test_create_description(__VA_ARGS__), \ 77 test_directive, test_reason, __FILE__, __LINE__, \ 78 "# got: '%d'\n" \ 79 "# expected: '%d'\n", \ 80 _this, _that); \ 81}) 82#define isnt(THIS, THAT, ...) \ 83 cmp_ok((THIS), !=, (THAT), __VA_ARGS__) 84#define diag(MSG, ARGS...) \ 85 test_diag(test_directive, test_reason, __FILE__, __LINE__, MSG, ## ARGS) 86#define cmp_ok(THIS, OP, THAT, ...) \ 87({ \ 88 __typeof__(THIS) _this = (THIS); \ 89 __typeof__(THAT) _that = (THAT); \ 90 test_ok((_this OP _that), test_create_description(__VA_ARGS__), \ 91 test_directive, test_reason, __FILE__, __LINE__, \ 92 "# '%d'\n" \ 93 "# " #OP "\n" \ 94 "# '%d'\n", \ 95 _this, _that); \ 96}) 97#define eq_string(THIS, THAT, ...) \ 98({ \ 99 const char *_this = (THIS); \ 100 const char *_that = (THAT); \ 101 test_ok(!strcmp(_this, _that), test_create_description(__VA_ARGS__), \ 102 test_directive, test_reason, __FILE__, __LINE__, \ 103 "# '%s'\n" \ 104 "# eq\n" \ 105 "# '%s'\n", \ 106 _this, _that); \ 107}) 108#define eq_stringn(THIS, THISLEN, THAT, THATLEN, ...) \ 109({ \ 110 __typeof__(THISLEN) _thislen = (THISLEN); \ 111 __typeof__(THATLEN) _thatlen = (THATLEN); \ 112 const char *_this = (THIS); \ 113 const char *_that = (THAT); \ 114 test_ok(_thislen == _thatlen && !strncmp(_this, _that, _thislen), \ 115 test_create_description(__VA_ARGS__), test_directive, test_reason, \ 116 __FILE__, __LINE__, \ 117 "# '%.*s'\n" \ 118 "# eq\n" \ 119 "# '%.*s'\n", \ 120 (int)_thislen, _this, (int)_thatlen, _that); \ 121}) 122#define eq_cf(THIS, THAT, ...) \ 123({ \ 124 CFTypeRef _this = (THIS); \ 125 CFTypeRef _that = (THAT); \ 126 test_ok(CFEqualSafe(_this, _that), test_create_description(__VA_ARGS__), test_directive, test_reason, \ 127 __FILE__, __LINE__, \ 128 "# '%@'\n" \ 129 "# eq\n" \ 130 "# '%@'\n", \ 131 _this, _that); \ 132}) 133 134#define like(THIS, REGEXP, ...) like_not_yet_implemented() 135#define unlike(THIS, REGEXP, ...) unlike_not_yet_implemented() 136#define is_deeply(STRUCT1, STRUCT2, ...) is_deeply_not_yet_implemented() 137#define TODO switch(0) default 138#define SKIP switch(0) default 139#define SETUP switch(0) default 140#define todo(REASON) const char *test_directive __attribute__((unused)) = "TODO", \ 141 *test_reason __attribute__((unused)) = (REASON) 142#define skip(WHY, HOW_MANY, UNLESS) if (!(UNLESS)) \ 143 { test_skip((WHY), (HOW_MANY), 0); break; } 144#define setup(REASON) const char *test_directive = "SETUP", \ 145 *test_reason = (REASON) 146#define pass(...) ok(1, __VA_ARGS__) 147#define fail(...) ok(0, __VA_ARGS__) 148#define BAIL_OUT(WHY) test_bail_out(WHY, __FILE__, __LINE__) 149#define plan_skip_all(REASON) test_plan_skip_all(REASON) 150#define plan_tests(COUNT) test_plan_tests(COUNT, __FILE__, __LINE__) 151 152#define ok_status(THIS, ...) \ 153({ \ 154 OSStatus _this = (THIS); \ 155 test_ok(!_this, test_create_description(__VA_ARGS__), \ 156 test_directive, test_reason, __FILE__, __LINE__, \ 157 "# status: %s(%" PRId32 ")\n", \ 158 sec_errstr(_this), _this); \ 159}) 160#define is_status(THIS, THAT, ...) \ 161({ \ 162 OSStatus _this = (THIS); \ 163 OSStatus _that = (THAT); \ 164 test_ok(_this == _that, test_create_description(__VA_ARGS__), \ 165 test_directive, test_reason, __FILE__, __LINE__, \ 166 "# got: %s(%" PRId32 ")\n" \ 167 "# expected: %s(%" PRId32 ")\n", \ 168 sec_errstr(_this), _this, sec_errstr(_that), _that); \ 169}) 170#define ok_unix(THIS, ...) \ 171({ \ 172 int _this = (THIS) < 0 ? errno : 0; \ 173 test_ok(!_this, test_create_description(__VA_ARGS__), \ 174 test_directive, test_reason, __FILE__, __LINE__, \ 175 "# got: %s(%d)\n", \ 176 strerror(_this), _this); \ 177}) 178#define is_unix(THIS, THAT, ...) \ 179({ \ 180 int _result = (THIS); \ 181 int _this = _result < 0 ? errno : 0; \ 182 int _that = (THAT); \ 183 _that && _result < 0 \ 184 ? test_ok(_this == _that, test_create_description(__VA_ARGS__), \ 185 test_directive, test_reason, __FILE__, __LINE__, \ 186 "# got: %s(%d)\n" \ 187 "# expected: %s(%d)\n", \ 188 strerror(_this), _this, strerror(_that), _that) \ 189 : test_ok(_this == _that, test_create_description(__VA_ARGS__), \ 190 test_directive, test_reason, __FILE__, __LINE__, \ 191 "# got: %d\n" \ 192 "# expected errno: %s(%d)\n", \ 193 _result, strerror(_that), _that); \ 194}) 195 196 197extern const char *test_directive; 198extern const char *test_reason; 199 200void test_bail_out(const char *reason, const char *file, unsigned line); 201int test_diag(const char *directive, const char *reason, 202 const char *file, unsigned line, const char *fmt, ...); 203int test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const char *directive, 204 const char *reason, const char *file, unsigned line, const char *fmt, ...); 205void test_plan_skip_all(const char *reason); 206void test_plan_tests(int count, const char *file, unsigned line); 207void test_skip(const char *reason, int how_many, int unless); 208 209const char *sec_errstr(int err); 210 211__END_DECLS 212 213#endif /* !_TESTMORE_H_ */ 214