summaryrefslogtreecommitdiff
path: root/src/test/test_dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test_dir.c')
-rw-r--r--src/test/test_dir.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 83c612045b..ed0c5a1afb 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -7,6 +7,7 @@
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
#define ROUTER_PRIVATE
+#define ROUTERLIST_PRIVATE
#define HIBERNATE_PRIVATE
#include "or.h"
#include "directory.h"
@@ -1381,6 +1382,85 @@ test_dir_v3_networkstatus(void)
ns_detached_signatures_free(dsig2);
}
+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;
+ uint64_t zeros[5] = {0,0,0,0,0};
+ 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)
+ total += vals[i];
+ tt_int_op(total, ==, 45);
+ for (i=0; i<n; ++i) {
+ uint64_t t;
+ choice = choose_array_element_by_weight(vals, 10, &t);
+ tt_int_op(t, ==, total);
+ 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(vals, 1, NULL);
+ tt_int_op(choice, ==, 0);
+ }
+
+ /* Now try an array of zeros. We should choose randomly. */
+ memset(histogram,0,sizeof(histogram));
+ for (i = 0; i < n; ++i) {
+ uint64_t t;
+ choice = choose_array_element_by_weight(zeros, 5, &t);
+ tt_int_op(t, ==, 0);
+ 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 }
@@ -1396,6 +1476,7 @@ struct testcase_t dir_tests[] = {
DIR_LEGACY(measured_bw),
DIR_LEGACY(param_voting),
DIR_LEGACY(v3_networkstatus),
+ DIR(random_weighted),
END_OF_TESTCASES
};