diff options
Diffstat (limited to 'src/test/test_dir.c')
-rw-r--r-- | src/test/test_dir.c | 422 |
1 files changed, 350 insertions, 72 deletions
diff --git a/src/test/test_dir.c b/src/test/test_dir.c index bda56b3a8e..c2f3f5297d 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -23,6 +23,7 @@ #include "app/config/confparse.h" #include "app/config/config.h" #include "feature/control/control.h" +#include "lib/encoding/confline.h" #include "lib/crypt_ops/crypto_ed25519.h" #include "lib/crypt_ops/crypto_format.h" #include "lib/crypt_ops/crypto_rand.h" @@ -1591,25 +1592,6 @@ test_dir_measured_bw_kb(void *arg) return; } -/* Test dirserv_read_measured_bandwidths */ -static void -test_dir_dirserv_read_measured_bandwidths_empty(void *arg) -{ - char *fname=NULL; - (void)arg; - - fname = tor_strdup(get_fname("V3BandwidthsFile")); - /* Test an empty file */ - write_str_to_file(fname, "", 0); - setup_capture_of_logs(LOG_WARN); - tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); - expect_log_msg("Empty bandwidth file\n"); - - done: - tor_free(fname); - teardown_capture_of_logs(); -} - /* Unit tests for measured_bw_line_parse using line_is_after_headers flag. * When the end of the header is detected (a first complete bw line is parsed), * incomplete lines fail and give warnings, but do not give warnings if @@ -1653,7 +1635,7 @@ test_dir_measured_bw_kb_line_is_after_headers(void *arg) teardown_capture_of_logs(); } -/* Test dirserv_read_measured_bandwidths with whole files. */ +/* Test dirserv_read_measured_bandwidths with headers and complete files. */ static void test_dir_dirserv_read_measured_bandwidths(void *arg) { @@ -1661,76 +1643,321 @@ test_dir_dirserv_read_measured_bandwidths(void *arg) char *content = NULL; time_t timestamp = time(NULL); char *fname = tor_strdup(get_fname("V3BandwidthsFile")); - - /* Test Torflow file only with timestamp*/ - tor_asprintf(&content, "%ld", (long)timestamp); - write_str_to_file(fname, content, 0); - tor_free(content); - tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); - - /* Test Torflow file with timestamp followed by '\n' */ - tor_asprintf(&content, "%ld\n", (long)timestamp); - write_str_to_file(fname, content, 0); - tor_free(content); - tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); - - /* Test Torflow complete file*/ - const char *torflow_relay_lines= + smartlist_t *bw_file_headers = smartlist_new(); + /* bw file strings in vote */ + char *bw_file_headers_str = NULL; + char *bw_file_headers_str_v100 = NULL; + char *bw_file_headers_str_v110 = NULL; + char *bw_file_headers_str_bad = NULL; + char *bw_file_headers_str_extra = NULL; + char bw_file_headers_str_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = ""; + /* string header lines in bw file */ + char *header_lines_v100 = NULL; + char *header_lines_v110_no_terminator = NULL; + char *header_lines_v110 = NULL; + char header_lines_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = ""; + int i; + const char *header_lines_v110_no_terminator_no_timestamp = + "version=1.1.0\n" + "software=sbws\n" + "software_version=0.1.0\n" + "earliest_bandwidth=2018-05-08T16:13:26\n" + "file_created=2018-04-16T21:49:18\n" + "generator_started=2018-05-08T16:13:25\n" + "latest_bandwidth=2018-04-16T20:49:18\n"; + const char *bw_file_headers_str_v110_no_timestamp = + "version=1.1.0 software=sbws " + "software_version=0.1.0 " + "earliest_bandwidth=2018-05-08T16:13:26 " + "file_created=2018-04-16T21:49:18 " + "generator_started=2018-05-08T16:13:25 " + "latest_bandwidth=2018-04-16T20:49:18"; + const char *relay_lines_v100 = "node_id=$557365204145532d32353620696e73746561642e bw=1024 " "nick=Test measured_at=1523911725 updated_at=1523911725 " "pid_error=4.11374090719 pid_error_sum=4.11374090719 " "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 " "scanner=/filepath\n"; - - tor_asprintf(&content, "%ld\n%s", (long)timestamp, torflow_relay_lines); + const char *relay_lines_v110 = + "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 " + "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ " + "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n"; + const char *relay_lines_bad = + "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A\n"; + + tor_asprintf(&header_lines_v100, "%ld\n", (long)timestamp); + tor_asprintf(&header_lines_v110_no_terminator, "%ld\n%s", (long)timestamp, + header_lines_v110_no_terminator_no_timestamp); + tor_asprintf(&header_lines_v110, "%s%s", + header_lines_v110_no_terminator, BW_FILE_HEADERS_TERMINATOR); + + tor_asprintf(&bw_file_headers_str_v100, "timestamp=%ld",(long)timestamp); + tor_asprintf(&bw_file_headers_str_v110, "timestamp=%ld %s", + (long)timestamp, bw_file_headers_str_v110_no_timestamp); + tor_asprintf(&bw_file_headers_str_bad, "%s " + "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A", + bw_file_headers_str_v110); + + for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE; i++) { + strlcat(header_lines_long, "foo=bar\n", + sizeof(header_lines_long)); + } + /* 8 is the number of v110 lines in header_lines_v110 */ + for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE - 8 - 1; i++) { + strlcat(bw_file_headers_str_long, "foo=bar ", + sizeof(bw_file_headers_str_long)); + } + strlcat(bw_file_headers_str_long, "foo=bar", + sizeof(bw_file_headers_str_long)); + tor_asprintf(&bw_file_headers_str_extra, + "%s %s", + bw_file_headers_str_v110, + bw_file_headers_str_long); + + /* Test an empty bandwidth file. bw_file_headers will be empty string */ + write_str_to_file(fname, "", 0); + setup_capture_of_logs(LOG_WARN); + tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + expect_log_msg("Empty bandwidth file\n"); + teardown_capture_of_logs(); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op("", OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test bandwidth file with only timestamp. + * bw_file_headers will be empty string */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%ld", (long)timestamp); write_str_to_file(fname, content, 0); tor_free(content); - tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); - - /* Test Torflow complete file including v1.1.0 headers */ - const char *v110_header_lines= - "version=1.1.0\n" - "software=sbws\n" - "software_version=0.1.0\n" - "generator_started=2018-05-08T16:13:25\n" - "earliest_bandwidth=2018-05-08T16:13:26\n" - "====\n"; - - tor_asprintf(&content, "%ld\n%s%s", (long)timestamp, v110_header_lines, - torflow_relay_lines); + tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op("", OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.0.0 bandwidth file headers */ + write_str_to_file(fname, header_lines_v100, 0); + bw_file_headers = smartlist_new(); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.0.0 complete bandwidth file */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100); write_str_to_file(fname, content, 0); tor_free(content); - tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); - - /* Test Torflow with additional headers afer a correct bw line */ - tor_asprintf(&content, "%ld\n%s%s", (long)timestamp, torflow_relay_lines, - v110_header_lines); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.0.0 complete bandwidth file with NULL bw_file_headers. */ + tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100); write_str_to_file(fname, content, 0); tor_free(content); - tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL)); - /* Test Torflow with additional headers afer a correct bw line and more - * bw lines after the headers. */ - tor_asprintf(&content, "%ld\n%s%s%s", (long)timestamp, torflow_relay_lines, - v110_header_lines, torflow_relay_lines); + /* Test bandwidth file including v1.1.0 bandwidth headers and + * v1.0.0 relay lines. bw_file_headers will contain the v1.1.0 headers. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s", header_lines_v100, header_lines_v110, + relay_lines_v100); write_str_to_file(fname, content, 0); tor_free(content); - tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); - - /* Test sbws file */ - const char *sbws_relay_lines= - "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 " - "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ " - "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n"; - - tor_asprintf(&content, "%ld\n%s%s", (long)timestamp, v110_header_lines, - sbws_relay_lines); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.0.0 complete bandwidth file with v1.1.0 headers at the end. + * bw_file_headers will contain only v1.0.0 headers and the additional + * headers will be interpreted as malformed relay lines. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s", header_lines_v100, relay_lines_v100, + header_lines_v110); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.0.0 complete bandwidth file, the v1.1.0 headers and more relay + * lines. bw_file_headers will contain only v1.0.0 headers, the additional + * headers will be interpreted as malformed relay lines and the last relay + * lines will be correctly interpreted as relay lines. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s%s", header_lines_v100, relay_lines_v100, + header_lines_v110, relay_lines_v100); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers without terminator */ + bw_file_headers = smartlist_new(); + write_str_to_file(fname, header_lines_v110_no_terminator, 0); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers with terminator */ + bw_file_headers = smartlist_new(); + write_str_to_file(fname, header_lines_v110, 0); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth file without terminator, then relay lines. + * bw_file_headers will contain the v1.1.0 headers. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s", + header_lines_v110_no_terminator, relay_lines_v110); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers with terminator, then relay lines + * bw_file_headers will contain the v1.1.0 headers. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s", + header_lines_v110, relay_lines_v110); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers with terminator, then bad relay lines, + * then terminator, then relay_lines_bad. + * bw_file_headers will contain the v1.1.0 headers. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s%s", header_lines_v110, relay_lines_bad, + BW_FILE_HEADERS_TERMINATOR, relay_lines_bad); write_str_to_file(fname, content, 0); tor_free(content); - tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL)); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers without terminator, then bad relay lines, + * then relay lines. bw_file_headers will contain the v1.1.0 headers and + * the bad relay lines. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s", + header_lines_v110_no_terminator, relay_lines_bad, + relay_lines_v110); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_bad, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers without terminator, + * then many bad relay lines, then relay lines. + * bw_file_headers will contain the v1.1.0 headers and the bad relay lines + * to a maximum of MAX_BW_FILE_HEADER_COUNT_IN_VOTE header lines. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s", + header_lines_v110_no_terminator, header_lines_long, + relay_lines_v110); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ, + smartlist_len(bw_file_headers)); + bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL); + tt_str_op(bw_file_headers_str_extra, OP_EQ, bw_file_headers_str); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); + + /* Test v1.1.0 bandwidth headers without terminator, + * then many bad relay lines, then relay lines. + * bw_file_headers will contain the v1.1.0 headers and the bad relay lines. + * Force bw_file_headers to have more than MAX_BW_FILE_HEADER_COUNT_IN_VOTE + * This test is needed while there is not dirvote test. */ + bw_file_headers = smartlist_new(); + tor_asprintf(&content, "%s%s%s", + header_lines_v110_no_terminator, header_lines_long, + relay_lines_v110); + write_str_to_file(fname, content, 0); + tor_free(content); + tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, + bw_file_headers)); + tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ, + smartlist_len(bw_file_headers)); + /* force bw_file_headers to be bigger than + * MAX_BW_FILE_HEADER_COUNT_IN_VOTE */ + char line[8] = "foo=bar\0"; + smartlist_add_strdup(bw_file_headers, line); + tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_LT, + smartlist_len(bw_file_headers)); + SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c)); + smartlist_free(bw_file_headers); + tor_free(bw_file_headers_str); done: tor_free(fname); + tor_free(header_lines_v100); + tor_free(header_lines_v110_no_terminator); + tor_free(header_lines_v110); + tor_free(bw_file_headers_str_v100); + tor_free(bw_file_headers_str_v110); + tor_free(bw_file_headers_str_bad); + tor_free(bw_file_headers_str_extra); } #define MBWC_INIT_TIME 1000 @@ -5979,6 +6206,57 @@ test_dir_networkstatus_consensus_has_ipv6(void *arg) UNMOCK(networkstatus_get_latest_consensus_by_flavor); } +static void +test_dir_format_versions_list(void *arg) +{ + (void)arg; + char *s = NULL; + config_line_t *lines = NULL; + + setup_capture_of_logs(LOG_WARN); + s = format_recommended_version_list(lines, 1); + tt_str_op(s, OP_EQ, ""); + + tor_free(s); + config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc"); + s = format_recommended_version_list(lines, 1); + tt_str_op(s, OP_EQ, "0.2.9.111-alpha,0.3.4.1,4.4.4-rc"); + + tor_free(s); + config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10 "); + s = format_recommended_version_list(lines, 1); + tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,4.4.4-rc"); + + /* There should be no warnings so far. */ + expect_no_log_entry(); + + /* Now try a line with a space in it. */ + tor_free(s); + config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7"); + s = format_recommended_version_list(lines, 1); + tt_str_op(s, OP_EQ, "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1," + "1.3.3.7,1.3.3.8,4.4.4-rc"); + + expect_single_log_msg_containing( + "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." ); + + /* Start over, with a line containing a bogus version */ + config_free_lines(lines); + lines = NULL; + tor_free(s); + mock_clean_saved_logs(); + config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc"); + s = format_recommended_version_list(lines,1); + tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex"); + expect_single_log_msg_containing( + "Recommended version \"alpha-complex\" does not look valid."); + + done: + tor_free(s); + config_free_lines(lines); + teardown_capture_of_logs(); +} + #define DIR_LEGACY(name) \ { #name, test_dir_ ## name , TT_FORK, NULL, NULL } @@ -6001,7 +6279,6 @@ struct testcase_t dir_tests[] = { DIR_LEGACY(versions), DIR_LEGACY(fp_pairs), DIR(split_fps, 0), - DIR_LEGACY(dirserv_read_measured_bandwidths_empty), DIR_LEGACY(measured_bw_kb), DIR_LEGACY(measured_bw_kb_line_is_after_headers), DIR_LEGACY(measured_bw_kb_cache), @@ -6049,5 +6326,6 @@ struct testcase_t dir_tests[] = { DIR(networkstatus_compute_bw_weights_v10, 0), DIR(platform_str, 0), DIR(networkstatus_consensus_has_ipv6, TT_FORK), + DIR(format_versions_list, TT_FORK), END_OF_TESTCASES }; |