1/* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2008, 2009, 2010 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 atf_tc_t *tc, 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(tc, "before"); \ 104 macro; \ 105 create_ctl_file(tc, "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_EQ_MSG_HEAD_NAME(id) \ 129 ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id) 130#define H_CHECK_EQ_MSG_BODY_NAME(id) \ 131 ATF_TC_BODY_NAME(h_check_eq_msg_ ## id) 132#define H_CHECK_EQ_MSG(id, v1, v2, msg) \ 133 H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg)) 134 135#define H_CHECK_STREQ_MSG_HEAD_NAME(id) \ 136 ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id) 137#define H_CHECK_STREQ_MSG_BODY_NAME(id) \ 138 ATF_TC_BODY_NAME(h_check_streq_msg_ ## id) 139#define H_CHECK_STREQ_MSG(id, v1, v2, msg) \ 140 H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg)) 141 142#define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id) 143#define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id) 144#define H_CHECK_ERRNO(id, exp_errno, bool_expr) \ 145 H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr)) 146 147#define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id) 148#define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id) 149#define H_REQUIRE(id, condition) \ 150 H_DEF(require_ ## id, ATF_REQUIRE(condition)) 151 152#define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id) 153#define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id) 154#define H_REQUIRE_MSG(id, condition, msg) \ 155 H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg)) 156 157#define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id) 158#define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id) 159#define H_REQUIRE_EQ(id, v1, v2) \ 160 H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2)) 161 162#define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id) 163#define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id) 164#define H_REQUIRE_STREQ(id, v1, v2) \ 165 H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2)) 166 167#define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \ 168 ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id) 169#define H_REQUIRE_EQ_MSG_BODY_NAME(id) \ 170 ATF_TC_BODY_NAME(h_require_eq_msg_ ## id) 171#define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \ 172 H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg)) 173 174#define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \ 175 ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id) 176#define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \ 177 ATF_TC_BODY_NAME(h_require_streq_msg_ ## id) 178#define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \ 179 H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg)) 180 181#define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id) 182#define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id) 183#define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \ 184 H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr)) 185 186/* --------------------------------------------------------------------- 187 * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros. 188 * --------------------------------------------------------------------- */ 189 190static int 191errno_fail_stub(const int raised_errno) 192{ 193 errno = raised_errno; 194 return -1; 195} 196 197static int 198errno_ok_stub(void) 199{ 200 return 0; 201} 202 203H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1); 204H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1); 205H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1); 206 207H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1); 208H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1); 209H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1); 210 211ATF_TC(check_errno); 212ATF_TC_HEAD(check_errno, tc) 213{ 214 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro"); 215} 216ATF_TC_BODY(check_errno, tc) 217{ 218 struct test { 219 void (*head)(atf_tc_t *); 220 void (*body)(const atf_tc_t *); 221 bool ok; 222 const char *exp_regex; 223 } *t, tests[] = { 224 { H_CHECK_ERRNO_HEAD_NAME(no_error), 225 H_CHECK_ERRNO_BODY_NAME(no_error), 226 false, "Expected true value in errno_ok_stub\\(\\) == -1" }, 227 { H_CHECK_ERRNO_HEAD_NAME(errno_ok), 228 H_CHECK_ERRNO_BODY_NAME(errno_ok), 229 true, NULL }, 230 { H_CHECK_ERRNO_HEAD_NAME(errno_fail), 231 H_CHECK_ERRNO_BODY_NAME(errno_fail), 232 false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" }, 233 { NULL, NULL, false, NULL } 234 }; 235 236 for (t = &tests[0]; t->head != NULL; t++) { 237 init_and_run_h_tc("h_check_errno", t->head, t->body); 238 239 ATF_REQUIRE(exists("before")); 240 ATF_REQUIRE(exists("after")); 241 242 if (t->ok) { 243 ATF_REQUIRE(grep_file("result", "^passed")); 244 } else { 245 ATF_REQUIRE(grep_file("result", "^failed")); 246 ATF_REQUIRE(grep_file("error", "macros_test.c:[0-9]+: %s$", 247 t->exp_regex)); 248 } 249 250 ATF_REQUIRE(unlink("before") != -1); 251 ATF_REQUIRE(unlink("after") != -1); 252 } 253} 254 255ATF_TC(require_errno); 256ATF_TC_HEAD(require_errno, tc) 257{ 258 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro"); 259} 260ATF_TC_BODY(require_errno, tc) 261{ 262 struct test { 263 void (*head)(atf_tc_t *); 264 void (*body)(const atf_tc_t *); 265 bool ok; 266 const char *exp_regex; 267 } *t, tests[] = { 268 { H_REQUIRE_ERRNO_HEAD_NAME(no_error), 269 H_REQUIRE_ERRNO_BODY_NAME(no_error), 270 false, "Expected true value in errno_ok_stub\\(\\) == -1" }, 271 { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok), 272 H_REQUIRE_ERRNO_BODY_NAME(errno_ok), 273 true, NULL }, 274 { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail), 275 H_REQUIRE_ERRNO_BODY_NAME(errno_fail), 276 false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" }, 277 { NULL, NULL, false, NULL } 278 }; 279 280 for (t = &tests[0]; t->head != NULL; t++) { 281 init_and_run_h_tc("h_require_errno", t->head, t->body); 282 283 ATF_REQUIRE(exists("before")); 284 if (t->ok) { 285 ATF_REQUIRE(grep_file("result", "^passed")); 286 ATF_REQUIRE(exists("after")); 287 } else { 288 ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: " 289 "%s$", t->exp_regex)); 290 ATF_REQUIRE(!exists("after")); 291 } 292 293 ATF_REQUIRE(unlink("before") != -1); 294 if (t->ok) 295 ATF_REQUIRE(unlink("after") != -1); 296 } 297} 298 299/* --------------------------------------------------------------------- 300 * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros. 301 * --------------------------------------------------------------------- */ 302 303H_CHECK(0, 0); 304H_CHECK(1, 1); 305H_CHECK_MSG(0, 0, "expected a false value"); 306H_CHECK_MSG(1, 1, "expected a true value"); 307 308ATF_TC(check); 309ATF_TC_HEAD(check, tc) 310{ 311 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and " 312 "ATF_CHECK_MSG macros"); 313} 314ATF_TC_BODY(check, tc) 315{ 316 struct test { 317 void (*head)(atf_tc_t *); 318 void (*body)(const atf_tc_t *); 319 bool value; 320 const char *msg; 321 bool ok; 322 } *t, tests[] = { 323 { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0, 324 "0 not met", false }, 325 { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1, 326 "1 not met", true }, 327 { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0, 328 "expected a false value", false }, 329 { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1, 330 "expected a true value", true }, 331 { NULL, NULL, false, NULL, false } 332 }; 333 334 for (t = &tests[0]; t->head != NULL; t++) { 335 printf("Checking with a %d value\n", t->value); 336 337 init_and_run_h_tc("h_check", t->head, t->body); 338 339 ATF_REQUIRE(exists("before")); 340 ATF_REQUIRE(exists("after")); 341 342 if (t->ok) { 343 ATF_REQUIRE(grep_file("result", "^passed")); 344 } else { 345 ATF_REQUIRE(grep_file("result", "^failed")); 346 ATF_REQUIRE(grep_file("error", "Check failed: .*" 347 "macros_test.c:[0-9]+: %s$", t->msg)); 348 } 349 350 ATF_REQUIRE(unlink("before") != -1); 351 ATF_REQUIRE(unlink("after") != -1); 352 } 353} 354 355/* --------------------------------------------------------------------- 356 * Test cases for the ATF_CHECK_*EQ_ macros. 357 * --------------------------------------------------------------------- */ 358 359struct check_eq_test { 360 void (*head)(atf_tc_t *); 361 void (*body)(const atf_tc_t *); 362 const char *v1; 363 const char *v2; 364 const char *msg; 365 bool ok; 366}; 367 368static 369void 370do_check_eq_tests(const struct check_eq_test *tests) 371{ 372 const struct check_eq_test *t; 373 374 for (t = &tests[0]; t->head != NULL; t++) { 375 printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2, 376 t->ok ? "true" : "false"); 377 378 init_and_run_h_tc("h_check", t->head, t->body); 379 380 ATF_CHECK(exists("before")); 381 ATF_CHECK(exists("after")); 382 383 if (t->ok) { 384 ATF_REQUIRE(grep_file("result", "^passed")); 385 } else { 386 ATF_REQUIRE(grep_file("result", "^failed")); 387 ATF_CHECK(grep_file("error", "Check failed: .*" 388 "macros_test.c:[0-9]+: %s$", t->msg)); 389 } 390 391 ATF_CHECK(unlink("before") != -1); 392 ATF_CHECK(unlink("after") != -1); 393 } 394} 395 396H_CHECK_EQ(1_1, 1, 1); 397H_CHECK_EQ(1_2, 1, 2); 398H_CHECK_EQ(2_1, 2, 1); 399H_CHECK_EQ(2_2, 2, 2); 400H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1"); 401H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2"); 402H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1"); 403H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2"); 404 405ATF_TC(check_eq); 406ATF_TC_HEAD(check_eq, tc) 407{ 408 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and " 409 "ATF_CHECK_EQ_MSG macros"); 410} 411ATF_TC_BODY(check_eq, tc) 412{ 413 struct check_eq_test tests[] = { 414 { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1), 415 "1", "1", "1 != 1", true }, 416 { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2), 417 "1", "2", "1 != 2", false }, 418 { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1), 419 "2", "1", "2 != 1", false }, 420 { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2), 421 "2", "2", "2 != 2", true }, 422 { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1), 423 "1", "1", "1 != 1: 1 does not match 1", true }, 424 { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2), 425 "1", "2", "1 != 2: 1 does not match 2", false }, 426 { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1), 427 "2", "1", "2 != 1: 2 does not match 1", false }, 428 { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2), 429 "2", "2", "2 != 2: 2 does not match 2", true }, 430 { NULL, NULL, 0, 0, "", false } 431 }; 432 do_check_eq_tests(tests); 433} 434 435H_CHECK_STREQ(1_1, "1", "1"); 436H_CHECK_STREQ(1_2, "1", "2"); 437H_CHECK_STREQ(2_1, "2", "1"); 438H_CHECK_STREQ(2_2, "2", "2"); 439H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1"); 440H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2"); 441H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1"); 442H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2"); 443#define CHECK_STREQ_VAR1 "5" 444#define CHECK_STREQ_VAR2 "9" 445const const char *check_streq_var1 = CHECK_STREQ_VAR1; 446const const char *check_streq_var2 = CHECK_STREQ_VAR2; 447H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2); 448 449ATF_TC(check_streq); 450ATF_TC_HEAD(check_streq, tc) 451{ 452 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and " 453 "ATF_CHECK_STREQ_MSG macros"); 454} 455ATF_TC_BODY(check_streq, tc) 456{ 457 struct check_eq_test tests[] = { 458 { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1), 459 "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true }, 460 { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2), 461 "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false }, 462 { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1), 463 "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false }, 464 { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2), 465 "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true }, 466 { H_CHECK_STREQ_MSG_HEAD_NAME(1_1), 467 H_CHECK_STREQ_MSG_BODY_NAME(1_1), 468 "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true }, 469 { H_CHECK_STREQ_MSG_HEAD_NAME(1_2), 470 H_CHECK_STREQ_MSG_BODY_NAME(1_2), 471 "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false }, 472 { H_CHECK_STREQ_MSG_HEAD_NAME(2_1), 473 H_CHECK_STREQ_MSG_BODY_NAME(2_1), 474 "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false }, 475 { H_CHECK_STREQ_MSG_HEAD_NAME(2_2), 476 H_CHECK_STREQ_MSG_BODY_NAME(2_2), 477 "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true }, 478 { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars), 479 check_streq_var1, check_streq_var2, 480 "check_streq_var1 != check_streq_var2 \\(" 481 CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false }, 482 { NULL, NULL, 0, 0, "", false } 483 }; 484 do_check_eq_tests(tests); 485} 486 487/* --------------------------------------------------------------------- 488 * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros. 489 * --------------------------------------------------------------------- */ 490 491H_REQUIRE(0, 0); 492H_REQUIRE(1, 1); 493H_REQUIRE_MSG(0, 0, "expected a false value"); 494H_REQUIRE_MSG(1, 1, "expected a true value"); 495 496ATF_TC(require); 497ATF_TC_HEAD(require, tc) 498{ 499 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and " 500 "ATF_REQUIRE_MSG macros"); 501} 502ATF_TC_BODY(require, tc) 503{ 504 struct test { 505 void (*head)(atf_tc_t *); 506 void (*body)(const atf_tc_t *); 507 bool value; 508 const char *msg; 509 bool ok; 510 } *t, tests[] = { 511 { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0, 512 "0 not met", false }, 513 { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1, 514 "1 not met", true }, 515 { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0, 516 "expected a false value", false }, 517 { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1, 518 "expected a true value", true }, 519 { NULL, NULL, false, NULL, false } 520 }; 521 522 for (t = &tests[0]; t->head != NULL; t++) { 523 printf("Checking with a %d value\n", t->value); 524 525 init_and_run_h_tc("h_require", t->head, t->body); 526 527 ATF_REQUIRE(exists("before")); 528 if (t->ok) { 529 ATF_REQUIRE(grep_file("result", "^passed")); 530 ATF_REQUIRE(exists("after")); 531 } else { 532 ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: " 533 "%s$", t->msg)); 534 ATF_REQUIRE(!exists("after")); 535 } 536 537 ATF_REQUIRE(unlink("before") != -1); 538 if (t->ok) 539 ATF_REQUIRE(unlink("after") != -1); 540 } 541} 542 543/* --------------------------------------------------------------------- 544 * Test cases for the ATF_REQUIRE_*EQ_ macros. 545 * --------------------------------------------------------------------- */ 546 547struct require_eq_test { 548 void (*head)(atf_tc_t *); 549 void (*body)(const atf_tc_t *); 550 const char *v1; 551 const char *v2; 552 const char *msg; 553 bool ok; 554}; 555 556static 557void 558do_require_eq_tests(const struct require_eq_test *tests) 559{ 560 const struct require_eq_test *t; 561 562 for (t = &tests[0]; t->head != NULL; t++) { 563 printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2, 564 t->ok ? "true" : "false"); 565 566 init_and_run_h_tc("h_require", t->head, t->body); 567 568 ATF_REQUIRE(exists("before")); 569 if (t->ok) { 570 ATF_REQUIRE(grep_file("result", "^passed")); 571 ATF_REQUIRE(exists("after")); 572 } else { 573 ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c" 574 ":[0-9]+: %s$", t->msg)); 575 ATF_REQUIRE(!exists("after")); 576 } 577 578 ATF_REQUIRE(unlink("before") != -1); 579 if (t->ok) 580 ATF_REQUIRE(unlink("after") != -1); 581 } 582} 583 584H_REQUIRE_EQ(1_1, 1, 1); 585H_REQUIRE_EQ(1_2, 1, 2); 586H_REQUIRE_EQ(2_1, 2, 1); 587H_REQUIRE_EQ(2_2, 2, 2); 588H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1"); 589H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2"); 590H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1"); 591H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2"); 592 593ATF_TC(require_eq); 594ATF_TC_HEAD(require_eq, tc) 595{ 596 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and " 597 "ATF_REQUIRE_EQ_MSG macros"); 598} 599ATF_TC_BODY(require_eq, tc) 600{ 601 struct require_eq_test tests[] = { 602 { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1), 603 "1", "1", "1 != 1", true }, 604 { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2), 605 "1", "2", "1 != 2", false }, 606 { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1), 607 "2", "1", "2 != 1", false }, 608 { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2), 609 "2", "2", "2 != 2", true }, 610 { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1), 611 "1", "1", "1 != 1: 1 does not match 1", true }, 612 { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2), 613 "1", "2", "1 != 2: 1 does not match 2", false }, 614 { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1), 615 "2", "1", "2 != 1: 2 does not match 1", false }, 616 { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2), 617 "2", "2", "2 != 2: 2 does not match 2", true }, 618 { NULL, NULL, 0, 0, "", false } 619 }; 620 do_require_eq_tests(tests); 621} 622 623H_REQUIRE_STREQ(1_1, "1", "1"); 624H_REQUIRE_STREQ(1_2, "1", "2"); 625H_REQUIRE_STREQ(2_1, "2", "1"); 626H_REQUIRE_STREQ(2_2, "2", "2"); 627H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1"); 628H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2"); 629H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1"); 630H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2"); 631#define REQUIRE_STREQ_VAR1 "5" 632#define REQUIRE_STREQ_VAR2 "9" 633const const char *require_streq_var1 = REQUIRE_STREQ_VAR1; 634const const char *require_streq_var2 = REQUIRE_STREQ_VAR2; 635H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2); 636 637ATF_TC(require_streq); 638ATF_TC_HEAD(require_streq, tc) 639{ 640 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and " 641 "ATF_REQUIRE_STREQ_MSG macros"); 642} 643ATF_TC_BODY(require_streq, tc) 644{ 645 struct require_eq_test tests[] = { 646 { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1), 647 "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true }, 648 { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2), 649 "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false }, 650 { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1), 651 "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false }, 652 { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2), 653 "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true }, 654 { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1), 655 H_REQUIRE_STREQ_MSG_BODY_NAME(1_1), 656 "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true }, 657 { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2), 658 H_REQUIRE_STREQ_MSG_BODY_NAME(1_2), 659 "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false }, 660 { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1), 661 H_REQUIRE_STREQ_MSG_BODY_NAME(2_1), 662 "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false }, 663 { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2), 664 H_REQUIRE_STREQ_MSG_BODY_NAME(2_2), 665 "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true }, 666 { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars), 667 require_streq_var1, require_streq_var2, 668 "require_streq_var1 != require_streq_var2 \\(" 669 REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false }, 670 { NULL, NULL, 0, 0, "", false } 671 }; 672 do_require_eq_tests(tests); 673} 674 675/* --------------------------------------------------------------------- 676 * Miscellaneous test cases covering several macros. 677 * --------------------------------------------------------------------- */ 678 679static 680bool 681aux_bool(const char *fmt) 682{ 683 return false; 684} 685 686static 687const char * 688aux_str(const char *fmt) 689{ 690 return "foo"; 691} 692 693H_CHECK(msg, aux_bool("%d")); 694H_REQUIRE(msg, aux_bool("%d")); 695H_CHECK_STREQ(msg, aux_str("%d"), ""); 696H_REQUIRE_STREQ(msg, aux_str("%d"), ""); 697 698ATF_TC(msg_embedded_fmt); 699ATF_TC_HEAD(msg_embedded_fmt, tc) 700{ 701 atf_tc_set_md_var(tc, "descr", "Tests that format strings passed " 702 "as part of the automatically-generated messages " 703 "do not get expanded"); 704} 705ATF_TC_BODY(msg_embedded_fmt, tc) 706{ 707 struct test { 708 void (*head)(atf_tc_t *); 709 void (*body)(const atf_tc_t *); 710 bool fatal; 711 const char *msg; 712 } *t, tests[] = { 713 { H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false, 714 "aux_bool\\(\"%d\"\\) not met" }, 715 { H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true, 716 "aux_bool\\(\"%d\"\\) not met" }, 717 { H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false, 718 "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" }, 719 { H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true, 720 "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" }, 721 { NULL, NULL, false, NULL } 722 }; 723 724 for (t = &tests[0]; t->head != NULL; t++) { 725 printf("Checking with an expected '%s' message\n", t->msg); 726 727 init_and_run_h_tc("h_check", t->head, t->body); 728 729 if (t->fatal) { 730 bool matched = 731 grep_file("result", "^failed: .*macros_test.c:[0-9]+: " 732 "%s$", t->msg); 733 ATF_CHECK_MSG(matched, "couldn't find error string in result"); 734 } else { 735 bool matched = grep_file("error", "Check failed: .*" 736 "macros_test.c:[0-9]+: %s$", t->msg); 737 ATF_CHECK_MSG(matched, "couldn't find error string in output"); 738 } 739 } 740} 741 742/* --------------------------------------------------------------------- 743 * Tests cases for the header file. 744 * --------------------------------------------------------------------- */ 745 746HEADER_TC(include, "atf-c/macros.h"); 747BUILD_TC(use, "macros_h_test.c", 748 "Tests that the macros provided by the atf-c/macros.h file " 749 "do not cause syntax errors when used", 750 "Build of macros_h_test.c failed; some macros in atf-c/macros.h " 751 "are broken"); 752 753/* --------------------------------------------------------------------- 754 * Main. 755 * --------------------------------------------------------------------- */ 756 757ATF_TP_ADD_TCS(tp) 758{ 759 ATF_TP_ADD_TC(tp, check); 760 ATF_TP_ADD_TC(tp, check_eq); 761 ATF_TP_ADD_TC(tp, check_streq); 762 ATF_TP_ADD_TC(tp, check_errno); 763 764 ATF_TP_ADD_TC(tp, require); 765 ATF_TP_ADD_TC(tp, require_eq); 766 ATF_TP_ADD_TC(tp, require_streq); 767 ATF_TP_ADD_TC(tp, require_errno); 768 769 ATF_TP_ADD_TC(tp, msg_embedded_fmt); 770 771 /* Add the test cases for the header file. */ 772 ATF_TP_ADD_TC(tp, include); 773 ATF_TP_ADD_TC(tp, use); 774 775 return atf_no_error(); 776} 777