138451Smsmith/*- 238451Smsmith * Copyright (c) 2008-2011 Robert N. M. Watson 338451Smsmith * Copyright (c) 2011 Jonathan Anderson 438451Smsmith * All rights reserved. 538451Smsmith * 638451Smsmith * Redistribution and use in source and binary forms, with or without 738451Smsmith * modification, are permitted provided that the following conditions 838451Smsmith * are met: 938451Smsmith * 1. Redistributions of source code must retain the above copyright 1038451Smsmith * notice, this list of conditions and the following disclaimer. 1138451Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1238451Smsmith * notice, this list of conditions and the following disclaimer in the 1338451Smsmith * documentation and/or other materials provided with the distribution. 1438451Smsmith * 1538451Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1638451Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1738451Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1838451Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1938451Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2038451Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2138451Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2238451Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2338451Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2438451Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2538451Smsmith * SUCH DAMAGE. 2638451Smsmith * 2738451Smsmith * $FreeBSD$ 2838451Smsmith */ 2938451Smsmith 3038451Smsmith#include <sys/cdefs.h> 3138451Smsmith__FBSDID("$FreeBSD$"); 3238451Smsmith 3338451Smsmith#include <sys/wait.h> 3438451Smsmith 3538451Smsmith#include <err.h> 3638451Smsmith#include <inttypes.h> 3738451Smsmith#include <stdio.h> 3884221Sdillon#include <stdlib.h> 3984221Sdillon#include <string.h> 4084221Sdillon#include <unistd.h> 4138451Smsmith 4238451Smsmith#include "cap_test.h" 4338451Smsmith 4438451Smsmith/* Initialize a named test. Requires test_NAME() function to be declared. */ 4538451Smsmith#define TEST_INIT(name) { #name, test_##name, FAILED } 4638451Smsmith 4738451Smsmith/* All of the tests that can be run. */ 4838451Smsmithstruct test all_tests[] = { 4938451Smsmith TEST_INIT(capmode), 5038451Smsmith TEST_INIT(capabilities), 5138451Smsmith TEST_INIT(fcntl), 5238451Smsmith TEST_INIT(pdfork), 5338451Smsmith TEST_INIT(pdkill), 5438451Smsmith TEST_INIT(relative), 5538451Smsmith TEST_INIT(sysctl), 5638451Smsmith}; 5738451Smsmithint test_count = sizeof(all_tests) / sizeof(struct test); 5838451Smsmith 5938451Smsmithint 6038451Smsmithmain(int argc, char *argv[]) 6138451Smsmith{ 6238451Smsmith 6338451Smsmith /* 6492913Sobrien * If no tests have been specified at the command line, run them all. 6592913Sobrien */ 6638451Smsmith if (argc == 1) { 6738451Smsmith printf("1..%d\n", test_count); 6838451Smsmith 6938451Smsmith for (int i = 0; i < test_count; i++) 7038451Smsmith execute(i + 1, all_tests + i); 7138451Smsmith return (0); 7238451Smsmith } 7338451Smsmith 7438451Smsmith /* 7538451Smsmith * Otherwise, run only the specified tests. 7638451Smsmith */ 7738451Smsmith printf("1..%d\n", argc - 1); 7838451Smsmith for (int i = 1; i < argc; i++) 7938451Smsmith { 8038451Smsmith int found = 0; 8138451Smsmith for (int j = 0; j < test_count; j++) { 8238451Smsmith if (strncmp(argv[i], all_tests[j].t_name, 8338451Smsmith strlen(argv[i])) == 0) { 8438451Smsmith found = 1; 8538451Smsmith execute(i, all_tests + j); 8638451Smsmith break; 8738451Smsmith } 8838451Smsmith } 8938451Smsmith 9038451Smsmith if (found == 0) 9138451Smsmith errx(-1, "No such test '%s'", argv[i]); 9238451Smsmith } 9338451Smsmith 9492913Sobrien return (0); 9592913Sobrien} 9692913Sobrien 9738451Smsmithint 9892913Sobrienexecute(int id, struct test *t) { 9938451Smsmith int result; 10092913Sobrien 10192913Sobrien pid_t pid = fork(); 10238451Smsmith if (pid < 0) 10338451Smsmith err(-1, "fork"); 10438451Smsmith if (pid) { 10538451Smsmith /* Parent: wait for result from child. */ 10638451Smsmith int status; 10738451Smsmith while (waitpid(pid, &status, 0) != pid) {} 10838451Smsmith if (WIFEXITED(status)) 10938451Smsmith result = WEXITSTATUS(status); 11038451Smsmith else 11138451Smsmith result = FAILED; 11238451Smsmith } else { 11338451Smsmith /* Child process: run the test. */ 11438451Smsmith exit(t->t_run()); 11538451Smsmith } 11638451Smsmith 11738451Smsmith printf("%s %d - %s\n", 11838451Smsmith (result == PASSED) ? "ok" : "not ok", 11938451Smsmith id, t->t_name); 12038451Smsmith 12138451Smsmith return (result); 12238451Smsmith} 12338451Smsmith