aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-09-11 17:51:36 -0400
committerNick Mathewson <nickm@torproject.org>2012-09-11 17:51:36 -0400
commit75c9ccd4f851bac6d32cb08ded557ac207bc8002 (patch)
tree0edd289ca5453ebfad30d52bc55665bad1e76fe0 /src/test
parentb8f93c5dd7a069c9e5ac3469d067a31c3992fa25 (diff)
parent9982122f3448293e80adf83cb28c7ab66bc04da9 (diff)
downloadtor-75c9ccd4f851bac6d32cb08ded557ac207bc8002.tar
tor-75c9ccd4f851bac6d32cb08ded557ac207bc8002.tar.gz
Merge remote-tracking branch 'public/bug6538'
Conflicts: configure.ac
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test.h4
-rw-r--r--src/test/test_dir.c123
2 files changed, 127 insertions, 0 deletions
diff --git a/src/test/test.h b/src/test/test.h
index 0b6e6c60c..6dcb9490b 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -65,6 +65,10 @@
#define test_memeq_hex(expr1, hex) test_mem_op_hex(expr1, ==, hex)
+#define tt_double_op(a,op,b) \
+ tt_assert_test_type(a,b,#a" "#op" "#b,double,(val1_ op val2_),"%f", \
+ TT_EXIT_TEST_FUNCTION)
+
const char *get_fname(const char *name);
crypto_pk_t *pk_generate(int idx);
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index af878a696..9bf44b116 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -4,9 +4,12 @@
/* See LICENSE for licensing information */
#include "orconfig.h"
+#include <math.h>
+
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
#define ROUTER_PRIVATE
+#define ROUTERLIST_PRIVATE
#define HIBERNATE_PRIVATE
#include "or.h"
#include "directory.h"
@@ -1389,6 +1392,124 @@ test_dir_v3_networkstatus(void)
ns_detached_signatures_free(dsig2);
}
+static void
+test_dir_scale_bw(void *testdata)
+{
+ double v[8] = { 2.0/3,
+ 7.0,
+ 1.0,
+ 3.0,
+ 1.0/5,
+ 1.0/7,
+ 12.0,
+ 24.0 };
+ u64_dbl_t vals[8];
+ uint64_t total;
+ int i;
+
+ (void) testdata;
+
+ for (i=0; i<8; ++i)
+ vals[i].dbl = v[i];
+
+ scale_array_elements_to_u64(vals, 8, &total);
+
+ tt_int_op((int)total, ==, 48);
+ total = 0;
+ for (i=0; i<8; ++i) {
+ total += vals[i].u64;
+ }
+ tt_assert(total >= (U64_LITERAL(1)<<60));
+ tt_assert(total <= (U64_LITERAL(1)<<62));
+
+ for (i=0; i<8; ++i) {
+ double ratio = ((double)vals[i].u64) / vals[2].u64;
+ tt_double_op(fabs(ratio - v[i]), <, .00001);
+ }
+
+ done:
+ ;
+}
+
+static void
+test_dir_random_weighted(void *testdata)
+{
+ int histogram[10];
+ uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0;
+ u64_dbl_t inp[10];
+ int i, choice;
+ const int n = 50000;
+ double max_sq_error;
+ (void) testdata;
+
+ /* Try a ten-element array with values from 0 through 10. The values are
+ * in a scrambled order to make sure we don't depend on order. */
+ memset(histogram,0,sizeof(histogram));
+ for (i=0; i<10; ++i) {
+ inp[i].u64 = vals[i];
+ total += vals[i];
+ }
+ tt_int_op(total, ==, 45);
+ for (i=0; i<n; ++i) {
+ choice = choose_array_element_by_weight(inp, 10);
+ tt_int_op(choice, >=, 0);
+ tt_int_op(choice, <, 10);
+ histogram[choice]++;
+ }
+
+ /* Now see if we chose things about frequently enough. */
+ max_sq_error = 0;
+ for (i=0; i<10; ++i) {
+ int expected = (int)(n*vals[i]/total);
+ double frac_diff = 0, sq;
+ TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
+ if (expected)
+ frac_diff = (histogram[i] - expected) / ((double)expected);
+ else
+ tt_int_op(histogram[i], ==, 0);
+
+ sq = frac_diff * frac_diff;
+ if (sq > max_sq_error)
+ max_sq_error = sq;
+ }
+ /* It should almost always be much much less than this. If you want to
+ * figure out the odds, please feel free. */
+ tt_double_op(max_sq_error, <, .05);
+
+ /* Now try a singleton; do we choose it? */
+ for (i = 0; i < 100; ++i) {
+ choice = choose_array_element_by_weight(inp, 1);
+ tt_int_op(choice, ==, 0);
+ }
+
+ /* Now try an array of zeros. We should choose randomly. */
+ memset(histogram,0,sizeof(histogram));
+ for (i = 0; i < 5; ++i)
+ inp[i].u64 = 0;
+ for (i = 0; i < n; ++i) {
+ choice = choose_array_element_by_weight(inp, 5);
+ tt_int_op(choice, >=, 0);
+ tt_int_op(choice, <, 5);
+ histogram[choice]++;
+ }
+ /* Now see if we chose things about frequently enough. */
+ max_sq_error = 0;
+ for (i=0; i<5; ++i) {
+ int expected = n/5;
+ double frac_diff = 0, sq;
+ TT_BLATHER((" %d : %5d vs %5d\n", (int)vals[i], histogram[i], expected));
+ frac_diff = (histogram[i] - expected) / ((double)expected);
+ sq = frac_diff * frac_diff;
+ if (sq > max_sq_error)
+ max_sq_error = sq;
+ }
+ /* It should almost always be much much less than this. If you want to
+ * figure out the odds, please feel free. */
+ tt_double_op(max_sq_error, <, .05);
+ done:
+ ;
+}
+
#define DIR_LEGACY(name) \
{ #name, legacy_test_helper, TT_FORK, &legacy_setup, test_dir_ ## name }
@@ -1404,6 +1525,8 @@ struct testcase_t dir_tests[] = {
DIR_LEGACY(measured_bw),
DIR_LEGACY(param_voting),
DIR_LEGACY(v3_networkstatus),
+ DIR(random_weighted),
+ DIR(scale_bw),
END_OF_TESTCASES
};