1 module tests.cluster;
2 
3 import tests.utils;
4 import vivaldi;
5 
6 /**
7  * Generates an NxN matrix of latencies clustered on either side of a
8  * split. Nodes on either side of split have "local" latency amongst
9  * themselves, and an additional "remote" latency with nodes on the
10  * opposite side.
11  */
12 template cluster(size_t n, double local, double remote) {
13 
14     auto cluster() nothrow @safe @nogc {
15         auto matrix = matrix!n;
16 
17         const split = n / 2;
18         for (size_t i = 0; i < n; i++) {
19             for (size_t j = i + 1; j < n; j++) {
20                 double rtt = local;
21 
22                 if ((i <= split && j > split) || (i > split && j <= split)) {
23                     rtt += remote;
24                 }
25 
26                 matrix[i][j] = rtt;
27                 matrix[j][i] = rtt;
28             }
29         }
30 
31         return matrix;
32     }
33 }
34 
35 @("cluster")
36 unittest {
37     import std.format;
38     import std.random;
39 
40     // Stable seed for random unitvectors.
41     rndGen().seed(1);
42 
43     alias N = Node!(Coordinate!8, 20);
44 
45     immutable double local = 0.001;
46     immutable double remote = 0.01;
47     immutable size_t n = 25;
48     auto cycles = 1000;
49 
50     N[n] nodes = new N[n];
51     double[n][n] matrix = cluster!(n, local, remote);
52 
53     simulate!(N, 3, n)(nodes, matrix, cycles);
54     auto stats = evaluate!(N, n)(nodes, matrix);
55 
56     assert(stats.mean <= 0.00006, format("mean=%s", stats.mean));
57     assert(stats.max <= 0.00048, format("max=%s", stats.max));
58 }