Browse Source

Add process and unite tests code for the condition that all the servers are unreachable.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac356@3760 e5f2f494-b856-4b98-b285-d166d9295462
Haidong Wang 14 years ago
parent
commit
399a6d6900

+ 16 - 5
src/lib/nsas/nameserver_entry.cc

@@ -253,7 +253,9 @@ void NameserverEntry::updateAddressSelector(std::vector<AddressEntry>& addresses
     for(vector<AddressEntry>::iterator it = addresses.begin(); 
             it != addresses.end(); ++it){
         uint32_t rtt = (*it).getRTT();
-        if(rtt == 0) isc_throw(RTTIsZero, "The RTT is 0");
+        if(rtt == 0) {
+            isc_throw(RTTIsZero, "The RTT is 0");
+        }
 
         if(rtt == AddressEntry::UNREACHABLE) {
             probabilities.push_back(0);
@@ -264,10 +266,19 @@ void NameserverEntry::updateAddressSelector(std::vector<AddressEntry>& addresses
     // Calculate the sum
     double sum = accumulate(probabilities.begin(), probabilities.end(), 0.0);
 
-    // Normalize the probabilities to make the sum equal to 1.0
-    for(vector<double>::iterator it = probabilities.begin(); 
-            it != probabilities.end(); ++it){
-        (*it) /= sum;
+    if(sum != 0) {
+        // Normalize the probabilities to make the sum equal to 1.0
+        for(vector<double>::iterator it = probabilities.begin(); 
+                it != probabilities.end(); ++it){
+            (*it) /= sum;
+        }
+    } else if(probabilities.size() > 0){
+        // If all the nameservers are unreachable, the sum will be 0
+        // So give each server equal opportunity to be selected.
+        for(vector<double>::iterator it = probabilities.begin(); 
+                it != probabilities.end(); ++it){
+            (*it) = 1.0/probabilities.size();
+        }
     }
 
     selector.reset(probabilities);

+ 17 - 0
src/lib/nsas/tests/nameserver_entry_unittest.cc

@@ -481,6 +481,23 @@ TEST_F(NameserverEntryTest, AddressSelection) {
     // The 3rd address should not be selected again
     ASSERT_EQ(0, c3);
 
+    // Test if all the servers are unrachable
+    ns->setAddressUnreachable(v4Addresses[0].getAddress());
+    ns->setAddressUnreachable(v4Addresses[1].getAddress());
+    ns->setAddressUnreachable(v4Addresses[2].getAddress());
+    c1 = c2 = c3 = 0;
+    for(int i = 0; i < 100000; ++i){
+        ns.get()->getAddress(ns_address, AF_INET);
+        asiolink::IOAddress io_address = ns_address.getAddress();
+        if(io_address.toText() == v4Addresses[0].getAddress().toText()) ++c1;
+        else if(io_address.toText() == v4Addresses[1].getAddress().toText()) ++c2;
+        else if(io_address.toText() == v4Addresses[2].getAddress().toText()) ++c3;
+    }
+
+    // All the unreachable servers should be selected with equal opportunity
+    ASSERT_EQ(1, (int)(c1*1.0/c2 + 0.5));
+    ASSERT_EQ(1, (int)(c1*1.0/c3 + 0.5));
+
     // TODO: The unreachable server should be changed to reachable after 5minutes, but how to test?
 }
 

+ 10 - 0
src/lib/nsas/tests/random_number_generator_unittest.cc

@@ -52,6 +52,11 @@ private:
     const static int max_ = 10;
 };
 
+/// Some validation tests will incur performance penalty, so the tests are
+/// made only in "debug" version with assert(). But if NDEBUG is defined
+/// the tests will be failed since assert() is non-op in non-debug version.
+/// The "#ifndef NDEBUG" is added to make the tests be performed only in
+/// non-debug environment.
 #ifndef NDEBUG
 // Test of the constructor
 TEST_F(UniformRandomIntegerGeneratorTest, Constructor) {
@@ -99,6 +104,11 @@ TEST_F(WeightedRandomIntegerGeneratorTest, Constructor)
         ASSERT_EQ(gen(), 123);
     }
 
+/// Some validation tests will incur performance penalty, so the tests are
+/// made only in "debug" version with assert(). But if NDEBUG is defined
+/// the tests will be failed since assert() is non-op in non-debug version.
+/// The "#ifndef NDEBUG" is added to make the tests be performed only in
+/// non-debug environment.
 #ifndef NDEBUG
     //The probability must be >= 0
     probabilities.push_back(-0.1);