diff options
Diffstat (limited to 'third_party/heimdal/lib/roken/dirent-test.c')
-rw-r--r-- | third_party/heimdal/lib/roken/dirent-test.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/roken/dirent-test.c b/third_party/heimdal/lib/roken/dirent-test.c new file mode 100644 index 0000000..dc4518a --- /dev/null +++ b/third_party/heimdal/lib/roken/dirent-test.c @@ -0,0 +1,278 @@ +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <direct.h> +#include <errno.h> +#include <io.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <string.h> +#include "dirent.h" + +/* Note that we create a known directory structure in a subdirectory + of the current directory to run our tests. */ + +#define TESTDIR "dirent-test-dir" + +const char * dir_entries[] = { + "A", + "B", + "C", + "CAA", + "CAAA", + "CABBBB", + "CAABBB.txt", + "A filename with spaces" +}; + +const char * entries_begin_with_C[] = { + "C", + "CAA", + "CAAA", + "CABBBB", + "CAABBB.txt" +}; + +const char * entries_end_with_A[] = { + "A", + "CAA", + "CAAA" +}; + +const int n_dir_entries = sizeof(dir_entries)/sizeof(dir_entries[0]); + +int teardown_test(void); + +void fail_test(const char * reason, ...) +{ + va_list args; + + va_start(args, reason); + vfprintf(stderr, reason, args); + va_end(args); + + fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno)); + teardown_test(); + abort(); +} + +void fail_test_nf(const char * format, ...) +{ + va_list args; + + fprintf(stderr, "FAIL:"); + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + fprintf(stderr, " : errno = %d (%s)\n", errno, strerror(errno)); +} + +int touch(const char * filename) +{ + int fd; + + fd = _open(filename, _O_CREAT, _S_IREAD| _S_IWRITE); + + if (fd == -1) + return -1; + + return _close(fd); +} + +int setup_test(void) +{ + int i; + + fprintf(stderr, "Creating test directory %s ...\n", TESTDIR); + + if (_mkdir(TESTDIR)) + fail_test("Can't create test directory \"" TESTDIR "\""); + + if (_chdir(TESTDIR)) + fail_test("Can't change to test directory"); + + for (i=0; i < n_dir_entries; i++) { + if (touch(dir_entries[i])) + fail_test("Can't create test file '%s'", dir_entries[i]); + } + + fprintf(stderr, "Done with test setup.\n"); + + return 0; +} + +int teardown_test(void) +{ + char dirname[_MAX_PATH]; + size_t len; + int i; + + printf ("Begin cleanup...\n"); + + if (_getcwd(dirname, sizeof(dirname)/sizeof(char)) != NULL && + + (len = strlen(dirname)) > sizeof(TESTDIR)/sizeof(char) && + + strcmp(dirname + len + 1 - sizeof(TESTDIR)/sizeof(char), TESTDIR) == 0) { + + fallthrough; + + } else { + /* did we create the directory? */ + + if (!_rmdir( TESTDIR )) { + fprintf(stderr, "Removed test directory\n"); + return 0; + } else { + if (errno == ENOTEMPTY) { + if (_chdir(TESTDIR)) { + fprintf(stderr, "Can't change to test directory. Aborting cleanup.\n"); + return -1; + } else { + fallthrough; + } + } else { + return -1; + } + } + } + + fprintf(stderr, "Cleaning up test directory %s ...\n", TESTDIR); + + for (i=0; i < n_dir_entries; i++) { + if (_unlink(dir_entries[i])) { + /* if the test setup failed, we expect this to happen for + at least some files */ + } + } + + if (_chdir("..")) { + fprintf(stderr, "Can't escape test directory. Giving in.\n"); + return -1; + } + + if (_rmdir( TESTDIR )) { + fprintf(stderr, "Can't remove test directory.\n"); + return -1; + } + + printf("Cleaned up test directory\n"); + return 0; +} + +int check_list(const char * filespec, const char ** list, int n, int expect_dot_and_dotdot) +{ + DIR * d; + struct dirent * e; + int n_found = 0; + int i; + int rv = 0; + int retry = 1; + + d = opendir(filespec); + if (d == NULL) { + fail_test_nf("opendir failed for [%s]", filespec); + return -1; + } + + printf("Checking filespec [%s]... ", filespec); + + retry: + while ((e = readdir(d)) != NULL) { + n_found ++; + + if (expect_dot_and_dotdot && + (strcmp(e->d_name, ".") == 0 || + strcmp(e->d_name, "..") == 0)) + continue; + + for (i=0; i < n; i++) { + if (strcmp(list[i], e->d_name) == 0) + break; + } + + if (i == n) { + fail_test_nf("Found unexpected entry [%s]", e->d_name); + rv = -1; + } + } + + if (n_found != n) { + fail_test_nf("Unexpected number of entries [%d]. Expected %d", n_found, n); + rv = -1; + } + + if (retry) { + retry = 0; + n_found = 0; + + rewinddir(d); + goto retry; + } + + if (closedir(d)) { + fail_test_nf("closedir() failed"); + } + + printf("done\n"); + + return rv; +} + +int run_tests() +{ + /* assumes that the test directory has been set up and we have + changed into the test directory. */ + + check_list("*", dir_entries, n_dir_entries + 2, 1); + check_list("*.*", dir_entries, n_dir_entries + 2, 1); + check_list("C*", entries_begin_with_C, sizeof(entries_begin_with_C)/sizeof(entries_begin_with_C[0]), 0); + check_list("*A", entries_end_with_A, sizeof(entries_end_with_A)/sizeof(entries_end_with_A[0]), 0); + + return 0; +} + +int main(int argc, char ** argv) +{ + if (setup_test()) + return 1; + + run_tests(); + + teardown_test(); + + return 0; +} |