Fix for SiteListTest failing on 32bit machines
[lhc/web/wiklou.git] / tests / phpunit / includes / IPTest.php
index b54222d..c4a6c55 100644 (file)
@@ -1,11 +1,13 @@
 <?php
-/*
+/**
  * Tests for IP validity functions. Ported from /t/inc/IP.t by avar.
+ * @group IP
  */
 
 class IPTest extends MediaWikiTestCase {
        /**
         *  not sure it should be tested with boolean false. hashar 20100924
+        * @covers IP::isIPAddress
         */
        public function testisIPAddress() {
                $this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' );
@@ -13,9 +15,9 @@ class IPTest extends MediaWikiTestCase {
                $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' );
                $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' );
                $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' );
-               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1'), 'IPv6 with a double :: occurence' );
-               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::'), 'IPv6 with a double :: occurence, last at end' );
-               $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1'), 'IPv6 with a double :: occurence, firt at beginning' );
+               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1'), 'IPv6 with a double :: occurrence' );
+               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::'), 'IPv6 with a double :: occurrence, last at end' );
+               $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1'), 'IPv6 with a double :: occurrence, firt at beginning' );
                $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' );
                $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' );
                $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' );
@@ -34,25 +36,28 @@ class IPTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @covers IP::isIPv6
+        */
        public function testisIPv6() {
                $this->assertFalse( IP::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' );
                $this->assertFalse( IP::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
                $this->assertFalse( IP::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' );
                $this->assertFalse( IP::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' );
-               
+
                $this->assertTrue( IP::isIPv6( 'fc:100::' ) );
                $this->assertTrue( IP::isIPv6( 'fc:100:a::' ) );
                $this->assertTrue( IP::isIPv6( 'fc:100:a:d::' ) );
                $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1::' ) );
                $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e::' ) );
                $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac::' ) );
-               
+
                $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' );
                $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' );
 
                $this->assertFalse( IP::isIPv6( ':::' ) );
                $this->assertFalse( IP::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' );
-               
+
                $this->assertTrue( IP::isIPv6( '::' ), 'IPv6 zero address' );
                $this->assertTrue( IP::isIPv6( '::0' ) );
                $this->assertTrue( IP::isIPv6( '::fc' ) );
@@ -62,14 +67,14 @@ class IPTest extends MediaWikiTestCase {
                $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1' ) );
                $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e' ) );
                $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e:ac' ) );
-               
+
                $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
                $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
 
                $this->assertFalse( IP::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' );
                $this->assertFalse( IP::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' );
                $this->assertFalse( IP::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' );
-               
+
                $this->assertTrue( IP::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' );
                $this->assertTrue( IP::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) );
@@ -79,13 +84,16 @@ class IPTest extends MediaWikiTestCase {
                $this->assertTrue( IP::isIPv6( '2001::df'), 'IPv6 with "::" and 2 words' );
                $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' );
                $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' );
-               
+
                $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
                $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
 
                $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac:0' ) );
        }
 
+       /**
+        * @covers IP::isIPv4
+        */
        public function testisIPv4() {
                $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' );
                $this->assertFalse( IP::isIPv4( true  ), 'Boolean true is not an IP' );
@@ -101,6 +109,9 @@ class IPTest extends MediaWikiTestCase {
                $this->assertTrue( IP::isIPv4( '74.24.52.13/20', 'IPv4 range' ) );
        }
 
+       /**
+        * @covers IP::isValid
+        */
        public function testValidIPs() {
                foreach ( range( 0, 255 ) as $i ) {
                        $a = sprintf( "%03d", $i );
@@ -125,11 +136,11 @@ class IPTest extends MediaWikiTestCase {
                $this->assertFalse( IP::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
                $this->assertFalse( IP::isValid( 'fc:300' ), 'IPv6 with only 2 words' );
                $this->assertFalse( IP::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' );
-               
+
                $this->assertTrue( IP::isValid( 'fc:100::' ) );
                $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e::' ) );
                $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e:ac::' ) );
-               
+
                $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
                $this->assertTrue( IP::isValid( '2001::df'), 'IPv6 with "::" and 2 words' );
@@ -137,11 +148,14 @@ class IPTest extends MediaWikiTestCase {
                $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
-               
+
                $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' );
                $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' );
        }
 
+       /**
+        * @covers IP::isValid
+        */
        public function testInvalidIPs() {
                // Out of range...
                foreach ( range( 256, 999 ) as $i ) {
@@ -189,6 +203,9 @@ class IPTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @covers IP::isValidBlock
+        */
        public function testValidBlocks() {
                $valid = array(
                        '116.17.184.5/32',
@@ -209,6 +226,9 @@ class IPTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @covers IP::isValidBlock
+        */
        public function testInvalidBlocks() {
                $invalid = array(
                        '116.17.184.5/33',
@@ -240,19 +260,27 @@ class IPTest extends MediaWikiTestCase {
 
        /**
         * test wrapper around ip2long which might return -1 or false depending on PHP version
+        * @covers IP::toUnsigned
         */
        public function testip2longWrapper() {
-               // fixme : add more tests ?
+               // @todo FIXME: Add more tests ?
                $this->assertEquals( pow(2,32) - 1, IP::toUnsigned( '255.255.255.255' ));
                $i = 'IN.VA.LI.D';
                $this->assertFalse( IP::toUnSigned( $i ) );
        }
 
+       /**
+        * @covers IP::isPublic
+        */
        public function testPrivateIPs() {
-               $private = array( 'fc::3', 'fc::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' );
+               $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' );
                foreach ( $private as $p ) {
                        $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" );
                }
+               $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' );
+               foreach ( $public as $p ) {
+                       $this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" );
+               }
        }
 
        // Private wrapper used to test CIDR Parsing.
@@ -267,6 +295,9 @@ class IPTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" );
        }
 
+       /**
+        * @covers IP::hexToQuad
+        */
        public function testHexToQuad() {
                $this->assertEquals( '0.0.0.1'        , IP::hexToQuad( '00000001' ) );
                $this->assertEquals( '255.0.0.0'      , IP::hexToQuad( 'FF000000' ) );
@@ -279,6 +310,9 @@ class IPTest extends MediaWikiTestCase {
                $this->assertEquals( '0.0.255.0'   , IP::hexToQuad( 'FF00' ) );
        }
 
+       /**
+        * @covers IP::hexToOctet
+        */
        public function testHexToOctet() {
                $this->assertEquals( '0:0:0:0:0:0:0:1',
                        IP::hexToOctet( '00000000000000000000000000000001' ) );
@@ -299,9 +333,10 @@ class IPTest extends MediaWikiTestCase {
                $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) );
        }
 
-       /*
+       /**
         * IP::parseCIDR() returns an array containing a signed IP address
         * representing the network mask and the bit mask.
+        * @covers IP::parseCIDR
         */
        function testCIDRParsing() {
                $this->assertFalseCIDR( '192.0.2.0' , "missing mask"    );
@@ -319,7 +354,7 @@ class IPTest extends MediaWikiTestCase {
                $this->assertEquals( array( 0, 0 ), IP::parseCIDR('0.0.0.0/0') );
                $this->assertEquals( array( 0, 0 ), IP::parseCIDR('255.255.255.255/0') );
 
-               // FIXME : add more tests.
+               // @todo FIXME: Add more tests.
 
                # This part test network shifting
                $this->assertNet( '192.0.0.0'  , '192.0.0.2/24'   );
@@ -357,7 +392,7 @@ class IPTest extends MediaWikiTestCase {
        }
 
        /**
-        * Issues there are most probably from IP::toHex() or IP::parseRange()          
+        * Issues there are most probably from IP::toHex() or IP::parseRange()
         * @covers IP::isInRange
         * @dataProvider provideIPsAndRanges
         */
@@ -370,7 +405,7 @@ class IPTest extends MediaWikiTestCase {
        }
 
        /** Provider for testIPIsInRange() */
-       function provideIPsAndRanges() {
+       public static function provideIPsAndRanges() {
                        # Format: (expected boolean, address, range, optional message)
                return array(
                        # IPv4
@@ -396,4 +431,112 @@ class IPTest extends MediaWikiTestCase {
                        array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
                );
        }
+
+       /**
+        * Test for IP::splitHostAndPort().
+        * @dataProvider provideSplitHostAndPort
+        */
+       function testSplitHostAndPort( $expected, $input, $description ) {
+               $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description );
+       }
+
+       /**
+        * Provider for IP::splitHostAndPort()
+        */
+       public static function provideSplitHostAndPort() {
+               return array(
+                       array( false, '[', 'Unclosed square bracket' ),
+                       array( false, '[::', 'Unclosed square bracket 2' ),
+                       array( array( '::', false ), '::', 'Bare IPv6 0' ),
+                       array( array( '::1', false ), '::1', 'Bare IPv6 1' ),
+                       array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ),
+                       array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ),
+                       array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ),
+                       array( false, '::x', 'Double colon but no IPv6' ),
+                       array( array( 'x', 80 ), 'x:80', 'Hostname and port' ),
+                       array( false, 'x:x', 'Hostname and invalid port' ),
+                       array( array( 'x', false ), 'x', 'Plain hostname' )
+               );
+       }
+
+       /**
+        * Test for IP::combineHostAndPort()
+        * @dataProvider provideCombineHostAndPort
+        */
+       function testCombineHostAndPort( $expected, $input, $description ) {
+               list( $host, $port, $defaultPort ) = $input;
+               $this->assertEquals(
+                       $expected,
+                       IP::combineHostAndPort( $host, $port, $defaultPort ),
+                       $description );
+       }
+
+       /**
+        * Provider for IP::combineHostAndPort()
+        */
+       public static function provideCombineHostAndPort() {
+               return array(
+                       array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ),
+                       array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ),
+                       array( 'x', array( 'x', 2, 2 ), 'Normal default port' ),
+                       array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ),
+               );
+       }
+
+       /**
+        * Test for IP::sanitizeRange()
+        * @dataProvider provideIPCIDRs
+        */
+       function testSanitizeRange( $input, $expected, $description ) {
+               $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description );
+       }
+
+       /**
+        * Provider for IP::testSanitizeRange()
+        */
+       public static function provideIPCIDRs() {
+               return array(
+                       array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ),
+                       array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ),
+                       array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ),
+                       array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ),
+                       array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ),
+                       array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ),
+                       array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ),
+                       array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ),
+               );
+       }
+
+       /**
+        * Test for IP::prettifyIP()
+        * @dataProvider provideIPsToPrettify
+        */
+       function testPrettifyIP( $ip, $prettified ) {
+               $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" );
+       }
+
+       /**
+        * Provider for IP::testPrettifyIP()
+        */
+       public static function provideIPsToPrettify() {
+               return array(
+                       array( '0:0:0:0:0:0:0:0', '::' ),
+                       array( '0:0:0::0:0:0', '::' ),
+                       array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ),
+                       array( '0:0::f', '::f' ),
+                       array( '0::0:0:0:33:fef:b', '::33:fef:b' ),
+                       array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ),
+                       array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ),
+                       array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ),
+                       array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ),
+                       array( '0:0:0:0:0:0:0:0/16', '::/16' ),
+                       array( '0:0:0::0:0:0/64', '::/64' ),
+                       array( '0:0::f/52', '::f/52' ),
+                       array( '::0:0:33:fef:b/52', '::33:fef:b/52' ),
+                       array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ),
+                       array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ),
+                       array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ),
+                       array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ),
+               );
+       }
 }