diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-11-19 11:52:10 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-11-20 09:26:47 -0500 |
commit | 3094651fa3c71429e8efb0e23087a78addd6728f (patch) | |
tree | d97c0bcebb64c4d8c2efd2fdd98aae18ed8fc63d /src/test | |
parent | 9951afe177107c9bae5b1731bcb01c59c68e5ebc (diff) | |
download | tor-3094651fa3c71429e8efb0e23087a78addd6728f.tar.gz tor-3094651fa3c71429e8efb0e23087a78addd6728f.zip |
New unit tests for options_create_directories().
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/include.am | 1 | ||||
-rw-r--r-- | src/test/test.c | 1 | ||||
-rw-r--r-- | src/test/test.h | 1 | ||||
-rw-r--r-- | src/test/test_options_act.c | 181 |
4 files changed, 184 insertions, 0 deletions
diff --git a/src/test/include.am b/src/test/include.am index bd7ab71a20..6697dbb171 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -177,6 +177,7 @@ src_test_test_SOURCES += \ src/test/test_oom.c \ src/test/test_oos.c \ src/test/test_options.c \ + src/test/test_options_act.c \ src/test/test_pem.c \ src/test/test_periodic_event.c \ src/test/test_policy.c \ diff --git a/src/test/test.c b/src/test/test.c index 90c0058be8..292082d4fb 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -732,6 +732,7 @@ struct testgroup_t testgroups[] = { { "oom/", oom_tests }, { "oos/", oos_tests }, { "options/", options_tests }, + { "options/act/", options_act_tests }, { "parsecommon/", parsecommon_tests }, { "periodic-event/" , periodic_event_tests }, { "policy/" , policy_tests }, diff --git a/src/test/test.h b/src/test/test.h index 967562890f..45c22d70f7 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -252,6 +252,7 @@ extern struct testcase_t nodelist_tests[]; extern struct testcase_t oom_tests[]; extern struct testcase_t oos_tests[]; extern struct testcase_t options_tests[]; +extern struct testcase_t options_act_tests[]; extern struct testcase_t parsecommon_tests[]; extern struct testcase_t pem_tests[]; extern struct testcase_t periodic_event_tests[]; diff --git a/src/test/test_options_act.c b/src/test/test_options_act.c new file mode 100644 index 0000000000..aaef1d9110 --- /dev/null +++ b/src/test/test_options_act.c @@ -0,0 +1,181 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#define CONFIG_PRIVATE +#include "core/or/or.h" +#include "app/config/config.h" + +#include "test/test.h" +#include "test/log_test_helpers.h" +#include "test/test_helpers.h" + +#ifndef _WIN32 +#include <sys/stat.h> + +/** + * Check whether fname is readable. On success set + * *<b>is_group_readable_out</b> to as appropriate and return 0. On failure + * return -1. + */ +static int +get_file_mode(const char *fname, unsigned *permissions_out) +{ + struct stat st; + int r = stat(fname, &st); + if (r < 0) + return -1; + *permissions_out = (unsigned) st.st_mode; + return 0; +} +#define assert_mode(fn,mask,expected) STMT_BEGIN \ + unsigned mode_; \ + int tmp_ = get_file_mode((fn), &mode_); \ + if (tmp_ < 0) { \ + TT_DIE(("Couldn't stat %s: %s", (fn), strerror(errno))); \ + } \ + if ((mode_ & (mask)) != (expected)) { \ + TT_DIE(("Bad mode %o on %s", mode_, (fn))); \ + } \ + STMT_END +#else +/* "group-readable" isn't meaningful on windows */ +#define assert_mode(fn,mask,expected) STMT_NIL +#endif + +static or_options_t *mock_opts; +static const or_options_t * +mock_get_options(void) +{ + return mock_opts; +} + +static void +test_options_act_create_dirs(void *arg) +{ + (void)arg; + MOCK(get_options, mock_get_options); + char *msg = NULL; + or_options_t *opts = mock_opts = options_new(); + + /* We're testing options_create_directories(), which assumes that + validate_data_directories() has already been called, and all of + KeyDirectory, DataDirectory, and CacheDirectory are set. */ + + /* Success case 1: all directories are the default */ + char *fn; + fn = tor_strdup(get_fname_rnd("ddir")); + opts->DataDirectory = tor_strdup(fn); + opts->CacheDirectory = tor_strdup(fn); + tor_asprintf(&opts->KeyDirectory, "%s/keys", fn); + opts->DataDirectoryGroupReadable = 1; + opts->CacheDirectoryGroupReadable = -1; /* default. */ + int r = options_create_directories(&msg); + tt_int_op(r, OP_EQ, 0); + tt_ptr_op(msg, OP_EQ, NULL); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->DataDirectory)); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->CacheDirectory)); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->KeyDirectory)); + assert_mode(opts->DataDirectory, 0777, 0750); + assert_mode(opts->KeyDirectory, 0777, 0700); + tor_free(fn); + tor_free(opts->KeyDirectory); + or_options_free(opts); + + /* Success case 2: all directories are different. */ + opts = mock_opts = options_new(); + opts->DataDirectory = tor_strdup(get_fname_rnd("ddir")); + opts->CacheDirectory = tor_strdup(get_fname_rnd("cdir")); + opts->KeyDirectory = tor_strdup(get_fname_rnd("kdir")); + opts->CacheDirectoryGroupReadable = 1; // cache directory group readable + r = options_create_directories(&msg); + tt_int_op(r, OP_EQ, 0); + tt_ptr_op(msg, OP_EQ, NULL); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->DataDirectory)); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->CacheDirectory)); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->KeyDirectory)); + assert_mode(opts->DataDirectory, 0777, 0700); + assert_mode(opts->KeyDirectory, 0777, 0700); + assert_mode(opts->CacheDirectory, 0777, 0750); + tor_free(fn); + or_options_free(opts); + + /* Success case 3: all directories are the same. */ + opts = mock_opts = options_new(); + fn = tor_strdup(get_fname_rnd("ddir")); + opts->DataDirectory = tor_strdup(fn); + opts->CacheDirectory = tor_strdup(fn); + opts->KeyDirectory = tor_strdup(fn); + opts->DataDirectoryGroupReadable = 1; + opts->CacheDirectoryGroupReadable = -1; /* default. */ +#if 1 + /* Bug 27992: this setting shouldn't be needed, but for now it is, in the + * unusual case that DataDirectory == KeyDirectory */ + opts->KeyDirectoryGroupReadable = 1; +#endif + r = options_create_directories(&msg); + tt_int_op(r, OP_EQ, 0); + tt_ptr_op(msg, OP_EQ, NULL); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->DataDirectory)); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->CacheDirectory)); + tt_int_op(FN_DIR, OP_EQ, file_status(opts->KeyDirectory)); + assert_mode(opts->DataDirectory, 0777, 0750); + assert_mode(opts->KeyDirectory, 0777, 0750); + assert_mode(opts->CacheDirectory, 0777, 0750); + tor_free(fn); + or_options_free(opts); + + /* Failure case 1: Can't make datadir. */ + opts = mock_opts = options_new(); + opts->DataDirectory = tor_strdup(get_fname_rnd("ddir")); + opts->CacheDirectory = tor_strdup(get_fname_rnd("cdir")); + opts->KeyDirectory = tor_strdup(get_fname_rnd("kdir")); + write_str_to_file(opts->DataDirectory, "foo", 0); + r = options_create_directories(&msg); + tt_int_op(r, OP_LT, 0); + tt_assert(!strcmpstart(msg, "Couldn't create private data directory")); + or_options_free(opts); + tor_free(msg); + + /* Failure case 2: Can't make keydir. */ + opts = mock_opts = options_new(); + opts->DataDirectory = tor_strdup(get_fname_rnd("ddir")); + opts->CacheDirectory = tor_strdup(get_fname_rnd("cdir")); + opts->KeyDirectory = tor_strdup(get_fname_rnd("kdir")); + write_str_to_file(opts->KeyDirectory, "foo", 0); + r = options_create_directories(&msg); + tt_int_op(r, OP_LT, 0); + tt_assert(!strcmpstart(msg, "Couldn't create private data directory")); + or_options_free(opts); + tor_free(msg); + + /* Failure case 3: Can't make cachedir. */ + opts = mock_opts = options_new(); + opts->DataDirectory = tor_strdup(get_fname_rnd("ddir")); + opts->CacheDirectory = tor_strdup(get_fname_rnd("cdir")); + opts->KeyDirectory = tor_strdup(get_fname_rnd("kdir")); + write_str_to_file(opts->CacheDirectory, "foo", 0); + r = options_create_directories(&msg); + tt_int_op(r, OP_LT, 0); + tt_assert(!strcmpstart(msg, "Couldn't create private data directory")); + tor_free(fn); + or_options_free(opts); + tor_free(msg); + + done: + UNMOCK(get_options); + or_options_free(opts); + mock_opts = NULL; + tor_free(fn); + tor_free(msg); +} + +#ifndef COCCI +#define T(name) { #name, test_options_act_##name, TT_FORK, NULL, NULL } +#endif + +struct testcase_t options_act_tests[] = { + T(create_dirs), + END_OF_TESTCASES +}; |