]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - tests/phpunit/includes/utils/UIDGeneratorTest.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / phpunit / includes / utils / UIDGeneratorTest.php
1 <?php
2
3 class UIDGeneratorTest extends PHPUnit_Framework_TestCase {
4
5         protected function tearDown() {
6                 // Bug: 44850
7                 UIDGenerator::unitTestTearDown();
8                 parent::tearDown();
9         }
10
11         /**
12          * Test that generated UIDs have the expected properties
13          *
14          * @dataProvider provider_testTimestampedUID
15          * @covers UIDGenerator::newTimestampedUID128
16          * @covers UIDGenerator::newTimestampedUID88
17          */
18         public function testTimestampedUID( $method, $digitlen, $bits, $tbits, $hostbits ) {
19                 $id = call_user_func( [ 'UIDGenerator', $method ] );
20                 $this->assertEquals( true, ctype_digit( $id ), "UID made of digit characters" );
21                 $this->assertLessThanOrEqual( $digitlen, strlen( $id ),
22                         "UID has the right number of digits" );
23                 $this->assertLessThanOrEqual( $bits, strlen( Wikimedia\base_convert( $id, 10, 2 ) ),
24                         "UID has the right number of bits" );
25
26                 $ids = [];
27                 for ( $i = 0; $i < 300; $i++ ) {
28                         $ids[] = call_user_func( [ 'UIDGenerator', $method ] );
29                 }
30
31                 $lastId = array_shift( $ids );
32
33                 $this->assertSame( array_unique( $ids ), $ids, "All generated IDs are unique." );
34
35                 foreach ( $ids as $id ) {
36                         // Convert string to binary and pad to full length so we can
37                         // extract segments
38                         $id_bin = Wikimedia\base_convert( $id, 10, 2, $bits );
39                         $lastId_bin = Wikimedia\base_convert( $lastId, 10, 2, $bits );
40
41                         $timestamp_bin = substr( $id_bin, 0, $tbits );
42                         $last_timestamp_bin = substr( $lastId_bin, 0, $tbits );
43
44                         $this->assertGreaterThanOrEqual(
45                                 $last_timestamp_bin,
46                                 $timestamp_bin,
47                                 "timestamp ($timestamp_bin) of current ID ($id_bin) >= timestamp ($last_timestamp_bin) " .
48                                         "of prior one ($lastId_bin)" );
49
50                         $hostbits_bin = substr( $id_bin, -$hostbits );
51                         $last_hostbits_bin = substr( $lastId_bin, -$hostbits );
52
53                         if ( $hostbits ) {
54                                 $this->assertEquals(
55                                         $hostbits_bin,
56                                         $last_hostbits_bin,
57                                         "Host ID ($hostbits_bin) of current ID ($id_bin) is same as host ID ($last_hostbits_bin) " .
58                                                 "of prior one ($lastId_bin)." );
59                         }
60
61                         $lastId = $id;
62                 }
63         }
64
65         /**
66          * array( method, length, bits, hostbits )
67          * NOTE: When adding a new method name here please update the covers tags for the tests!
68          */
69         public static function provider_testTimestampedUID() {
70                 return [
71                         [ 'newTimestampedUID128', 39, 128, 46, 48 ],
72                         [ 'newTimestampedUID128', 39, 128, 46, 48 ],
73                         [ 'newTimestampedUID88', 27, 88, 46, 32 ],
74                 ];
75         }
76
77         /**
78          * @covers UIDGenerator::newUUIDv1
79          */
80         public function testUUIDv1() {
81                 $ids = [];
82                 for ( $i = 0; $i < 100; $i++ ) {
83                         $id = UIDGenerator::newUUIDv1();
84                         $this->assertEquals( true,
85                                 preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ),
86                                 "UID $id has the right format" );
87                         $ids[] = $id;
88
89                         $id = UIDGenerator::newRawUUIDv1();
90                         $this->assertEquals( true,
91                                 preg_match( '!^[0-9a-f]{12}1[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
92                                 "UID $id has the right format" );
93
94                         $id = UIDGenerator::newRawUUIDv1();
95                         $this->assertEquals( true,
96                                 preg_match( '!^[0-9a-f]{12}1[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
97                                 "UID $id has the right format" );
98                 }
99
100                 $this->assertEquals( array_unique( $ids ), $ids, "All generated IDs are unique." );
101         }
102
103         /**
104          * @covers UIDGenerator::newUUIDv4
105          */
106         public function testUUIDv4() {
107                 $ids = [];
108                 for ( $i = 0; $i < 100; $i++ ) {
109                         $id = UIDGenerator::newUUIDv4();
110                         $ids[] = $id;
111                         $this->assertEquals( true,
112                                 preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ),
113                                 "UID $id has the right format" );
114                 }
115
116                 $this->assertEquals( array_unique( $ids ), $ids, 'All generated IDs are unique.' );
117         }
118
119         /**
120          * @covers UIDGenerator::newRawUUIDv4
121          */
122         public function testRawUUIDv4() {
123                 for ( $i = 0; $i < 100; $i++ ) {
124                         $id = UIDGenerator::newRawUUIDv4();
125                         $this->assertEquals( true,
126                                 preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
127                                 "UID $id has the right format" );
128                 }
129         }
130
131         /**
132          * @covers UIDGenerator::newRawUUIDv4
133          */
134         public function testRawUUIDv4QuickRand() {
135                 for ( $i = 0; $i < 100; $i++ ) {
136                         $id = UIDGenerator::newRawUUIDv4( UIDGenerator::QUICK_RAND );
137                         $this->assertEquals( true,
138                                 preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
139                                 "UID $id has the right format" );
140                 }
141         }
142
143         /**
144          * @covers UIDGenerator::newSequentialPerNodeID
145          */
146         public function testNewSequentialID() {
147                 $id1 = UIDGenerator::newSequentialPerNodeID( 'test', 32 );
148                 $id2 = UIDGenerator::newSequentialPerNodeID( 'test', 32 );
149
150                 $this->assertInternalType( 'float', $id1, "ID returned as float" );
151                 $this->assertInternalType( 'float', $id2, "ID returned as float" );
152                 $this->assertGreaterThan( 0, $id1, "ID greater than 1" );
153                 $this->assertGreaterThan( $id1, $id2, "IDs increasing in value" );
154         }
155
156         /**
157          * @covers UIDGenerator::newSequentialPerNodeIDs
158          */
159         public function testNewSequentialIDs() {
160                 $ids = UIDGenerator::newSequentialPerNodeIDs( 'test', 32, 5 );
161                 $lastId = null;
162                 foreach ( $ids as $id ) {
163                         $this->assertInternalType( 'float', $id, "ID returned as float" );
164                         $this->assertGreaterThan( 0, $id, "ID greater than 1" );
165                         if ( $lastId ) {
166                                 $this->assertGreaterThan( $lastId, $id, "IDs increasing in value" );
167                         }
168                         $lastId = $id;
169                 }
170         }
171 }