diff options
Diffstat (limited to 'src/test')
19 files changed, 307 insertions, 18 deletions
diff --git a/src/test/conf_examples/bridgeauth_1/expected b/src/test/conf_examples/bridgeauth_1/expected new file mode 100644 index 0000000000..d43aaf2c8b --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/expected @@ -0,0 +1,7 @@ +Address 198.51.100.123 +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 +ContactInfo tor_parse_test@example.com +DirPort 80 +Nickname Unnamed +ORPort 443 diff --git a/src/test/conf_examples/bridgeauth_1/expected_no_dirauth b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth new file mode 100644 index 0000000000..d43aaf2c8b --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth @@ -0,0 +1,7 @@ +Address 198.51.100.123 +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 +ContactInfo tor_parse_test@example.com +DirPort 80 +Nickname Unnamed +ORPort 443 diff --git a/src/test/conf_examples/bridgeauth_1/expected_no_dirauth_relay b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth_relay new file mode 100644 index 0000000000..e059d79971 --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth_relay @@ -0,0 +1,6 @@ +Address 198.51.100.123 +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 +ContactInfo tor_parse_test@example.com +DirPort 80 +ORPort 443 diff --git a/src/test/conf_examples/bridgeauth_1/torrc b/src/test/conf_examples/bridgeauth_1/torrc new file mode 100644 index 0000000000..740bc6c2eb --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/torrc @@ -0,0 +1,8 @@ +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 + +ContactInfo tor_parse_test@example.com + +Address 198.51.100.123 +ORPort 443 +DirPort 80 diff --git a/src/test/conf_examples/dirauth_1/expected b/src/test/conf_examples/dirauth_1/expected new file mode 100644 index 0000000000..901f7d947f --- /dev/null +++ b/src/test/conf_examples/dirauth_1/expected @@ -0,0 +1,8 @@ +Address 192.0.2.1 +AuthoritativeDirectory 1 +ContactInfo tor_parse_test@example.net +DirPort 9030 +DownloadExtraInfo 1 +Nickname Unnamed +ORPort 9001 +V3AuthoritativeDirectory 1 diff --git a/src/test/conf_examples/dirauth_1/expected_no_dirauth b/src/test/conf_examples/dirauth_1/expected_no_dirauth new file mode 100644 index 0000000000..f006c6f8f2 --- /dev/null +++ b/src/test/conf_examples/dirauth_1/expected_no_dirauth @@ -0,0 +1,7 @@ +Address 192.0.2.1 +AuthoritativeDirectory 1 +ContactInfo tor_parse_test@example.net +DirPort 9030 +Nickname Unnamed +ORPort 9001 +V3AuthoritativeDirectory 1 diff --git a/src/test/conf_examples/dirauth_1/expected_no_dirauth_relay b/src/test/conf_examples/dirauth_1/expected_no_dirauth_relay new file mode 100644 index 0000000000..4b9ad49bb2 --- /dev/null +++ b/src/test/conf_examples/dirauth_1/expected_no_dirauth_relay @@ -0,0 +1,6 @@ +Address 192.0.2.1 +AuthoritativeDirectory 1 +ContactInfo tor_parse_test@example.net +DirPort 9030 +ORPort 9001 +V3AuthoritativeDirectory 1 diff --git a/src/test/conf_examples/dirauth_1/torrc b/src/test/conf_examples/dirauth_1/torrc new file mode 100644 index 0000000000..b870e6e8e0 --- /dev/null +++ b/src/test/conf_examples/dirauth_1/torrc @@ -0,0 +1,8 @@ +AuthoritativeDirectory 1 +V3AuthoritativeDirectory 1 + +ContactInfo tor_parse_test@example.net + +Address 192.0.2.1 +ORPort 9001 +DirPort 9030 diff --git a/src/test/conf_examples/ops_1/expected_no_dirauth_relay b/src/test/conf_examples/ops_1/expected_no_dirauth_relay new file mode 100644 index 0000000000..2bb9bfa132 --- /dev/null +++ b/src/test/conf_examples/ops_1/expected_no_dirauth_relay @@ -0,0 +1 @@ +ORPort 1000 diff --git a/src/test/conf_examples/ops_3/expected_no_dirauth_relay b/src/test/conf_examples/ops_3/expected_no_dirauth_relay new file mode 100644 index 0000000000..93dea50eeb --- /dev/null +++ b/src/test/conf_examples/ops_3/expected_no_dirauth_relay @@ -0,0 +1,2 @@ +ORPort 9999 +ORPort 1000 diff --git a/src/test/conf_examples/ops_4/expected_no_dirauth_relay b/src/test/conf_examples/ops_4/expected_no_dirauth_relay new file mode 100644 index 0000000000..56b3a5b71f --- /dev/null +++ b/src/test/conf_examples/ops_4/expected_no_dirauth_relay @@ -0,0 +1 @@ +ORPort 9099 diff --git a/src/test/conf_examples/ops_5/expected_no_dirauth_relay b/src/test/conf_examples/ops_5/expected_no_dirauth_relay new file mode 100644 index 0000000000..834a785090 --- /dev/null +++ b/src/test/conf_examples/ops_5/expected_no_dirauth_relay @@ -0,0 +1,2 @@ +ORPort 9000 +ORPort 9099 diff --git a/src/test/test_controller.c b/src/test/test_controller.c index 55eb79e448..8d9c3e8eaf 100644 --- a/src/test/test_controller.c +++ b/src/test/test_controller.c @@ -27,6 +27,7 @@ #include "feature/dirclient/download_status_st.h" #include "feature/nodelist/microdesc_st.h" #include "feature/nodelist/node_st.h" +#include "feature/dircache/dirserv.c" typedef struct { const char *input; @@ -1691,6 +1692,138 @@ test_download_status_bridge(void *arg) return; } +/** Mock cached consensus */ +static cached_dir_t *mock_ns_consensus_cache; +static cached_dir_t *mock_microdesc_consensus_cache; + +/** Mock the function that retrieves consensus from cache. These use a + * global variable so that they can be cleared from within the test. + * The actual code retains the pointer to the consensus data, but + * we are doing this here, to prevent memory leaks + * from within the tests */ +static cached_dir_t * +mock_dirserv_get_consensus(const char *flavor_name) +{ + if (!strcmp(flavor_name, "ns")) { + mock_ns_consensus_cache = tor_malloc_zero(sizeof(cached_dir_t)); + mock_ns_consensus_cache->dir = tor_strdup("mock_ns_consensus"); + return mock_ns_consensus_cache; + } else { + mock_microdesc_consensus_cache = tor_malloc_zero(sizeof(cached_dir_t)); + mock_microdesc_consensus_cache->dir = tor_strdup( + "mock_microdesc_consensus"); + return mock_microdesc_consensus_cache; + } +} + +/** Mock the function that retrieves consensuses + * from a files in the directory. */ +static tor_mmap_t * +mock_tor_mmap_file(const char* filename) +{ + tor_mmap_t *res; + res = tor_malloc_zero(sizeof(tor_mmap_t)); + if (strstr(filename, "cached-consensus") != NULL) { + res->data = "mock_ns_consensus"; + } else if (strstr(filename, "cached-microdesc-consensus") != NULL) { + res->data = "mock_microdesc_consensus"; + } else { + res->data = "."; + } + res->size = strlen(res->data); + return res; +} + +/** Mock the function that clears file data + * loaded into the memory */ +static int +mock_tor_munmap_file(tor_mmap_t *handle) +{ + tor_free(handle); + return 0; +} + +static void +test_getinfo_helper_current_consensus_from_file(void *arg) +{ + /* We just need one of these to pass, it doesn't matter what's in it */ + control_connection_t dummy; + /* Get results out */ + char *answer = NULL; + const char *errmsg = NULL; + + (void)arg; + + MOCK(tor_mmap_file, mock_tor_mmap_file); + MOCK(tor_munmap_file, mock_tor_munmap_file); + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_ns_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + tor_free(answer); + errmsg = NULL; + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus-microdesc", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_microdesc_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + errmsg = NULL; + + done: + tor_free(answer); + UNMOCK(tor_mmap_file); + UNMOCK(tor_munmap_file); + return; +} + +static void +test_getinfo_helper_current_consensus_from_cache(void *arg) +{ + /* We just need one of these to pass, it doesn't matter what's in it */ + control_connection_t dummy; + /* Get results out */ + char *answer = NULL; + const char *errmsg = NULL; + + (void)arg; + or_options_t *options = get_options_mutable(); + options->FetchUselessDescriptors = 1; + MOCK(dirserv_get_consensus, mock_dirserv_get_consensus); + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_ns_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + tor_free(answer); + tor_free(mock_ns_consensus_cache->dir); + tor_free(mock_ns_consensus_cache); + errmsg = NULL; + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus-microdesc", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_microdesc_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + tor_free(mock_microdesc_consensus_cache->dir); + tor_free(answer); + errmsg = NULL; + + done: + options->FetchUselessDescriptors = 0; + tor_free(answer); + tor_free(mock_microdesc_consensus_cache); + UNMOCK(dirserv_get_consensus); + return; +} + /** Set timeval to a mock date and time. This is necessary * to make tor_gettimeofday() mockable. */ static void @@ -1840,6 +1973,10 @@ struct testcase_t controller_tests[] = { NULL }, { "download_status_consensus", test_download_status_consensus, 0, NULL, NULL }, + {"getinfo_helper_current_consensus_from_cache", + test_getinfo_helper_current_consensus_from_cache, 0, NULL, NULL }, + {"getinfo_helper_current_consensus_from_file", + test_getinfo_helper_current_consensus_from_file, 0, NULL, NULL }, { "download_status_cert", test_download_status_cert, 0, NULL, NULL }, { "download_status_desc", test_download_status_desc, 0, NULL, NULL }, diff --git a/src/test/test_key_expiration.sh b/src/test/test_key_expiration.sh index 54abb4a2fa..9d42c1cc4c 100755 --- a/src/test/test_key_expiration.sh +++ b/src/test/test_key_expiration.sh @@ -28,6 +28,11 @@ else TOR_BINARY="${TESTING_TOR_BINARY}" fi +if "$TOR_BINARY" --list-modules | grep -q "relay: no"; then + echo "This test requires the relay module. Skipping." >&2 + exit 77 +fi + if [ $# -ge 1 ]; then dflt=0 else diff --git a/src/test/test_keygen.sh b/src/test/test_keygen.sh index cbdfd1909c..57df888274 100755 --- a/src/test/test_keygen.sh +++ b/src/test/test_keygen.sh @@ -28,7 +28,10 @@ else TOR_BINARY="${TESTING_TOR_BINARY}" fi - +if "$TOR_BINARY" --list-modules | grep -q "relay: no"; then + echo "This test requires the relay module. Skipping." >&2 + exit 77 +fi if [ $# -ge 1 ]; then dflt=0 diff --git a/src/test/test_parseconf.sh b/src/test/test_parseconf.sh index eeb80cdfa7..d46be5e5cd 100755 --- a/src/test/test_parseconf.sh +++ b/src/test/test_parseconf.sh @@ -36,6 +36,27 @@ # matched by some line in the output of "--verify-config", which must # fail. Exactly one of "expected" or "error" must be present, or the # test will fail. +# +# {expected,error}_no_${TOR_MODULES_DISABLED} -- If this file is present, +# then the outcome is different when some modules are disabled. If there +# is no result file matching the exact list of disabled modules, the +# standard result file is used. +# +# For example: +# A test that succeeds, regardless of any disabled modules: +# - expected +# A test that has a different result if the relay module is disabled +# (but the same result if just the dirauth module is disabled): +# - expected +# - expected_no_relay_dirauth +# A test that fails if the dirauth module is disabled: +# - expected +# - error_no_dirauth +# - error_no_relay_dirauth +# (Disabling the relay module also disables dirauth module. But we don't +# want to encode that knowledge in this test script, so we supply a +# separate result file for every combination of disabled modules that +# has a different result.) umask 077 set -e @@ -64,6 +85,11 @@ fi TOR_BINARY="$(abspath "$TOR_BINARY")" +TOR_MODULES_DISABLED="$("$TOR_BINARY" --list-modules | grep ": no" \ + | cut -d ":" -f1 | sort | tr "\n" "_")" +# Remove the last underscore, if there is one +TOR_MODULES_DISABLED=${TOR_MODULES_DISABLED%_} + # make a safe space for temporary files DATA_DIR=$(mktemp -d -t tor_parseconf_tests.XXXXXX) trap 'rm -rf "$DATA_DIR"' 0 @@ -125,12 +151,30 @@ for dir in "${EXAMPLEDIR}"/*; do CMDLINE="" fi - if test -f "./expected"; then - if test -f "./error"; then - echo "FAIL: Found both ${dir}/expected and ${dir}/error." - echo "(Only one of these files should exist.)" - exit $EXITCODE + # If tor has some modules disabled, search for a custom result file for + # the disabled modules + for suffix in "_no_$TOR_MODULES_DISABLED" ""; do + + if test -f "./expected${suffix}"; then + + # Check for broken configs + if test -f "./error${suffix}"; then + echo "FAIL: Found both ${dir}/expected${suffix}" + echo "and ${dir}/error${suffix}." + echo "(Only one of these files should exist.)" + exit $EXITCODE + fi + + EXPECTED="./expected${suffix}" + break + + elif test -f "./error${suffix}"; then + ERROR="./error${suffix}" + break fi + done + + if test -f "$EXPECTED"; then # This case should succeed: run dump-config and see if it does. @@ -141,7 +185,7 @@ for dir in "${EXAMPLEDIR}"/*; do | "${FILTER}" > "${DATA_DIR}/output.${testname}" \ || die "Failure: Tor exited." - if cmp "./expected" "${DATA_DIR}/output.${testname}">/dev/null ; then + if cmp "$EXPECTED" "${DATA_DIR}/output.${testname}">/dev/null ; then # Check round-trip. "${TOR_BINARY}" -f "${DATA_DIR}/output.${testname}" \ --defaults-torrc "${DATA_DIR}/empty" \ @@ -166,11 +210,11 @@ for dir in "${EXAMPLEDIR}"/*; do --verify-config \ ${CMDLINE} || true fi - diff -u "./expected" "${DATA_DIR}/output.${testname}" || /bin/true + diff -u "$EXPECTED" "${DATA_DIR}/output.${testname}" || /bin/true exit $EXITCODE fi - elif test -f "./error"; then + elif test -f "$ERROR"; then # This case should fail: run verify-config and see if it does. "${TOR_BINARY}" --verify-config \ @@ -180,7 +224,7 @@ for dir in "${EXAMPLEDIR}"/*; do > "${DATA_DIR}/output.${testname}" \ && die "Failure: Tor did not report an error." - expect_err="$(cat ./error)" + expect_err="$(cat $ERROR)" if grep "${expect_err}" "${DATA_DIR}/output.${testname}" >/dev/null; then echo "OK" else @@ -195,7 +239,7 @@ for dir in "${EXAMPLEDIR}"/*; do # This case is not actually configured with a success or a failure. # call that an error. - echo "FAIL: Did not find ${dir}/expected or ${dir}/error." + echo "FAIL: Did not find ${dir}/*expected or ${dir}/*error." exit $EXITCODE fi diff --git a/src/test/test_process_slow.c b/src/test/test_process_slow.c index 91252c725d..f311e8b293 100644 --- a/src/test/test_process_slow.c +++ b/src/test/test_process_slow.c @@ -328,8 +328,38 @@ test_callbacks_terminate(void *arg) process_free(process); } +static void +test_nonexistent_executable(void *arg) +{ + (void)arg; + + /* Process callback data. */ + process_data_t *process_data = process_data_new(); + + /* Setup our process. */ + process_t *process = process_new("binary-does-not-exist"); + process_set_data(process, process_data); + process_set_exit_callback(process, process_exit_callback); + + /* Run our process. */ + process_exec(process); + + /* Start our main loop. */ + run_main_loop(process_data); + + /* Ensure that the exit callback was actually called even though the binary + * did not exist. + */ + tt_assert(process_data->did_exit); + + done: + process_data_free(process_data); + process_free(process); +} + struct testcase_t slow_process_tests[] = { { "callbacks", test_callbacks, 0, NULL, NULL }, { "callbacks_terminate", test_callbacks_terminate, 0, NULL, NULL }, + { "nonexistent_executable", test_nonexistent_executable, 0, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_rebind.py b/src/test/test_rebind.py index 232b200326..c9b9200b2d 100644 --- a/src/test/test_rebind.py +++ b/src/test/test_rebind.py @@ -32,15 +32,17 @@ def wait_for_log(s): cutoff = time.time() + LOG_TIMEOUT while time.time() < cutoff: l = tor_process.stdout.readline() - l = l.decode('utf8') + l = l.decode('utf8', 'backslashreplace') if s in l: logging.info('Tor logged: "{}"'.format(l.strip())) return - logging.info('Tor logged: "{}", waiting for "{}"'.format(l.strip(), s)) # readline() returns a blank string when there is no output # avoid busy-waiting - if len(s) == 0: + if len(l) == 0: + logging.debug('Tor has not logged anything, waiting for "{}"'.format(s)) time.sleep(LOG_WAIT) + else: + logging.info('Tor logged: "{}", waiting for "{}"'.format(l.strip(), s)) fail('Could not find "{}" in logs after {} seconds'.format(s, LOG_TIMEOUT)) def pick_random_port(): @@ -120,18 +122,18 @@ if control_socket.connect_ex(('127.0.0.1', control_port)): tor_process.terminate() fail('Cannot connect to ControlPort') -control_socket.sendall('AUTHENTICATE \r\n'.encode('utf8')) -control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('utf8')) +control_socket.sendall('AUTHENTICATE \r\n'.encode('ascii')) +control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('ascii')) wait_for_log('Opened Socks listener') try_connecting_to_socksport() -control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('utf8')) +control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('ascii')) wait_for_log('Opened Socks listener') try_connecting_to_socksport() -control_socket.sendall('SIGNAL HALT\r\n'.encode('utf8')) +control_socket.sendall('SIGNAL HALT\r\n'.encode('ascii')) wait_for_log('exiting cleanly') logging.info('OK') diff --git a/src/test/test_zero_length_keys.sh b/src/test/test_zero_length_keys.sh index 84ca513b0a..eeabab352d 100755 --- a/src/test/test_zero_length_keys.sh +++ b/src/test/test_zero_length_keys.sh @@ -1,6 +1,11 @@ #!/bin/sh # Check that tor regenerates keys when key files are zero-length +if "${builddir:-.}/src/app/tor" --list-modules | grep -q "relay: no"; then + echo "This test requires the relay module. Skipping." >&2 + exit 77 +fi + exitcode=0 "${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/app/tor" -z || exitcode=1 |