1ceb42a13SJonathan Anderson /*- 2ceb42a13SJonathan Anderson * Copyright (c) 2008-2011 Robert N. M. Watson 3f8c6c2cfSJonathan Anderson * Copyright (c) 2011 Jonathan Anderson 4ceb42a13SJonathan Anderson * All rights reserved. 5ceb42a13SJonathan Anderson * 6ceb42a13SJonathan Anderson * Redistribution and use in source and binary forms, with or without 7ceb42a13SJonathan Anderson * modification, are permitted provided that the following conditions 8ceb42a13SJonathan Anderson * are met: 9ceb42a13SJonathan Anderson * 1. Redistributions of source code must retain the above copyright 10ceb42a13SJonathan Anderson * notice, this list of conditions and the following disclaimer. 11ceb42a13SJonathan Anderson * 2. Redistributions in binary form must reproduce the above copyright 12ceb42a13SJonathan Anderson * notice, this list of conditions and the following disclaimer in the 13ceb42a13SJonathan Anderson * documentation and/or other materials provided with the distribution. 14ceb42a13SJonathan Anderson * 15ceb42a13SJonathan Anderson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16ceb42a13SJonathan Anderson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17ceb42a13SJonathan Anderson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18ceb42a13SJonathan Anderson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19ceb42a13SJonathan Anderson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20ceb42a13SJonathan Anderson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21ceb42a13SJonathan Anderson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22ceb42a13SJonathan Anderson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23ceb42a13SJonathan Anderson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24ceb42a13SJonathan Anderson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25ceb42a13SJonathan Anderson * SUCH DAMAGE. 26ceb42a13SJonathan Anderson * 27ceb42a13SJonathan Anderson * $FreeBSD$ 28ceb42a13SJonathan Anderson */ 29ceb42a13SJonathan Anderson 30ceb42a13SJonathan Anderson #include <sys/cdefs.h> 31ceb42a13SJonathan Anderson __FBSDID("$FreeBSD$"); 32ceb42a13SJonathan Anderson 33f8c6c2cfSJonathan Anderson #include <sys/wait.h> 34f8c6c2cfSJonathan Anderson 35f8c6c2cfSJonathan Anderson #include <err.h> 36a9d2f8d8SRobert Watson #include <inttypes.h> 37f8c6c2cfSJonathan Anderson #include <stdio.h> 38ceb42a13SJonathan Anderson #include <stdlib.h> 39f8c6c2cfSJonathan Anderson #include <string.h> 40f8c6c2cfSJonathan Anderson #include <unistd.h> 41ceb42a13SJonathan Anderson 42ceb42a13SJonathan Anderson #include "cap_test.h" 43ceb42a13SJonathan Anderson 44f8c6c2cfSJonathan Anderson /* Initialize a named test. Requires test_NAME() function to be declared. */ 45f8c6c2cfSJonathan Anderson #define TEST_INIT(name) { #name, test_##name, FAILED } 46f8c6c2cfSJonathan Anderson 47f8c6c2cfSJonathan Anderson /* All of the tests that can be run. */ 48f8c6c2cfSJonathan Anderson struct test all_tests[] = { 49f8c6c2cfSJonathan Anderson TEST_INIT(capmode), 50f8c6c2cfSJonathan Anderson TEST_INIT(capabilities), 51f8c6c2cfSJonathan Anderson TEST_INIT(fcntl), 52*b465884fSJonathan Anderson TEST_INIT(pdfork), 53*b465884fSJonathan Anderson TEST_INIT(pdkill), 54a0108be6SJonathan Anderson TEST_INIT(relative), 55f8c6c2cfSJonathan Anderson TEST_INIT(sysctl), 56f8c6c2cfSJonathan Anderson }; 57dbb202b3SJonathan Anderson int test_count = sizeof(all_tests) / sizeof(struct test); 58f8c6c2cfSJonathan Anderson 59ceb42a13SJonathan Anderson int 60ceb42a13SJonathan Anderson main(int argc, char *argv[]) 61ceb42a13SJonathan Anderson { 62f8c6c2cfSJonathan Anderson 63ceb42a13SJonathan Anderson /* 64f8c6c2cfSJonathan Anderson * If no tests have been specified at the command line, run them all. 65ceb42a13SJonathan Anderson */ 66f8c6c2cfSJonathan Anderson if (argc == 1) { 67dbb202b3SJonathan Anderson printf("1..%d\n", test_count); 68f8c6c2cfSJonathan Anderson 69dbb202b3SJonathan Anderson for (int i = 0; i < test_count; i++) 70f8c6c2cfSJonathan Anderson execute(i + 1, all_tests + i); 71f8c6c2cfSJonathan Anderson return (0); 72f8c6c2cfSJonathan Anderson } 73f8c6c2cfSJonathan Anderson 74f8c6c2cfSJonathan Anderson /* 75f8c6c2cfSJonathan Anderson * Otherwise, run only the specified tests. 76f8c6c2cfSJonathan Anderson */ 77f8c6c2cfSJonathan Anderson printf("1..%d\n", argc - 1); 78f8c6c2cfSJonathan Anderson for (int i = 1; i < argc; i++) 79f8c6c2cfSJonathan Anderson { 80f8c6c2cfSJonathan Anderson int found = 0; 81dbb202b3SJonathan Anderson for (int j = 0; j < test_count; j++) { 82f8c6c2cfSJonathan Anderson if (strncmp(argv[i], all_tests[j].t_name, 83f8c6c2cfSJonathan Anderson strlen(argv[i])) == 0) { 84f8c6c2cfSJonathan Anderson found = 1; 85f8c6c2cfSJonathan Anderson execute(i, all_tests + j); 86f8c6c2cfSJonathan Anderson break; 87f8c6c2cfSJonathan Anderson } 88f8c6c2cfSJonathan Anderson } 89f8c6c2cfSJonathan Anderson 90f8c6c2cfSJonathan Anderson if (found == 0) 91f8c6c2cfSJonathan Anderson errx(-1, "No such test '%s'", argv[i]); 92f8c6c2cfSJonathan Anderson } 93f8c6c2cfSJonathan Anderson 94f8c6c2cfSJonathan Anderson return (0); 95f8c6c2cfSJonathan Anderson } 96f8c6c2cfSJonathan Anderson 97f8c6c2cfSJonathan Anderson int 98f8c6c2cfSJonathan Anderson execute(int id, struct test *t) { 99f8c6c2cfSJonathan Anderson int result; 100f8c6c2cfSJonathan Anderson 101f8c6c2cfSJonathan Anderson pid_t pid = fork(); 102f8c6c2cfSJonathan Anderson if (pid < 0) 103f8c6c2cfSJonathan Anderson err(-1, "fork"); 104f8c6c2cfSJonathan Anderson if (pid) { 105f8c6c2cfSJonathan Anderson /* Parent: wait for result from child. */ 106f8c6c2cfSJonathan Anderson int status; 107f8c6c2cfSJonathan Anderson while (waitpid(pid, &status, 0) != pid) {} 108f8c6c2cfSJonathan Anderson if (WIFEXITED(status)) 109f8c6c2cfSJonathan Anderson result = WEXITSTATUS(status); 110f8c6c2cfSJonathan Anderson else 111f8c6c2cfSJonathan Anderson result = FAILED; 112f8c6c2cfSJonathan Anderson } else { 113f8c6c2cfSJonathan Anderson /* Child process: run the test. */ 114f8c6c2cfSJonathan Anderson exit(t->t_run()); 115f8c6c2cfSJonathan Anderson } 116f8c6c2cfSJonathan Anderson 117f8c6c2cfSJonathan Anderson printf("%s %d - %s\n", 118f8c6c2cfSJonathan Anderson (result == PASSED) ? "ok" : "not ok", 119f8c6c2cfSJonathan Anderson id, t->t_name); 120f8c6c2cfSJonathan Anderson 121f8c6c2cfSJonathan Anderson return (result); 122ceb42a13SJonathan Anderson } 123