示例#1
0
static
void
readlink_file(void)
{
	char buf[128];
	int fd, rv;

	fd = open_testfile("the question contains an invalid assumption");
	if (fd<0) {
		return;
	}
	close(fd);
	rv = readlink(TESTFILE, buf, sizeof(buf));
	report_test(rv, errno, EINVAL, "readlink on file");
	remove(TESTFILE);
}
示例#2
0
static
void
ftruncate_fd_device(void)
{
	int rv, fd;

	fd = open("null:", O_RDWR);
	if (fd<0) {
		warn("UH-OH: opening null: failed");
		return;
	}

	rv = ftruncate(fd, 6);
	report_test(rv, errno, EINVAL, "ftruncate on device");

	close(fd);
}
示例#3
0
static
void
ftruncate_size_neg(void)
{
	int rv, fd;

	fd = open_testfile(0);
	if (fd<0) {
		return;
	}

	rv = ftruncate(fd, -60);
	report_test(rv, errno, EINVAL, "ftruncate to negative size");

	close(fd);
	remove(TESTFILE);
}
示例#4
0
static
void
lseek_whence_inval(void)
{
	int fd, rv;

	fd = open_testfile(NULL);
	if (fd<0) {
		return;
	}

	rv = lseek(fd, 0, 3594);
	report_test(rv, errno, EINVAL, "lseek with invalid whence code");

	close(fd);
	remove(TESTFILE);
}
示例#5
0
static
void
lseek_fd_device(void)
{
	int fd, rv;

	fd = open("null:", O_RDONLY);
	if (fd<0) {
		warn("UH-OH: opening null: failed");
		return;
	}

	rv = lseek(fd, 309, SEEK_SET);
	report_test(rv, errno, ESPIPE, "lseek on device");

	close(fd);
}
示例#6
0
static
void
lseek_loc_negative(void)
{
	int fd, rv;

	fd = open_testfile(NULL);
	if (fd<0) {
		return;
	}

	rv = lseek(fd, -309, SEEK_SET);
	report_test(rv, errno, EINVAL, "lseek to negative offset");

	close(fd);
	remove(TESTFILE);
}
示例#7
0
static
void
wait_badstatus(void *ptr, const char *desc)
{
	int rv, pid, x;

	pid = fork();
	if (pid<0) {
		warn("UH-OH: fork failed");
		return;
	}
	if (pid==0) {
		exit(0);
	}

	rv = waitpid(pid, ptr, 0);
	report_test(rv, errno, EFAULT, desc);
	waitpid(pid, &x, 0);
}
示例#8
0
static
void
wait_badflags(void)
{
	int rv, x, pid;

	pid = fork();
	if (pid<0) {
		warn("UH-OH: fork failed");
		return;
	}
	if (pid==0) {
		exit(0);
	}

	rv = waitpid(pid, &x, 309429);
	report_test(rv, errno, EINVAL, "wait with bad flags");
	waitpid(pid, &x, 0);
}
示例#9
0
static
void
wait_nullstatus(void)
{
	pid_t pid, rv;
	int x;

	pid = fork();
	if (pid<0) {
		warn("UH-OH: fork failed");
		return;
	}
	if (pid==0) {
		exit(0);
	}

	/* POSIX explicitly says passing NULL for status is allowed */
	rv = waitpid(pid, NULL, 0);
	report_test(rv, errno, 0, "wait with NULL status");
	waitpid(pid, &x, 0);
}
示例#10
0
static
void
common_badpath(int (*func)(const char *path), int mk, int rm, const char *path,
	       const char *call, const char *pathdesc)
{
	char mydesc[128];
	int rv;

	if (mk) {
		if (create_testfile()<0) {
			return;
		}
	}

	snprintf(mydesc, sizeof(mydesc), "%s with %s path", call, pathdesc);
	rv = func(path);
	report_test(rv, errno, EFAULT, mydesc);

	if (mk || rm) {
		remove(TESTFILE);
	}
}
示例#11
0
int main(int argc, char **argv) {
    int c, exitcode = 0, num_cases = 0;
    const char *engine = NULL;
    const char *engine_args = NULL;
    const char *test_suite = NULL;
    engine_test_t *testcases = NULL;
    logger_descriptor = get_null_logger();

    /* Hack to remove the warning from C99 */
    union {
        GET_TESTS get_tests;
        void* voidptr;
    } my_get_test = {.get_tests = NULL };

    /* Hack to remove the warning from C99 */
    union {
        SETUP_SUITE setup_suite;
        void* voidptr;
    } my_setup_suite = {.setup_suite = NULL };

    /* Hack to remove the warning from C99 */
    union {
        TEARDOWN_SUITE teardown_suite;
        void* voidptr;
    } my_teardown_suite = {.teardown_suite = NULL };


    /* Use unbuffered stdio */
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    /* process arguments */
    while (-1 != (c = getopt(argc, argv,
          "h"  /* usage */
          "E:"  /* Engine to load */
          "e:"  /* Engine options */
          "T:"   /* Library with tests to load */
        ))) {
        switch (c) {
        case 'E':
            engine = optarg;
            break;
        case 'e':
            engine_args = optarg;
            break;
        case 'h':
            usage();
            return 0;
        case 'T':
            test_suite = optarg;
            break;
        default:
            fprintf(stderr, "Illegal argument \"%c\"\n", c);
            return 1;
        }
    }

    //validate args
    if (engine == NULL) {
        fprintf(stderr, "You must provide a path to the storage engine library.\n");
        return 1;
    }

    if (test_suite == NULL) {
        fprintf(stderr, "You must provide a path to the testsuite library.\n");
        return 1;
    }

    //load test_suite
    void* handle = dlopen(test_suite, RTLD_NOW | RTLD_LOCAL);
    if (handle == NULL) {
        const char *msg = dlerror();
        fprintf(stderr, "Failed to load testsuite %s: %s\n", test_suite, msg ? msg : "unknown error");
        return 1;
    }

    //get the test cases
    void *symbol = dlsym(handle, "get_tests");
    if (symbol == NULL) {
        const char *msg = dlerror();
        fprintf(stderr, "Could not find get_tests function in testsuite %s: %s\n", test_suite, msg ? msg : "unknown error");
        return 1;
    }
    my_get_test.voidptr = symbol;
    testcases = (*my_get_test.get_tests)();

    //set up the suite if needed
    struct test_harness harness = { .default_engine_cfg = engine_args,
                                    .engine_path = engine,
                                    .reload_engine = reload_engine,
                                    .start_engine = start_your_engines,
                                    .create_cookie = create_mock_cookie,
                                    .destroy_cookie = destroy_mock_cookie,
                                    .set_ewouldblock_handling = mock_set_ewouldblock_handling,
                                    .lock_cookie = lock_mock_cookie,
                                    .unlock_cookie = unlock_mock_cookie,
                                    .waitfor_cookie = waitfor_mock_cookie};
    symbol = dlsym(handle, "setup_suite");
    if (symbol != NULL) {
        my_setup_suite.voidptr = symbol;
        if (!(*my_setup_suite.setup_suite)(&harness)) {
            fprintf(stderr, "Failed to set up test suite %s \n", test_suite);
            return 1;
        }
    }


    for (num_cases = 0; testcases[num_cases].name; num_cases++) {
        /* Just counting */
    }

    printf("1..%d\n", num_cases);

    int i;
    for (i = 0; testcases[i].name; i++) {
        printf("Running %s... ", testcases[i].name);
        fflush(stdout);
        exitcode += report_test(run_test(testcases[i], engine, engine_args));
    }

    //tear down the suite if needed
    symbol = dlsym(handle, "teardown_suite");
    if (symbol != NULL) {
        my_teardown_suite.voidptr = symbol;
        if (!(*my_teardown_suite.teardown_suite)()) {
            fprintf(stderr, "Failed to teardown up test suite %s \n", test_suite);
        }
    }

    return exitcode;
}
示例#12
0
static
void
lseek_file_stdin(void)
{
	int fd, fd2, rv, status;
	const char slogan[] = "There ain't no such thing as a free lunch";
	size_t len = strlen(slogan);
	pid_t pid;

	/* fork so we don't affect our own stdin */
	pid = fork();
	if (pid<0) {
		warn("UH-OH: fork failed");
		return;
	}
	else if (pid!=0) {
		/* parent */
		rv = waitpid(pid, &status, 0);
		if (rv<0) {
			warn("UH-OH: waitpid failed");
		}
		if (WIFSIGNALED(status)) {
			warn("UH-OH: subprocess exited with signal %d",
			     WTERMSIG(status));
		}
		else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
			warn("UH-OH: subprocess exited with code %d",
			     WEXITSTATUS(status));
		}
		return;
	}

	/* child */

	fd = open_testfile(NULL);
	if (fd<0) {
		_exit(0);
	}

	/*
	 * Move file to stdin.
	 * Use stdin (rather than stdout or stderr) to maximize the
	 * chances of detecting any special-case handling of fds 0-2.
	 * (Writing to stdin is fine as long as it's open for write,
	 * and it will be.)
	 */
	fd2 = dup2(fd, STDIN_FILENO);
	if (fd2<0) {
		warn("UH-OH: dup2 to stdin failed");
		close(fd);
		remove(TESTFILE);
		_exit(0);
	}
	if (fd2 != STDIN_FILENO) {
		warn("UH-OH: dup2 returned wrong file handle");
		close(fd);
		remove(TESTFILE);
		_exit(0);
	}
	close(fd);

	rv = write(STDIN_FILENO, slogan, len);
	if (rv<0) {
		warn("UH-OH: write to %s (via stdin) failed", TESTFILE);
		remove(TESTFILE);
		_exit(0);
	}

	if ((unsigned)rv != len) {
		warnx("UH-OH: write to %s (via stdin) got short count",
		      TESTFILE);
		remove(TESTFILE);
		_exit(0);
	}

	rv = lseek(STDIN_FILENO, 0, SEEK_SET);
	report_test(rv, errno, 0, "lseek stdin when open on file (try 1)");

	rv = lseek(STDIN_FILENO, 0, SEEK_END);
	report_test(rv, errno, 0, "lseek stdin when open on file (try 2)");

	remove(TESTFILE);
	_exit(0);
}
示例#13
0
int main(int argc, char **argv) {
    int c, exitcode = 0, num_cases = 0, timeout = 0, loop_count = 0;
    bool verbose = false;
    bool quiet = false;
    bool dot = false;
    bool loop = false;
    bool terminate_on_error = false;
    const char *engine = NULL;
    const char *engine_args = NULL;
    const char *test_suite = NULL;
    const char *test_case = NULL;
    engine_test_t *testcases = NULL;
    logger_descriptor = get_null_logger();

    /* Hack to remove the warning from C99 */
    union {
        GET_TESTS get_tests;
        void* voidptr;
    } my_get_test = {.get_tests = NULL };

    /* Hack to remove the warning from C99 */
    union {
        SETUP_SUITE setup_suite;
        void* voidptr;
    } my_setup_suite = {.setup_suite = NULL };

    /* Hack to remove the warning from C99 */
    union {
        TEARDOWN_SUITE teardown_suite;
        void* voidptr;
    } my_teardown_suite = {.teardown_suite = NULL };

    color_enabled = getenv("TESTAPP_ENABLE_COLOR") != NULL;

    /* Use unbuffered stdio */
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    setup_alarm_handler();

    /* process arguments */
    while (-1 != (c = getopt(argc, argv,
          "h"  /* usage */
          "E:" /* Engine to load */
          "e:" /* Engine options */
          "T:" /* Library with tests to load */
          "t:" /* Timeout */
          "L"  /* Loop until failure */
          "q"  /* Be more quiet (only report failures) */
          "."  /* dot mode. */
          "n:"  /* test case to run */
          "v" /* verbose output */
          "Z"  /* Terminate on first error */
        ))) {
        switch (c) {
        case 'E':
            engine = optarg;
            break;
        case 'e':
            engine_args = optarg;
            break;
        case 'h':
            usage();
            return 0;
        case 'T':
            test_suite = optarg;
            break;
        case 't':
            timeout = atoi(optarg);
            break;
        case 'L':
            loop = true;
            break;
        case 'n':
            test_case = optarg;
            break;
        case 'v' :
            verbose = true;
            break;
        case 'q':
            quiet = true;
            break;
        case '.':
            dot = true;
            break;
        case 'Z' :
            terminate_on_error = true;
            break;
        default:
            fprintf(stderr, "Illegal argument \"%c\"\n", c);
            return 1;
        }
    }

    //validate args
    if (engine == NULL) {
        fprintf(stderr, "You must provide a path to the storage engine library.\n");
        return 1;
    }

    if (test_suite == NULL) {
        fprintf(stderr, "You must provide a path to the testsuite library.\n");
        return 1;
    }

    //load test_suite
    void* handle = dlopen(test_suite, RTLD_NOW | RTLD_LOCAL);
    if (handle == NULL) {
        const char *msg = dlerror();
        fprintf(stderr, "Failed to load testsuite %s: %s\n", test_suite, msg ? msg : "unknown error");
        return 1;
    }

    //get the test cases
    void *symbol = dlsym(handle, "get_tests");
    if (symbol == NULL) {
        const char *msg = dlerror();
        fprintf(stderr, "Could not find get_tests function in testsuite %s: %s\n", test_suite, msg ? msg : "unknown error");
        return 1;
    }
    my_get_test.voidptr = symbol;
    testcases = (*my_get_test.get_tests)();

    //set up the suite if needed
    struct test_harness harness = { .default_engine_cfg = engine_args,
                                    .engine_path = engine,
                                    .reload_engine = reload_engine,
                                    .start_engine = start_your_engines,
                                    .create_cookie = create_mock_cookie,
                                    .destroy_cookie = destroy_mock_cookie,
                                    .set_ewouldblock_handling = mock_set_ewouldblock_handling,
                                    .lock_cookie = lock_mock_cookie,
                                    .unlock_cookie = unlock_mock_cookie,
                                    .waitfor_cookie = waitfor_mock_cookie,
                                    .time_travel = mock_time_travel,
                                    .get_current_testcase = get_current_testcase };
    symbol = dlsym(handle, "setup_suite");
    if (symbol != NULL) {
        my_setup_suite.voidptr = symbol;
        if (!(*my_setup_suite.setup_suite)(&harness)) {
            fprintf(stderr, "Failed to set up test suite %s \n", test_suite);
            return 1;
        }
    }


    for (num_cases = 0; testcases[num_cases].name; num_cases++) {
        /* Just counting */
    }

    if (!quiet) {
        printf("1..%d\n", num_cases);
    }

    do {
        int i;
        bool need_newline = false;
        for (i = 0; testcases[i].name; i++) {
            int error;
            if (test_case != NULL && strcmp(test_case, testcases[i].name) != 0)
                continue;
            if (!quiet) {
                printf("Running [%04d/%04d]: %s...",
                       i + num_cases * loop_count,
                       num_cases * (loop_count + 1),
                       testcases[i].name);
                fflush(stdout);
            } else if(dot) {
                printf(".");
                need_newline = true;
                /* Add a newline every few tests */
                if ((i+1) % 70 == 0) {
                    printf("\n");
                    need_newline = false;
                }
            }
            set_test_timeout(timeout);
            error = report_test(testcases[i].name,
                                run_test(testcases[i], engine, engine_args),
                                quiet, !verbose);
            clear_test_timeout();

            if (error != 0) {
                ++exitcode;
                if (terminate_on_error) {
                    exit(EXIT_FAILURE);
                }
            }
        }

        if (need_newline) {
            printf("\n");
        }
        ++loop_count;
    } while (loop && exitcode == 0);

    //tear down the suite if needed
    symbol = dlsym(handle, "teardown_suite");
    if (symbol != NULL) {
        my_teardown_suite.voidptr = symbol;
        if (!(*my_teardown_suite.teardown_suite)()) {
            fprintf(stderr, "Failed to teardown up test suite %s \n", test_suite);
        }
    }

    printf("# Passed %d of %d tests\n", num_cases - exitcode, num_cases);

    return exitcode;
}