Fixed total breakage of HashRing in 9d1cd9a.
authorAaron Schulz <aschulz@wikimedia.org>
Wed, 15 May 2013 18:16:16 +0000 (11:16 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Wed, 15 May 2013 20:17:24 +0000 (20:17 +0000)
* This had PHP warnings but no errors, but was broken.
* Added some unit tests for this class.

Change-Id: I7c7ea2c30ca747aae7a3c3951fc33c69052de085

includes/HashRing.php
tests/phpunit/includes/HashRingTest.php [new file with mode: 0644]

index 73a38af..cd39ad8 100644 (file)
@@ -49,6 +49,7 @@ class HashRing {
                        return strcmp( $hashes[$a], $hashes[$b] );
                } );
                // Fit the map to weight-proportionate one with a space of size RING_SIZE
+               $sum = array_sum( $map );
                $standardMap = array();
                foreach ( $map as $location => $weight ) {
                        $standardMap[$location] = (int)floor( $weight / $sum * self::RING_SIZE );
diff --git a/tests/phpunit/includes/HashRingTest.php b/tests/phpunit/includes/HashRingTest.php
new file mode 100644 (file)
index 0000000..2d47fdf
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @group HashRing
+ */
+class HashRingTest extends MediaWikiTestCase {
+       function testHashRing() {
+               $ring = new HashRing( array( 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ) );
+
+               $locations = array();
+               for ( $i=0; $i<20; $i++ ) {
+                       $locations[ "hello$i"] = $ring->getLocation( "hello$i" );
+               }
+               $expectedLocations = array(
+                       "hello0" => "s5",
+                       "hello1" => "s6",
+                       "hello2" => "s2",
+                       "hello3" => "s5",
+                       "hello4" => "s6",
+                       "hello5" => "s4",
+                       "hello6" => "s5",
+                       "hello7" => "s4",
+                       "hello8" => "s5",
+                       "hello9" => "s5",
+                       "hello10" => "s3",
+                       "hello11" => "s6",
+                       "hello12" => "s1",
+                       "hello13" => "s3",
+                       "hello14" => "s3",
+                       "hello15" => "s5",
+                       "hello16" => "s4",
+                       "hello17" => "s6",
+                       "hello18" => "s6",
+                       "hello19" => "s3"
+               );
+
+               $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' );
+
+               $locations = array();
+               for ( $i=0; $i<5; $i++ ) {
+                       $locations[ "hello$i"] = $ring->getLocations( "hello$i", 2 );
+               }
+
+               $expectedLocations = array(
+                       "hello0" => array( "s5", "s6" ),
+                       "hello1" => array( "s6", "s4" ),
+                       "hello2" => array( "s2", "s1" ),
+                       "hello3" => array( "s5", "s6" ),
+                       "hello4" => array( "s6", "s4" ),
+               );
+               $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' );
+       }
+}