This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new a03db7d  Added a test of hierarchical sorting for the random sorter.
a03db7d is described below

commit a03db7d684f343656aa229771f30c4990a2839c1
Author: Benjamin Mahler <[email protected]>
AuthorDate: Tue Apr 9 17:08:02 2019 -0400

    Added a test of hierarchical sorting for the random sorter.
    
    Review: https://reviews.apache.org/r/70438
---
 src/tests/sorter_tests.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/src/tests/sorter_tests.cpp b/src/tests/sorter_tests.cpp
index 9d52a80..91bfde0 100644
--- a/src/tests/sorter_tests.cpp
+++ b/src/tests/sorter_tests.cpp
@@ -16,6 +16,7 @@
 
 #include <iostream>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include <gmock/gmock.h>
@@ -37,6 +38,7 @@ using mesos::internal::master::allocator::RandomSorter;
 
 using std::cout;
 using std::endl;
+using std::pair;
 using std::string;
 using std::vector;
 
@@ -94,6 +96,80 @@ TEST(WeightedShuffleTest, ProbabilityDistribution)
 }
 
 
+// Test the behavior of the random sorter by ensuring that the
+// probability distribution after a number of runs is within
+// a particular error bound.
+TEST(RandomSorterTest, HierarchicalProbabilityDistribution)
+{
+  RandomSorter sorter;
+
+  // We test the following role (weight) tree:
+  // |                 /\                   |
+  // |               /    \                 |
+  // |            /          \              |
+  // |      (1) a              c (2)        |
+  // |         / \            / \           |
+  // |    (1) .   b (2)  (1) d   e (2)      |
+
+  // Store the leaf position for each client, so that we
+  // can compute tables below.
+  hashmap<string, int> clients = {
+      {"a", 0},
+      {"a/b", 1},
+      {"c/d", 2},
+      {"c/e", 3}
+  };
+
+  vector<pair<string, double>> weights = {
+      {"a", 1.0}, {"a/b", 2.0},
+      {"c", 2.0}, {"c/d", 1.0}, {"c/e", 2.0}
+  };
+
+  foreachkey (const string& client, clients) {
+    sorter.add(client);
+    sorter.activate(client);
+  }
+
+  for (const pair<string, double> weight : weights) {
+    sorter.updateWeight(weight.first, weight.second);
+  }
+
+  // Count of how many times client i returned as the jth client
+  // in the sort result.
+  size_t totalRuns = 10000u;
+  size_t counts[4][4] = {};
+
+  for (size_t run = 0; run < totalRuns; ++run) {
+    vector<string> candidates = sorter.sort();
+    for (size_t i = 0; i < candidates.size(); ++i) {
+      ++counts[clients.at(candidates.at(i))][i];
+    }
+  }
+
+  // This table was generated by running a weighted shuffle algorithm
+  // for a large number of iterations.
+  double expectedProbabilities[4][4] = {
+    {0.11, 0.22, 0.22, 0.44},
+    {0.22, 0.11, 0.44, 0.22},
+    {0.22, 0.44, 0.11, 0.22},
+    {0.44, 0.22, 0.22, 0.11},
+  };
+
+  double actualProbabilities[4][4];
+
+  for (int i = 0; i < 4; ++i) {
+    for (int j = 0; j < 4; ++j) {
+      actualProbabilities[i][j] = counts[i][j] / (1.0 * totalRuns);
+
+      // Assert that the actual probabilities differ less than
+      // an absolute 5%.
+      EXPECT_NEAR(expectedProbabilities[i][j], actualProbabilities[i][j], 0.05)
+       << "position [" << i << "][" << j << "]";
+    }
+  }
+}
+
+
 template <typename T>
 class CommonSorterTest : public ::testing::Test {};
 

Reply via email to