[tor-commits] [tor/master] New unit tests for options_create_directories().

nickm at torproject.org nickm at torproject.org
Thu Nov 21 12:49:28 UTC 2019


commit 3094651fa3c71429e8efb0e23087a78addd6728f
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Nov 19 11:52:10 2019 -0500

    New unit tests for options_create_directories().
---
 src/test/include.am         |   1 +
 src/test/test.c             |   1 +
 src/test/test.h             |   1 +
 src/test/test_options_act.c | 181 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 184 insertions(+)

diff --git a/src/test/include.am b/src/test/include.am
index bd7ab71a2..6697dbb17 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 90c0058be..292082d4f 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 967562890..45c22d70f 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 000000000..aaef1d911
--- /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
+};





More information about the tor-commits mailing list