1/* $NetBSD: tinytest_macros.h,v 1.6 2021/04/10 19:18:45 rillig Exp $ */ 2 3/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#ifndef TINYTEST_MACROS_H_INCLUDED_ 29#define TINYTEST_MACROS_H_INCLUDED_ 30 31/* Helpers for defining statement-like macros */ 32#define TT_STMT_BEGIN do { 33#define TT_STMT_END } while (0) 34 35/* Redefine this if your test functions want to abort with something besides 36 * "goto end;" */ 37#ifndef TT_EXIT_TEST_FUNCTION 38#define TT_EXIT_TEST_FUNCTION TT_STMT_BEGIN goto end; TT_STMT_END 39#endif 40 41/* Redefine this if you want to note success/failure in some different way. */ 42#ifndef TT_DECLARE 43#define TT_DECLARE(prefix, args) \ 44 TT_STMT_BEGIN \ 45 printf("\n %s %s:%d: ",prefix,__FILE__,__LINE__); \ 46 printf args ; \ 47 TT_STMT_END 48#endif 49 50/* Announce a failure. Args are parenthesized printf args. */ 51#define TT_GRIPE(args) TT_DECLARE("FAIL", args) 52 53/* Announce a non-failure if we're verbose. */ 54#define TT_BLATHER(args) \ 55 TT_STMT_BEGIN \ 56 if (tinytest_get_verbosity_()>1) TT_DECLARE(" OK", args); \ 57 TT_STMT_END 58 59#define TT_DIE(args) \ 60 TT_STMT_BEGIN \ 61 tinytest_set_test_failed_(); \ 62 TT_GRIPE(args); \ 63 TT_EXIT_TEST_FUNCTION; \ 64 TT_STMT_END 65 66#define TT_FAIL(args) \ 67 TT_STMT_BEGIN \ 68 tinytest_set_test_failed_(); \ 69 TT_GRIPE(args); \ 70 TT_STMT_END 71 72/* Fail and abort the current test for the reason in msg */ 73#define tt_abort_printf(msg) TT_DIE(msg) 74#define tt_abort_perror(op) TT_DIE(("%s: %s [%d]",(op),strerror(errno), errno)) 75#define tt_abort_msg(msg) TT_DIE(("%s", msg)) 76#define tt_abort() TT_DIE(("%s", "(Failed.)")) 77 78/* Fail but do not abort the current test for the reason in msg. */ 79#define tt_failprint_f(msg) TT_FAIL(msg) 80#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno)) 81#define tt_fail_msg(msg) TT_FAIL(("%s", msg)) 82#define tt_fail() TT_FAIL(("%s", "(Failed.)")) 83 84/* End the current test, and indicate we are skipping it. */ 85#define tt_skip() \ 86 TT_STMT_BEGIN \ 87 tinytest_set_test_skipped_(); \ 88 TT_EXIT_TEST_FUNCTION; \ 89 TT_STMT_END 90 91#define tt_want_(b, msg, fail) \ 92 TT_STMT_BEGIN \ 93 if (!(b)) { \ 94 tinytest_set_test_failed_(); \ 95 TT_GRIPE(("%s",msg)); \ 96 fail; \ 97 } else { \ 98 TT_BLATHER(("%s",msg)); \ 99 } \ 100 TT_STMT_END 101 102/* Assert b, but do not stop the test if b fails. Log msg on failure. */ 103#define tt_want_msg(b, msg) \ 104 tt_want_(b, msg, ); 105 106/* Assert b and stop the test if b fails. Log msg on failure. */ 107#define tt_assert_msg(b, msg) \ 108 tt_want_(b, msg, TT_EXIT_TEST_FUNCTION); 109 110/* Assert b, but do not stop the test if b fails. */ 111#define tt_want(b) tt_want_msg( (b), "want("#b")") 112/* Assert b, and stop the test if b fails. */ 113#define tt_assert(b) tt_assert_msg((b), "assert("#b")") 114 115#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \ 116 setup_block,cleanup_block,die_on_fail) \ 117 TT_STMT_BEGIN \ 118 type val1_ = (type)(a); \ 119 type val2_ = (type)(b); \ 120 int tt_status_ = (test); \ 121 if (!tt_status_ || tinytest_get_verbosity_()>1) { \ 122 printf_type print_; \ 123 printf_type print1_; \ 124 printf_type print2_; \ 125 type value_ = val1_; \ 126 setup_block; \ 127 print1_ = print_; \ 128 value_ = val2_; \ 129 setup_block; \ 130 print2_ = print_; \ 131 TT_DECLARE(tt_status_?" OK":"FAIL", \ 132 ("assert(%s): "printf_fmt" vs "printf_fmt, \ 133 str_test, print1_, print2_)); \ 134 print_ = print1_; \ 135 cleanup_block; \ 136 print_ = print2_; \ 137 cleanup_block; \ 138 if (!tt_status_) { \ 139 tinytest_set_test_failed_(); \ 140 die_on_fail ; \ 141 } \ 142 } \ 143 TT_STMT_END 144 145#define tt_assert_test_type(a,b,str_test,type,test,fmt,die_on_fail) \ 146 tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ 147 {print_=value_;},{},die_on_fail) 148 149#define tt_assert_test_type_opt(a,b,str_test,type,test,fmt,die_on_fail) \ 150 tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ 151 {print_=value_?value_:"<NULL>";},{},die_on_fail) 152 153/* Helper: assert that a op b, when cast to type. Format the values with 154 * printf format fmt on failure. */ 155#define tt_assert_op_type(a,op,b,type,fmt) \ 156 tt_assert_test_type(a,b,#a" "#op" "#b,type,(val1_ op val2_),fmt, \ 157 TT_EXIT_TEST_FUNCTION) 158 159#define tt_int_op(a,op,b) \ 160 tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \ 161 "%ld",TT_EXIT_TEST_FUNCTION) 162 163/** To compare SOCKET(windows)/fd */ 164#define tt_fd_op(a,op,b) do { \ 165 int _a = (int)(a); \ 166 int _b = (int)(b); \ 167 tt_assert_test_type(_a,_b,#a" "#op" "#b,long,(val1_ op val2_), \ 168 "%ld",TT_EXIT_TEST_FUNCTION); \ 169} while (0) 170 171#define tt_uint_op(a,op,b) \ 172 tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ 173 (val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION) 174 175#define tt_ptr_op(a,op,b) \ 176 tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \ 177 (val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION) 178 179/** XXX: have some issues with printing this non-NUL terminated strings */ 180#define tt_nstr_op(n,a,op,b) \ 181 tt_assert_test_type_opt(a,b,#a" "#op" "#b,const char *, \ 182 (val1_ && val2_ && strncmp(val1_,val2_,(n)) op 0),"<%s>", \ 183 TT_EXIT_TEST_FUNCTION) 184 185#define tt_str_op(a,op,b) \ 186 tt_assert_test_type_opt(a,b,#a" "#op" "#b,const char *, \ 187 (val1_ && val2_ && strcmp(val1_,val2_) op 0),"<%s>", \ 188 TT_EXIT_TEST_FUNCTION) 189 190#define tt_mem_op(expr1, op, expr2, len) \ 191 tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \ 192 const void *, \ 193 (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), \ 194 char *, "%s", \ 195 { print_ = tinytest_format_hex_(value_, (len)); }, \ 196 { if (print_) free(print_); }, \ 197 TT_EXIT_TEST_FUNCTION \ 198 ); 199 200#define tt_want_int_op(a,op,b) \ 201 tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_),"%ld",(void)0) 202 203#define tt_want_uint_op(a,op,b) \ 204 tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ 205 (val1_ op val2_),"%lu",(void)0) 206 207#define tt_want_ptr_op(a,op,b) \ 208 tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \ 209 (val1_ op val2_),"%p",(void)0) 210 211#define tt_want_str_op(a,op,b) \ 212 tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \ 213 (strcmp(val1_,val2_) op 0),"<%s>",(void)0) 214 215#endif 216