1/* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/types.h> 31#include <sys/wait.h> 32 33#include <errno.h> 34#include <fcntl.h> 35#include <stdarg.h> 36#include <stdbool.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40#include <unistd.h> 41 42#include <atf-c.h> 43 44#include "detail/fs.h" 45#include "detail/process.h" 46#include "detail/test_helpers.h" 47#include "detail/text.h" 48 49/* --------------------------------------------------------------------- 50 * Auxiliary functions. 51 * --------------------------------------------------------------------- */ 52 53static 54void 55create_ctl_file(const char *name) 56{ 57 atf_fs_path_t p; 58 59 RE(atf_fs_path_init_fmt(&p, "%s", name)); 60 ATF_REQUIRE(open(atf_fs_path_cstring(&p), 61 O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1); 62 atf_fs_path_fini(&p); 63} 64 65static 66bool 67exists(const char *p) 68{ 69 bool b; 70 atf_fs_path_t pp; 71 72 RE(atf_fs_path_init_fmt(&pp, "%s", p)); 73 RE(atf_fs_exists(&pp, &b)); 74 atf_fs_path_fini(&pp); 75 76 return b; 77} 78 79static 80void 81init_and_run_h_tc(const char *name, void (*head)(atf_tc_t *), 82 void (*body)(const atf_tc_t *)) 83{ 84 atf_tc_t tc; 85 const char *const config[] = { NULL }; 86 87 RE(atf_tc_init(&tc, name, head, body, NULL, config)); 88 run_h_tc(&tc, "output", "error", "result"); 89 atf_tc_fini(&tc); 90} 91 92/* --------------------------------------------------------------------- 93 * Helper test cases. 94 * --------------------------------------------------------------------- */ 95 96#define H_DEF(id, macro) \ 97 ATF_TC_HEAD(h_ ## id, tc) \ 98 { \ 99 atf_tc_set_md_var(tc, "descr", "Helper test case"); \ 100 } \ 101 ATF_TC_BODY(h_ ## id, tc) \ 102 { \ 103 create_ctl_file("before"); \ 104 macro; \ 105 create_ctl_file("after"); \ 106 } 107 108#define H_CHECK_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_ ## id) 109#define H_CHECK_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_ ## id) 110#define H_CHECK(id, condition) \ 111 H_DEF(check_ ## id, ATF_CHECK(condition)) 112 113#define H_CHECK_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_msg_ ## id) 114#define H_CHECK_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_msg_ ## id) 115#define H_CHECK_MSG(id, condition, msg) \ 116 H_DEF(check_msg_ ## id, ATF_CHECK_MSG(condition, msg)) 117 118#define H_CHECK_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_eq_ ## id) 119#define H_CHECK_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_eq_ ## id) 120#define H_CHECK_EQ(id, v1, v2) \ 121 H_DEF(check_eq_ ## id, ATF_CHECK_EQ(v1, v2)) 122 123#define H_CHECK_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_streq_ ## id) 124#define H_CHECK_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_streq_ ## id) 125#define H_CHECK_STREQ(id, v1, v2) \ 126 H_DEF(check_streq_ ## id, ATF_CHECK_STREQ(v1, v2)) 127 128#define H_CHECK_MATCH_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_match_ ## id) 129#define H_CHECK_MATCH_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_match_ ## id) 130#define H_CHECK_MATCH(id, v1, v2) \ 131 H_DEF(check_match_ ## id, ATF_CHECK_MATCH(v1, v2)) 132 133#define H_CHECK_EQ_MSG_HEAD_NAME(id) \ 134 ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id) 135#define H_CHECK_EQ_MSG_BODY_NAME(id) \ 136 ATF_TC_BODY_NAME(h_check_eq_msg_ ## id) 137#define H_CHECK_EQ_MSG(id, v1, v2, msg) \ 138 H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg)) 139 140#define H_CHECK_STREQ_MSG_HEAD_NAME(id) \ 141 ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id) 142#define H_CHECK_STREQ_MSG_BODY_NAME(id) \ 143 ATF_TC_BODY_NAME(h_check_streq_msg_ ## id) 144#define H_CHECK_STREQ_MSG(id, v1, v2, msg) \ 145 H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg)) 146 147#define H_CHECK_MATCH_MSG_HEAD_NAME(id) \ 148 ATF_TC_HEAD_NAME(h_check_match_msg_ ## id) 149#define H_CHECK_MATCH_MSG_BODY_NAME(id) \ 150 ATF_TC_BODY_NAME(h_check_match_msg_ ## id) 151#define H_CHECK_MATCH_MSG(id, v1, v2, msg) \ 152 H_DEF(check_match_msg_ ## id, ATF_CHECK_MATCH_MSG(v1, v2, msg)) 153 154#define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id) 155#define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id) 156#define H_CHECK_ERRNO(id, exp_errno, bool_expr) \ 157 H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr)) 158 159#define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id) 160#define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id) 161#define H_REQUIRE(id, condition) \ 162 H_DEF(require_ ## id, ATF_REQUIRE(condition)) 163 164#define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id) 165#define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id) 166#define H_REQUIRE_MSG(id, condition, msg) \ 167 H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg)) 168 169#define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id) 170#define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id) 171#define H_REQUIRE_EQ(id, v1, v2) \ 172 H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2)) 173 174#define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id) 175#define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id) 176#define H_REQUIRE_STREQ(id, v1, v2) \ 177 H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2)) 178 179#define H_REQUIRE_MATCH_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_match_ ## id) 180#define H_REQUIRE_MATCH_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_match_ ## id) 181#define H_REQUIRE_MATCH(id, v1, v2) \ 182 H_DEF(require_match_ ## id, ATF_REQUIRE_MATCH(v1, v2)) 183 184#define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \ 185 ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id) 186#define H_REQUIRE_EQ_MSG_BODY_NAME(id) \ 187 ATF_TC_BODY_NAME(h_require_eq_msg_ ## id) 188#define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \ 189 H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg)) 190 191#define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \ 192 ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id) 193#define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \ 194 ATF_TC_BODY_NAME(h_require_streq_msg_ ## id) 195#define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \ 196 H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg)) 197 198#define H_REQUIRE_MATCH_MSG_HEAD_NAME(id) \ 199 ATF_TC_HEAD_NAME(h_require_match_msg_ ## id) 200#define H_REQUIRE_MATCH_MSG_BODY_NAME(id) \ 201 ATF_TC_BODY_NAME(h_require_match_msg_ ## id) 202#define H_REQUIRE_MATCH_MSG(id, v1, v2, msg) \ 203 H_DEF(require_match_msg_ ## id, ATF_REQUIRE_MATCH_MSG(v1, v2, msg)) 204 205#define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id) 206#define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id) 207#define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \ 208 H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr)) 209 210/* --------------------------------------------------------------------- 211 * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros. 212 * --------------------------------------------------------------------- */ 213 214static int 215errno_fail_stub(const int raised_errno) 216{ 217 errno = raised_errno; 218 return -1; 219} 220 221static int 222errno_ok_stub(void) 223{ 224 return 0; 225} 226 227H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1); 228H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1); 229H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1); 230 231H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1); 232H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1); 233H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1); 234 235ATF_TC(check_errno); 236ATF_TC_HEAD(check_errno, tc) 237{ 238 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro"); 239} 240ATF_TC_BODY(check_errno, tc) 241{ 242 struct test { 243 void (*head)(atf_tc_t *); 244 void (*body)(const atf_tc_t *); 245 bool ok; 246 const char *exp_regex; 247 } *t, tests[] = { 248 { H_CHECK_ERRNO_HEAD_NAME(no_error), 249 H_CHECK_ERRNO_BODY_NAME(no_error), 250 false, "Expected true value in errno_ok_stub\\(\\) == -1" }, 251 { H_CHECK_ERRNO_HEAD_NAME(errno_ok), 252 H_CHECK_ERRNO_BODY_NAME(errno_ok), 253 true, NULL }, 254 { H_CHECK_ERRNO_HEAD_NAME(errno_fail), 255 H_CHECK_ERRNO_BODY_NAME(errno_fail), 256 false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" }, 257 { NULL, NULL, false, NULL } 258 }; 259 260 for (t = &tests[0]; t->head != NULL; t++) { 261 init_and_run_h_tc("h_check_errno", t->head, t->body); 262 263 ATF_REQUIRE(exists("before")); 264 ATF_REQUIRE(exists("after")); 265 266 if (t->ok) { 267 ATF_REQUIRE(atf_utils_grep_file("^passed", "result")); 268 } else { 269 ATF_REQUIRE(atf_utils_grep_file("^failed", "result")); 270 ATF_REQUIRE(atf_utils_grep_file( 271 "macros_test.c:[0-9]+: %s$", "error", t->exp_regex)); 272 } 273 274 ATF_REQUIRE(unlink("before") != -1); 275 ATF_REQUIRE(unlink("after") != -1); 276 } 277} 278 279ATF_TC(require_errno); 280ATF_TC_HEAD(require_errno, tc) 281{ 282 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro"); 283} 284ATF_TC_BODY(require_errno, tc) 285{ 286 struct test { 287 void (*head)(atf_tc_t *); 288 void (*body)(const atf_tc_t *); 289 bool ok; 290 const char *exp_regex; 291 } *t, tests[] = { 292 { H_REQUIRE_ERRNO_HEAD_NAME(no_error), 293 H_REQUIRE_ERRNO_BODY_NAME(no_error), 294 false, "Expected true value in errno_ok_stub\\(\\) == -1" }, 295 { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok), 296 H_REQUIRE_ERRNO_BODY_NAME(errno_ok), 297 true, NULL }, 298 { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail), 299 H_REQUIRE_ERRNO_BODY_NAME(errno_fail), 300 false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" }, 301 { NULL, NULL, false, NULL } 302 }; 303 304 for (t = &tests[0]; t->head != NULL; t++) { 305 init_and_run_h_tc("h_require_errno", t->head, t->body); 306 307 ATF_REQUIRE(exists("before")); 308 if (t->ok) { 309 ATF_REQUIRE(atf_utils_grep_file("^passed", "result")); 310 ATF_REQUIRE(exists("after")); 311 } else { 312 ATF_REQUIRE(atf_utils_grep_file( 313 "^failed: .*macros_test.c:[0-9]+: %s$", "result", 314 t->exp_regex)); 315 ATF_REQUIRE(!exists("after")); 316 } 317 318 ATF_REQUIRE(unlink("before") != -1); 319 if (t->ok) 320 ATF_REQUIRE(unlink("after") != -1); 321 } 322} 323 324/* --------------------------------------------------------------------- 325 * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros. 326 * --------------------------------------------------------------------- */ 327 328H_CHECK(0, 0); 329H_CHECK(1, 1); 330H_CHECK_MSG(0, 0, "expected a false value"); 331H_CHECK_MSG(1, 1, "expected a true value"); 332 333ATF_TC(check); 334ATF_TC_HEAD(check, tc) 335{ 336 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and " 337 "ATF_CHECK_MSG macros"); 338} 339ATF_TC_BODY(check, tc) 340{ 341 struct test { 342 void (*head)(atf_tc_t *); 343 void (*body)(const atf_tc_t *); 344 bool value; 345 const char *msg; 346 bool ok; 347 } *t, tests[] = { 348 { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0, 349 "0 not met", false }, 350 { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1, 351 "1 not met", true }, 352 { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0, 353 "expected a false value", false }, 354 { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1, 355 "expected a true value", true }, 356 { NULL, NULL, false, NULL, false } 357 }; 358 359 for (t = &tests[0]; t->head != NULL; t++) { 360 printf("Checking with a %d value\n", t->value); 361 362 init_and_run_h_tc("h_check", t->head, t->body); 363 364 ATF_REQUIRE(exists("before")); 365 ATF_REQUIRE(exists("after")); 366 367 if (t->ok) { 368 ATF_REQUIRE(atf_utils_grep_file("^passed", "result")); 369 } else { 370 ATF_REQUIRE(atf_utils_grep_file("^failed", "result")); 371 ATF_REQUIRE(atf_utils_grep_file("Check failed: .*" 372 "macros_test.c:[0-9]+: %s$", "error", t->msg)); 373 } 374 375 ATF_REQUIRE(unlink("before") != -1); 376 ATF_REQUIRE(unlink("after") != -1); 377 } 378} 379 380/* --------------------------------------------------------------------- 381 * Test cases for the ATF_CHECK_*EQ_ macros. 382 * --------------------------------------------------------------------- */ 383 384struct check_eq_test { 385 void (*head)(atf_tc_t *); 386 void (*body)(const atf_tc_t *); 387 const char *v1; 388 const char *v2; 389 const char *msg; 390 bool ok; 391}; 392 393static 394void 395do_check_eq_tests(const struct check_eq_test *tests) 396{ 397 const struct check_eq_test *t; 398 399 for (t = &tests[0]; t->head != NULL; t++) { 400 printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2, 401 t->ok ? "true" : "false"); 402 403 init_and_run_h_tc("h_check", t->head, t->body); 404 405 ATF_CHECK(exists("before")); 406 ATF_CHECK(exists("after")); 407 408 if (t->ok) { 409 ATF_REQUIRE(atf_utils_grep_file("^passed", "result")); 410 } else { 411 ATF_REQUIRE(atf_utils_grep_file("^failed", "result")); 412 ATF_CHECK(atf_utils_grep_file("Check failed: .*" 413 "macros_test.c:[0-9]+: %s$", "error", t->msg)); 414 } 415 416 ATF_CHECK(unlink("before") != -1); 417 ATF_CHECK(unlink("after") != -1); 418 } 419} 420 421H_CHECK_EQ(1_1, 1, 1); 422H_CHECK_EQ(1_2, 1, 2); 423H_CHECK_EQ(2_1, 2, 1); 424H_CHECK_EQ(2_2, 2, 2); 425H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1"); 426H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2"); 427H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1"); 428H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2"); 429 430ATF_TC(check_eq); 431ATF_TC_HEAD(check_eq, tc) 432{ 433 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and " 434 "ATF_CHECK_EQ_MSG macros"); 435} 436ATF_TC_BODY(check_eq, tc) 437{ 438 struct check_eq_test tests[] = { 439 { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1), 440 "1", "1", "1 != 1", true }, 441 { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2), 442 "1", "2", "1 != 2", false }, 443 { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1), 444 "2", "1", "2 != 1", false }, 445 { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2), 446 "2", "2", "2 != 2", true }, 447 { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1), 448 "1", "1", "1 != 1: 1 does not match 1", true }, 449 { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2), 450 "1", "2", "1 != 2: 1 does not match 2", false }, 451 { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1), 452 "2", "1", "2 != 1: 2 does not match 1", false }, 453 { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2), 454 "2", "2", "2 != 2: 2 does not match 2", true }, 455 { NULL, NULL, 0, 0, "", false } 456 }; 457 do_check_eq_tests(tests); 458} 459 460H_CHECK_STREQ(1_1, "1", "1"); 461H_CHECK_STREQ(1_2, "1", "2"); 462H_CHECK_STREQ(2_1, "2", "1"); 463H_CHECK_STREQ(2_2, "2", "2"); 464H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1"); 465H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2"); 466H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1"); 467H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2"); 468#define CHECK_STREQ_VAR1 "5" 469#define CHECK_STREQ_VAR2 "9" 470const char *check_streq_var1 = CHECK_STREQ_VAR1; 471const char *check_streq_var2 = CHECK_STREQ_VAR2; 472H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2); 473 474ATF_TC(check_streq); 475ATF_TC_HEAD(check_streq, tc) 476{ 477 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and " 478 "ATF_CHECK_STREQ_MSG macros"); 479} 480ATF_TC_BODY(check_streq, tc) 481{ 482 struct check_eq_test tests[] = { 483 { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1), 484 "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true }, 485 { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2), 486 "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false }, 487 { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1), 488 "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false }, 489 { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2), 490 "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true }, 491 { H_CHECK_STREQ_MSG_HEAD_NAME(1_1), 492 H_CHECK_STREQ_MSG_BODY_NAME(1_1), 493 "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true }, 494 { H_CHECK_STREQ_MSG_HEAD_NAME(1_2), 495 H_CHECK_STREQ_MSG_BODY_NAME(1_2), 496 "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false }, 497 { H_CHECK_STREQ_MSG_HEAD_NAME(2_1), 498 H_CHECK_STREQ_MSG_BODY_NAME(2_1), 499 "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false }, 500 { H_CHECK_STREQ_MSG_HEAD_NAME(2_2), 501 H_CHECK_STREQ_MSG_BODY_NAME(2_2), 502 "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true }, 503 { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars), 504 check_streq_var1, check_streq_var2, 505 "check_streq_var1 != check_streq_var2 \\(" 506 CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false }, 507 { NULL, NULL, 0, 0, "", false } 508 }; 509 do_check_eq_tests(tests); 510} 511 512/* --------------------------------------------------------------------- 513 * Test cases for the ATF_CHECK_MATCH and ATF_CHECK_MATCH_MSG macros. 514 * --------------------------------------------------------------------- */ 515 516H_CHECK_MATCH(yes, "hello [a-z]+", "abc hello world"); 517H_CHECK_MATCH(no, "hello [a-z]+", "abc hello WORLD"); 518H_CHECK_MATCH_MSG(yes, "hello [a-z]+", "abc hello world", "lowercase"); 519H_CHECK_MATCH_MSG(no, "hello [a-z]+", "abc hello WORLD", "uppercase"); 520 521ATF_TC(check_match); 522ATF_TC_HEAD(check_match, tc) 523{ 524 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_MATCH and " 525 "ATF_CHECK_MATCH_MSG macros"); 526} 527ATF_TC_BODY(check_match, tc) 528{ 529 struct check_eq_test tests[] = { 530 { H_CHECK_MATCH_HEAD_NAME(yes), H_CHECK_MATCH_BODY_NAME(yes), 531 "hello [a-z]+", "abc hello world", "", true }, 532 { H_CHECK_MATCH_HEAD_NAME(no), H_CHECK_MATCH_BODY_NAME(no), 533 "hello [a-z]+", "abc hello WORLD", 534 "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD'", false }, 535 { H_CHECK_MATCH_MSG_HEAD_NAME(yes), H_CHECK_MATCH_MSG_BODY_NAME(yes), 536 "hello [a-z]+", "abc hello world", "", true }, 537 { H_CHECK_MATCH_MSG_HEAD_NAME(no), H_CHECK_MATCH_MSG_BODY_NAME(no), 538 "hello [a-z]+", "abc hello WORLD", 539 "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD': uppercase", 540 false }, 541 { NULL, NULL, 0, 0, "", false } 542 }; 543 do_check_eq_tests(tests); 544} 545 546/* --------------------------------------------------------------------- 547 * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros. 548 * --------------------------------------------------------------------- */ 549 550H_REQUIRE(0, 0); 551H_REQUIRE(1, 1); 552H_REQUIRE_MSG(0, 0, "expected a false value"); 553H_REQUIRE_MSG(1, 1, "expected a true value"); 554 555ATF_TC(require); 556ATF_TC_HEAD(require, tc) 557{ 558 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and " 559 "ATF_REQUIRE_MSG macros"); 560} 561ATF_TC_BODY(require, tc) 562{ 563 struct test { 564 void (*head)(atf_tc_t *); 565 void (*body)(const atf_tc_t *); 566 bool value; 567 const char *msg; 568 bool ok; 569 } *t, tests[] = { 570 { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0, 571 "0 not met", false }, 572 { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1, 573 "1 not met", true }, 574 { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0, 575 "expected a false value", false }, 576 { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1, 577 "expected a true value", true }, 578 { NULL, NULL, false, NULL, false } 579 }; 580 581 for (t = &tests[0]; t->head != NULL; t++) { 582 printf("Checking with a %d value\n", t->value); 583 584 init_and_run_h_tc("h_require", t->head, t->body); 585 586 ATF_REQUIRE(exists("before")); 587 if (t->ok) { 588 ATF_REQUIRE(atf_utils_grep_file("^passed", "result")); 589 ATF_REQUIRE(exists("after")); 590 } else { 591 ATF_REQUIRE(atf_utils_grep_file( 592 "^failed: .*macros_test.c:[0-9]+: %s$", "result", t->msg)); 593 ATF_REQUIRE(!exists("after")); 594 } 595 596 ATF_REQUIRE(unlink("before") != -1); 597 if (t->ok) 598 ATF_REQUIRE(unlink("after") != -1); 599 } 600} 601 602/* --------------------------------------------------------------------- 603 * Test cases for the ATF_REQUIRE_*EQ_ macros. 604 * --------------------------------------------------------------------- */ 605 606struct require_eq_test { 607 void (*head)(atf_tc_t *); 608 void (*body)(const atf_tc_t *); 609 const char *v1; 610 const char *v2; 611 const char *msg; 612 bool ok; 613}; 614 615static 616void 617do_require_eq_tests(const struct require_eq_test *tests) 618{ 619 const struct require_eq_test *t; 620 621 for (t = &tests[0]; t->head != NULL; t++) { 622 printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2, 623 t->ok ? "true" : "false"); 624 625 init_and_run_h_tc("h_require", t->head, t->body); 626 627 ATF_REQUIRE(exists("before")); 628 if (t->ok) { 629 ATF_REQUIRE(atf_utils_grep_file("^passed", "result")); 630 ATF_REQUIRE(exists("after")); 631 } else { 632 ATF_REQUIRE(atf_utils_grep_file("^failed: .*macros_test.c" 633 ":[0-9]+: %s$", "result", t->msg)); 634 ATF_REQUIRE(!exists("after")); 635 } 636 637 ATF_REQUIRE(unlink("before") != -1); 638 if (t->ok) 639 ATF_REQUIRE(unlink("after") != -1); 640 } 641} 642 643H_REQUIRE_EQ(1_1, 1, 1); 644H_REQUIRE_EQ(1_2, 1, 2); 645H_REQUIRE_EQ(2_1, 2, 1); 646H_REQUIRE_EQ(2_2, 2, 2); 647H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1"); 648H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2"); 649H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1"); 650H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2"); 651 652ATF_TC(require_eq); 653ATF_TC_HEAD(require_eq, tc) 654{ 655 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and " 656 "ATF_REQUIRE_EQ_MSG macros"); 657} 658ATF_TC_BODY(require_eq, tc) 659{ 660 struct require_eq_test tests[] = { 661 { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1), 662 "1", "1", "1 != 1", true }, 663 { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2), 664 "1", "2", "1 != 2", false }, 665 { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1), 666 "2", "1", "2 != 1", false }, 667 { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2), 668 "2", "2", "2 != 2", true }, 669 { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1), 670 "1", "1", "1 != 1: 1 does not match 1", true }, 671 { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2), 672 "1", "2", "1 != 2: 1 does not match 2", false }, 673 { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1), 674 "2", "1", "2 != 1: 2 does not match 1", false }, 675 { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2), 676 "2", "2", "2 != 2: 2 does not match 2", true }, 677 { NULL, NULL, 0, 0, "", false } 678 }; 679 do_require_eq_tests(tests); 680} 681 682H_REQUIRE_STREQ(1_1, "1", "1"); 683H_REQUIRE_STREQ(1_2, "1", "2"); 684H_REQUIRE_STREQ(2_1, "2", "1"); 685H_REQUIRE_STREQ(2_2, "2", "2"); 686H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1"); 687H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2"); 688H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1"); 689H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2"); 690#define REQUIRE_STREQ_VAR1 "5" 691#define REQUIRE_STREQ_VAR2 "9" 692const char *require_streq_var1 = REQUIRE_STREQ_VAR1; 693const char *require_streq_var2 = REQUIRE_STREQ_VAR2; 694H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2); 695 696ATF_TC(require_streq); 697ATF_TC_HEAD(require_streq, tc) 698{ 699 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and " 700 "ATF_REQUIRE_STREQ_MSG macros"); 701} 702ATF_TC_BODY(require_streq, tc) 703{ 704 struct require_eq_test tests[] = { 705 { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1), 706 "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true }, 707 { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2), 708 "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false }, 709 { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1), 710 "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false }, 711 { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2), 712 "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true }, 713 { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1), 714 H_REQUIRE_STREQ_MSG_BODY_NAME(1_1), 715 "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true }, 716 { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2), 717 H_REQUIRE_STREQ_MSG_BODY_NAME(1_2), 718 "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false }, 719 { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1), 720 H_REQUIRE_STREQ_MSG_BODY_NAME(2_1), 721 "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false }, 722 { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2), 723 H_REQUIRE_STREQ_MSG_BODY_NAME(2_2), 724 "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true }, 725 { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars), 726 require_streq_var1, require_streq_var2, 727 "require_streq_var1 != require_streq_var2 \\(" 728 REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false }, 729 { NULL, NULL, 0, 0, "", false } 730 }; 731 do_require_eq_tests(tests); 732} 733 734/* --------------------------------------------------------------------- 735 * Test cases for the ATF_REQUIRE_MATCH and ATF_REQUIRE_MATCH_MSG macros. 736 * --------------------------------------------------------------------- */ 737 738H_REQUIRE_MATCH(yes, "hello [a-z]+", "abc hello world"); 739H_REQUIRE_MATCH(no, "hello [a-z]+", "abc hello WORLD"); 740H_REQUIRE_MATCH_MSG(yes, "hello [a-z]+", "abc hello world", "lowercase"); 741H_REQUIRE_MATCH_MSG(no, "hello [a-z]+", "abc hello WORLD", "uppercase"); 742 743ATF_TC(require_match); 744ATF_TC_HEAD(require_match, tc) 745{ 746 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_MATCH and " 747 "ATF_REQUIRE_MATCH_MSG macros"); 748} 749ATF_TC_BODY(require_match, tc) 750{ 751 struct require_eq_test tests[] = { 752 { H_REQUIRE_MATCH_HEAD_NAME(yes), H_REQUIRE_MATCH_BODY_NAME(yes), 753 "hello [a-z]+", "abc hello world", "", true }, 754 { H_REQUIRE_MATCH_HEAD_NAME(no), H_REQUIRE_MATCH_BODY_NAME(no), 755 "hello [a-z]+", "abc hello WORLD", 756 "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD'", false }, 757 { H_REQUIRE_MATCH_MSG_HEAD_NAME(yes), 758 H_REQUIRE_MATCH_MSG_BODY_NAME(yes), 759 "hello [a-z]+", "abc hello world", "", true }, 760 { H_REQUIRE_MATCH_MSG_HEAD_NAME(no), H_REQUIRE_MATCH_MSG_BODY_NAME(no), 761 "hello [a-z]+", "abc hello WORLD", 762 "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD': uppercase", 763 false }, 764 { NULL, NULL, 0, 0, "", false } 765 }; 766 do_require_eq_tests(tests); 767} 768 769/* --------------------------------------------------------------------- 770 * Miscellaneous test cases covering several macros. 771 * --------------------------------------------------------------------- */ 772 773static 774bool 775aux_bool(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED) 776{ 777 return false; 778} 779 780static 781const char * 782aux_str(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED) 783{ 784 return "foo"; 785} 786 787H_CHECK(msg, aux_bool("%d")); 788H_REQUIRE(msg, aux_bool("%d")); 789H_CHECK_STREQ(msg, aux_str("%d"), ""); 790H_REQUIRE_STREQ(msg, aux_str("%d"), ""); 791 792ATF_TC(msg_embedded_fmt); 793ATF_TC_HEAD(msg_embedded_fmt, tc) 794{ 795 atf_tc_set_md_var(tc, "descr", "Tests that format strings passed " 796 "as part of the automatically-generated messages " 797 "do not get expanded"); 798} 799ATF_TC_BODY(msg_embedded_fmt, tc) 800{ 801 struct test { 802 void (*head)(atf_tc_t *); 803 void (*body)(const atf_tc_t *); 804 bool fatal; 805 const char *msg; 806 } *t, tests[] = { 807 { H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false, 808 "aux_bool\\(\"%d\"\\) not met" }, 809 { H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true, 810 "aux_bool\\(\"%d\"\\) not met" }, 811 { H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false, 812 "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" }, 813 { H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true, 814 "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" }, 815 { NULL, NULL, false, NULL } 816 }; 817 818 for (t = &tests[0]; t->head != NULL; t++) { 819 printf("Checking with an expected '%s' message\n", t->msg); 820 821 init_and_run_h_tc("h_check", t->head, t->body); 822 823 if (t->fatal) { 824 bool matched = 825 atf_utils_grep_file( 826 "^failed: .*macros_test.c:[0-9]+: %s$", "result", t->msg); 827 ATF_CHECK_MSG(matched, "couldn't find error string in result"); 828 } else { 829 bool matched = atf_utils_grep_file("Check failed: .*" 830 "macros_test.c:[0-9]+: %s$", "error", t->msg); 831 ATF_CHECK_MSG(matched, "couldn't find error string in output"); 832 } 833 } 834} 835 836/* --------------------------------------------------------------------- 837 * Tests cases for the header file. 838 * --------------------------------------------------------------------- */ 839 840HEADER_TC(include, "atf-c/macros.h"); 841BUILD_TC(use, "macros_h_test.c", 842 "Tests that the macros provided by the atf-c/macros.h file " 843 "do not cause syntax errors when used", 844 "Build of macros_h_test.c failed; some macros in atf-c/macros.h " 845 "are broken"); 846 847ATF_TC(detect_unused_tests); 848ATF_TC_HEAD(detect_unused_tests, tc) 849{ 850 atf_tc_set_md_var(tc, "descr", 851 "Tests that defining an unused test case raises a " 852 "warning (and thus an error)"); 853} 854ATF_TC_BODY(detect_unused_tests, tc) 855{ 856 const char* validate_compiler = 857 "struct test_struct { int dummy; };\n" 858 "#define define_unused static struct test_struct unused\n" 859 "define_unused;\n"; 860 861 atf_utils_create_file("compiler_test.c", "%s", validate_compiler); 862 if (build_check_c_o("compiler_test.c")) 863 atf_tc_expect_fail("Compiler does not raise a warning on an unused " 864 "static global variable declared by a macro"); 865 866 if (build_check_c_o_srcdir(tc, "unused_test.c")) 867 atf_tc_fail("Build of unused_test.c passed; unused test cases are " 868 "not properly detected"); 869} 870 871/* --------------------------------------------------------------------- 872 * Main. 873 * --------------------------------------------------------------------- */ 874 875ATF_TP_ADD_TCS(tp) 876{ 877 ATF_TP_ADD_TC(tp, check); 878 ATF_TP_ADD_TC(tp, check_eq); 879 ATF_TP_ADD_TC(tp, check_streq); 880 ATF_TP_ADD_TC(tp, check_errno); 881 ATF_TP_ADD_TC(tp, check_match); 882 883 ATF_TP_ADD_TC(tp, require); 884 ATF_TP_ADD_TC(tp, require_eq); 885 ATF_TP_ADD_TC(tp, require_streq); 886 ATF_TP_ADD_TC(tp, require_errno); 887 ATF_TP_ADD_TC(tp, require_match); 888 889 ATF_TP_ADD_TC(tp, msg_embedded_fmt); 890 891 /* Add the test cases for the header file. */ 892 ATF_TP_ADD_TC(tp, include); 893 ATF_TP_ADD_TC(tp, use); 894 ATF_TP_ADD_TC(tp, detect_unused_tests); 895 896 return atf_no_error(); 897} 898