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> 36*a9d2f8d8SRobert 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), 52f8c6c2cfSJonathan Anderson TEST_INIT(sysctl), 53f8c6c2cfSJonathan Anderson }; 54f8c6c2cfSJonathan Anderson size_t test_count = sizeof(all_tests) / sizeof(struct test); 55f8c6c2cfSJonathan Anderson 56ceb42a13SJonathan Anderson int 57ceb42a13SJonathan Anderson main(int argc, char *argv[]) 58ceb42a13SJonathan Anderson { 59f8c6c2cfSJonathan Anderson 60ceb42a13SJonathan Anderson /* 61f8c6c2cfSJonathan Anderson * If no tests have been specified at the command line, run them all. 62ceb42a13SJonathan Anderson */ 63f8c6c2cfSJonathan Anderson if (argc == 1) { 64*a9d2f8d8SRobert Watson printf("1..%ju\n", (uintmax_t)test_count); 65f8c6c2cfSJonathan Anderson 66f8c6c2cfSJonathan Anderson for (size_t i = 0; i < test_count; i++) 67f8c6c2cfSJonathan Anderson execute(i + 1, all_tests + i); 68f8c6c2cfSJonathan Anderson return (0); 69f8c6c2cfSJonathan Anderson } 70f8c6c2cfSJonathan Anderson 71f8c6c2cfSJonathan Anderson /* 72f8c6c2cfSJonathan Anderson * Otherwise, run only the specified tests. 73f8c6c2cfSJonathan Anderson */ 74f8c6c2cfSJonathan Anderson printf("1..%d\n", argc - 1); 75f8c6c2cfSJonathan Anderson for (int i = 1; i < argc; i++) 76f8c6c2cfSJonathan Anderson { 77f8c6c2cfSJonathan Anderson int found = 0; 78f8c6c2cfSJonathan Anderson for (size_t j = 0; j < test_count; j++) { 79f8c6c2cfSJonathan Anderson if (strncmp(argv[i], all_tests[j].t_name, 80f8c6c2cfSJonathan Anderson strlen(argv[i])) == 0) { 81f8c6c2cfSJonathan Anderson found = 1; 82f8c6c2cfSJonathan Anderson execute(i, all_tests + j); 83f8c6c2cfSJonathan Anderson break; 84f8c6c2cfSJonathan Anderson } 85f8c6c2cfSJonathan Anderson } 86f8c6c2cfSJonathan Anderson 87f8c6c2cfSJonathan Anderson if (found == 0) 88f8c6c2cfSJonathan Anderson errx(-1, "No such test '%s'", argv[i]); 89f8c6c2cfSJonathan Anderson } 90f8c6c2cfSJonathan Anderson 91f8c6c2cfSJonathan Anderson return (0); 92f8c6c2cfSJonathan Anderson } 93f8c6c2cfSJonathan Anderson 94f8c6c2cfSJonathan Anderson int 95f8c6c2cfSJonathan Anderson execute(int id, struct test *t) { 96f8c6c2cfSJonathan Anderson int result; 97f8c6c2cfSJonathan Anderson 98f8c6c2cfSJonathan Anderson pid_t pid = fork(); 99f8c6c2cfSJonathan Anderson if (pid < 0) 100f8c6c2cfSJonathan Anderson err(-1, "fork"); 101f8c6c2cfSJonathan Anderson if (pid) { 102f8c6c2cfSJonathan Anderson /* Parent: wait for result from child. */ 103f8c6c2cfSJonathan Anderson int status; 104f8c6c2cfSJonathan Anderson while (waitpid(pid, &status, 0) != pid) {} 105f8c6c2cfSJonathan Anderson if (WIFEXITED(status)) 106f8c6c2cfSJonathan Anderson result = WEXITSTATUS(status); 107f8c6c2cfSJonathan Anderson else 108f8c6c2cfSJonathan Anderson result = FAILED; 109f8c6c2cfSJonathan Anderson } else { 110f8c6c2cfSJonathan Anderson /* Child process: run the test. */ 111f8c6c2cfSJonathan Anderson exit(t->t_run()); 112f8c6c2cfSJonathan Anderson } 113f8c6c2cfSJonathan Anderson 114f8c6c2cfSJonathan Anderson printf("%s %d - %s\n", 115f8c6c2cfSJonathan Anderson (result == PASSED) ? "ok" : "not ok", 116f8c6c2cfSJonathan Anderson id, t->t_name); 117f8c6c2cfSJonathan Anderson 118f8c6c2cfSJonathan Anderson return (result); 119ceb42a13SJonathan Anderson } 120