1 /* 2 * This file is part of the Sofia-SIP package 3 * 4 * Copyright (C) 2005 Nokia Corporation. 5 * 6 * Contact: Pekka Pessi <pekka.pessi@nokia.com> 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 * 23 */ 24 25 /**@file sofia-sip/tstdef.h Macros for unit tests 26 * 27 * The macros defined here can be used by unit test programs. When a test 28 * fails, the TEST macros print the offending file name and line number. 29 * They use format that is accepted by Emacs and other fine editors so you 30 * can directly go to the source code of the failed test with next-error. 31 * 32 * @note There is no protection agains multiple inclusion. 33 * 34 * @author Pekka Pessi <Pekka.Pessi@nokia.com> 35 * 36 * @date Created: Wed Aug 22 13:53:24 2001 ppessi 37 * 38 * @par Example Program 39 * 40 * You should define the macro TSTFLAGS to a int variable possibly 41 * containing a flag #tst_verbatim. As a convention, the int variable should 42 * be set when your test program is run with @c -v or @c --verbatim command 43 * line option. If the (TSTFLAGS & tst_verbatim) is true, the test macros 44 * log the test before executing it and the result of successful tests, too. 45 * 46 * You should typedef longlong to integer type at least 64 bit wide before 47 * including <sofia-sip/tstdef.h>, too. 48 * 49 * As an example, we provide a test program making sure that inet_ntop() and 50 * inet_pton() behave as expected and that we can create UDP/IPv4 sockets 51 * with @b su library: 52 * 53 * @code 54 * #include "config.h" 55 * 56 * #include <stdio.h> 57 * #include <limits.h> 58 * 59 * #include <sofia-sip/su.h> 60 * 61 * #define TSTFLAGS tstflags 62 * 63 * #include <stdlib.h> 64 * #include <sofia-sip/tstdef.h> 65 * 66 * static int tstflags = 0; 67 * 68 * void usage(void) 69 * { 70 * fprintf(stderr, "usage: %s [-v|--verbatim]\n", name); 71 * exit(2); 72 * } 73 * 74 * static int socket_test(void); 75 * 76 * int main(int argc, char *argv[]) 77 * { 78 * int retval = 0, i; 79 * 80 * for (i = 1; argv[i]; i++) { 81 * if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbatim") == 0) 82 * tstflags |= tst_verbatim; 83 * else 84 * usage(); 85 * } 86 * 87 * retval |= socket_test(); fflush(stdout); 88 * 89 * return retval; 90 * } 91 * 92 * double max_bandwidth() 93 * 94 * int socket_test(void) 95 * { 96 * su_socket_t s; 97 * char buf[64]; 98 * unsigned long localhost = htonl(0x7f000001); 99 * unsigned long addr; 100 * 101 * BEGIN(); 102 * 103 * // Check inet_ntop() return value (Tests equality of integral values) 104 * TEST(inet_ntop(AF_INET, &localhost, buf, sizeof buf), buf); 105 * 106 * // Check inet_ntop() result (Tests equality of strings) 107 * TEST_S(buf, "127.0.0.1"); 108 * 109 * // Check inet_pton() argument validation (Tests equality of ints) 110 * TEST(inet_pton(0, buf, &addr), -1); 111 * 112 * // Check inet_pton() return value (Tests for true value (non-zero)) 113 * TEST_1(inet_pton(AF_INET, buf, &addr) > 0); 114 * 115 * // Check inet_pton() result (Tests equality of memory areas) 116 * TEST_M(&addr, &localhost, sizeof(addr)); 117 * 118 * // Test to create UDP socket (Test for true value) 119 * TEST_1((s = su_socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET); 120 * 121 * // Check max bandwidth 122 * TEST_D(max_bandwidth(), DBL_MAX); 123 * 124 * END(); 125 * } 126 * @endcode 127 */ 128 129 #ifndef SU_TYPES_H 130 #include <sofia-sip/su_types.h> 131 #endif 132 133 SOFIA_BEGIN_DECLS 134 135 #if HAVE_FUNC 136 #define TSTNAME name, __func__, "() " 137 #elif HAVE_FUNCTION 138 #define TSTNAME name, __FUNCTION__, "() " 139 #else 140 #define TSTNAME name, "", "" 141 #endif 142 143 enum { 144 /** If (TSTFLAGS & tst_verbatim) is non-zero, be verbatim. */ 145 tst_verbatim = 1, 146 /** If (TSTFLAGS & tst_abort) is non-zero, abort() when failed. */ 147 tst_abort = 2, 148 /** If (TSTFLAGS & tst_log) is non-zero, log intermediate results. */ 149 tst_log = 4 150 }; 151 152 #ifndef TSTFLAGS 153 #error <TSTFLAGS is not defined> 154 #endif 155 156 /** Begin a test function. @HIDE */ 157 #define BEGIN() BEGIN_(TSTFLAGS); { extern int tstdef_dummy 158 /** End a test function. @HIDE */ 159 #define END() (void) tstdef_dummy; } END_(TSTFLAGS) 160 /**Test that @a suite returns a nonzero value. 161 * @deprecated Use TEST_1() 162 * @HIDE */ 163 #define TEST0(suite) TEST_1_(TSTFLAGS, suite) 164 /** Test that @a suite returns a nonzero value. @HIDE */ 165 #define TEST_1(suite) TEST_1_(TSTFLAGS, suite) 166 /** Test a void suite. @HIDE */ 167 #define TEST_VOID(suite) TEST_VOID_(TSTFLAGS, suite) 168 /** Test that @a suite is equal to @a expected. @HIDE */ 169 #define TEST(suite, expected) TEST_(TSTFLAGS, suite, expected) 170 /** Test that @a suite is same pointer as @a expected. @HIDE */ 171 #define TEST_P(suite, expected) TEST_P_(TSTFLAGS, suite, expected) 172 /** Test that 64-bit @a suite is equal to @a expect. @HIDE */ 173 #define TEST64(suite, expected) TEST64_(TSTFLAGS, suite, expected) 174 /** Test that @a suite is same double as @a expected. @HIDE */ 175 #define TEST_D(suite, expected) TEST_D_(TSTFLAGS, suite, expected) 176 /** Test that @a suite is same string as @a expected. @HIDE */ 177 #define TEST_S(suite, expected) TEST_S_(TSTFLAGS, suite, expected) 178 /** Test that @a suite is results as identical memory as @a expected. @HIDE */ 179 #define TEST_M(suite, expected, len) TEST_M_(TSTFLAGS, suite, expected, len) 180 /** Test that @a suite has same size as @a expected. @HIDE */ 181 #define TEST_SIZE(suite, expected) TEST_SIZE_(TSTFLAGS, suite, expected) 182 183 /** Print in torture test with -l option */ 184 #define TEST_LOG(x) \ 185 do { \ 186 if (tstflags & tst_log) \ 187 printf x; \ 188 } while(0) 189 190 #define TEST_FAILED(flags) \ 191 ((flags) & tst_abort) ? abort() : (void)0; return 1 192 193 /** @HIDE */ 194 #define TEST_1_(flags, suite) do { \ 195 if (flags & tst_verbatim) { \ 196 printf("%s: %s%stesting %s\n", TSTNAME, #suite); \ 197 fflush(stdout); } \ 198 if ((suite)) { if (flags & tst_verbatim) \ 199 printf("%s: %s%sok: (%s)\n", TSTNAME, #suite); break ; } \ 200 fprintf(stderr, "%s:%u: %s %s%sFAILED: (%s)\n", \ 201 __FILE__, __LINE__, TSTNAME, #suite); fflush(stderr); \ 202 TEST_FAILED(flags); } \ 203 while(0) 204 205 /** @HIDE */ 206 #define TEST_VOID_(flags, suite) do { \ 207 if (flags & tst_verbatim) { \ 208 printf("%s: %s%stesting %s\n", TSTNAME, #suite); \ 209 fflush(stdout); } \ 210 (suite); } while(0) 211 212 /** @HIDE */ 213 #define TEST_(flags, suite, expect) do { \ 214 uintptr_t _value, _expect; \ 215 if (flags & tst_verbatim) { \ 216 printf("%s: %s%stesting %s == %s\n", TSTNAME, #suite, #expect); \ 217 fflush(stdout); } \ 218 _value = (uintptr_t)(suite); \ 219 _expect = (uintptr_t)(expect); \ 220 if (_value == _expect) { \ 221 if (flags & tst_verbatim) \ 222 printf("%s: %s%sok: %s == %s \n", \ 223 TSTNAME, #suite, #expect); \ 224 break; \ 225 } \ 226 fprintf(stderr, "%s:%u: %s %s%sFAILED: " \ 227 "%s != %s or "MOD_ZU" != "MOD_ZU"\n", \ 228 __FILE__, __LINE__, TSTNAME, \ 229 #suite, #expect, (size_t)_value, (size_t)_expect); \ 230 fflush(stderr); \ 231 TEST_FAILED(flags); \ 232 } while(0) 233 234 /** @HIDE */ 235 #define TEST_P_(flags, suite, expect) do { \ 236 void const * _value, * _expect; \ 237 if (flags & tst_verbatim) { \ 238 printf("%s: %s%stesting %s == %s\n", TSTNAME, #suite, #expect); \ 239 fflush(stdout); } \ 240 if ((_value = (suite)) == (_expect = (expect))) { \ 241 if (flags & tst_verbatim) \ 242 printf("%s: %s%sok: %s == %s \n", TSTNAME, #suite, #expect); \ 243 break; \ 244 } \ 245 fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s or %p != %p\n", \ 246 __FILE__, __LINE__, TSTNAME, \ 247 #suite, #expect, _value, _expect); fflush(stderr); \ 248 TEST_FAILED(flags); \ 249 } while(0) 250 251 /** @HIDE */ 252 #define TEST_SIZE_(flags, suite, expect) do { \ 253 size_t _value, _expect; \ 254 if (flags & tst_verbatim) { \ 255 printf("%s: %s%stesting %s == %s\n", TSTNAME, #suite, #expect); \ 256 fflush(stdout); } \ 257 if ((_value = (size_t)(suite)) == \ 258 (_expect = (size_t)(expect))) \ 259 { if (flags & tst_verbatim) \ 260 printf("%s: %s%sok: %s == %s \n", TSTNAME, #suite, #expect); break; } \ 261 fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s or "MOD_ZU" != "MOD_ZU"\n", \ 262 __FILE__, __LINE__, TSTNAME, \ 263 #suite, #expect, _value, _expect); fflush(stderr); \ 264 TEST_FAILED(flags); \ 265 } while(0) 266 267 268 /** @HIDE */ 269 #define TEST64_(flags, suite, expect) do { \ 270 uint64_t _value, _expect; \ 271 if (flags & tst_verbatim) { \ 272 printf("%s: %s%stesting %s == %s\n", TSTNAME, #suite, #expect); \ 273 fflush(stdout); } \ 274 if ((_value = (uint64_t)(suite)) == (_expect = (uint64_t)(expect))) \ 275 { if (flags & tst_verbatim) \ 276 printf("%s: %s%sok: %s == %s \n", TSTNAME, #suite, #expect); break; } \ 277 fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s or "LLU" != "LLU"\n", \ 278 __FILE__, __LINE__, TSTNAME, \ 279 #suite, #expect, (unsigned longlong)_value, \ 280 (unsigned longlong)_expect); fflush(stderr); \ 281 TEST_FAILED(flags); \ 282 } while(0) 283 284 /** @HIDE */ 285 #define TEST_D_(flags, suite, expect) do { \ 286 double _value, _expect; \ 287 if (flags & tst_verbatim) { \ 288 printf("%s: %s%stesting %s == %s\n", TSTNAME, #suite, #expect); \ 289 fflush(stdout); } \ 290 if ((_value = (double)(suite)) == (_expect = (double)(expect))) \ 291 { if (flags & tst_verbatim) \ 292 printf("%s: %s%sok: %s == %s \n", TSTNAME, #suite, #expect); break; } \ 293 fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s or %g != %g\n", \ 294 __FILE__, __LINE__, TSTNAME, \ 295 #suite, #expect, _value, _expect); fflush(stderr); \ 296 TEST_FAILED(flags); \ 297 } while(0) 298 299 /** @HIDE */ 300 #define TEST_S_(flags, suite, expect) do { \ 301 char const * _value, * _expect; \ 302 if (flags & tst_verbatim) { \ 303 printf("%s: %s%stesting %s is %s\n", TSTNAME, #suite, #expect); \ 304 fflush(stdout); } \ 305 _value = (suite); \ 306 _expect = (expect); \ 307 if (((_value == NULL || _expect == NULL) && _value == _expect) || \ 308 (_value != NULL && _expect != NULL && strcmp(_value, _expect) == 0)) \ 309 { if (flags & tst_verbatim) \ 310 printf("%s: %s%sok: %s == %s \n", TSTNAME, #suite, #expect);break;}\ 311 fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s or %s%s%s != \"%s\"\n", \ 312 __FILE__, __LINE__, TSTNAME, \ 313 #suite, #expect, \ 314 _value ? "\"" : "", _value ? _value : "NULL", _value ? "\"" : "", \ 315 _expect); fflush(stderr); \ 316 TEST_FAILED(flags); \ 317 } while(0) 318 319 /** @HIDE */ 320 #define TEST_M_(flags, suite, expect, len) do { \ 321 void const * _value, * _expect; \ 322 size_t _len; \ 323 if (flags & tst_verbatim) { \ 324 printf("%s: %s%stesting %s is %s\n", TSTNAME, #suite, #expect); \ 325 fflush(stdout); } \ 326 _value = (suite); \ 327 _expect = (expect); \ 328 _len = (size_t)(len); \ 329 if (((_value == NULL || _expect == NULL) && _value == _expect) || \ 330 memcmp(_value, _expect, _len) == 0) \ 331 { if (flags & tst_verbatim) \ 332 printf("%s: %s%sok: %s == %s \n", TSTNAME, #suite, #expect);break;}\ 333 fprintf(stderr, "%s:%u: %s %s%sFAILED: %s != %s "\ 334 "or \"%.*s\" != \"%.*s\"\n", \ 335 __FILE__, __LINE__, TSTNAME, \ 336 #suite, #expect, (int)_len, \ 337 (char *)_value, (int)_len, (char *)_expect); \ 338 fflush(stderr); \ 339 TEST_FAILED(flags); \ 340 } while(0) 341 342 /** @HIDE */ 343 #define BEGIN_(flags) \ 344 if (flags & tst_verbatim) printf("%s: %s%sstarting\n", TSTNAME) 345 346 /** @HIDE */ 347 #define END_(flags) \ 348 if (flags & tst_verbatim) \ 349 printf("%s: %s%sfinished fully successful\n", TSTNAME); \ 350 return 0 351 352 SOFIA_END_DECLS 353