Merge "Split out new ObjectCache::newWANCacheFromParams() method"
[lhc/web/wiklou.git] / tests / phpunit / includes / libs / WaitConditionLoopTest.php
1 <?php
2
3 class WaitConditionLoopFakeTime extends WaitConditionLoop {
4 protected $wallClock = 1;
5
6 function __construct( callable $condition, $timeout, array $busyCallbacks ) {
7 parent::__construct( $condition, $timeout, $busyCallbacks );
8 }
9
10 function usleep( $microseconds ) {
11 $this->wallClock += $microseconds / 1e6;
12 }
13
14 function getCpuTime() {
15 return 0.0;
16 }
17
18 function getWallTime() {
19 return $this->wallClock;
20 }
21
22 public function setWallClock( &$timestamp ) {
23 $this->wallClock =& $timestamp;
24 }
25 }
26
27 class WaitConditionLoopTest extends PHPUnit_Framework_TestCase {
28 public function testCallbackReached() {
29 $wallClock = microtime( true );
30
31 $count = 0;
32 $status = new StatusValue();
33 $loop = new WaitConditionLoopFakeTime(
34 function () use ( &$count, $status ) {
35 ++$count;
36 $status->value = 'cookie';
37
38 return WaitConditionLoop::CONDITION_REACHED;
39 },
40 10.0,
41 $this->newBusyWork( $x, $y, $z )
42 );
43 $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke() );
44 $this->assertEquals( 1, $count );
45 $this->assertEquals( 'cookie', $status->value );
46 $this->assertEquals( [ 0, 0, 0 ], [ $x, $y, $z ], "No busy work done" );
47
48 $count = 0;
49 $loop = new WaitConditionLoopFakeTime(
50 function () use ( &$count, &$wallClock ) {
51 $wallClock += 1;
52 ++$count;
53
54 return $count >= 2 ? WaitConditionLoop::CONDITION_REACHED : false;
55 },
56 7.0,
57 $this->newBusyWork( $x, $y, $z, $wallClock )
58 );
59 $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke(),
60 "Busy work did not cause timeout" );
61 $this->assertEquals( [ 1, 0, 0 ], [ $x, $y, $z ] );
62
63 $count = 0;
64 $loop = new WaitConditionLoopFakeTime(
65 function () use ( &$count, &$wallClock ) {
66 $wallClock += .1;
67 ++$count;
68
69 return $count > 80 ? true : false;
70 },
71 50.0,
72 $this->newBusyWork( $x, $y, $z, $wallClock, $dontCallMe, $badCalls )
73 );
74 $this->assertEquals( 0, $badCalls, "Callback exception not yet called" );
75 $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke() );
76 $this->assertEquals( [ 1, 1, 1 ], [ $x, $y, $z ], "Busy work done" );
77 $this->assertEquals( 1, $badCalls, "Bad callback ran and was exception caught" );
78
79 try {
80 $e = null;
81 $dontCallMe();
82 } catch ( Exception $e ) {
83 }
84
85 $this->assertInstanceOf( 'RunTimeException', $e );
86 $this->assertEquals( 1, $badCalls, "Callback exception cached" );
87 }
88
89 public function testCallbackTimeout() {
90 $count = 0;
91 $wallClock = microtime( true );
92 $loop = new WaitConditionLoopFakeTime(
93 function () use ( &$count, &$wallClock ) {
94 $wallClock += 3;
95 ++$count;
96
97 return $count > 300 ? true : false;
98 },
99 50.0,
100 $this->newBusyWork( $x, $y, $z, $wallClock )
101 );
102 $loop->setWallClock( $wallClock );
103 $this->assertEquals( $loop::CONDITION_TIMED_OUT, $loop->invoke() );
104 $this->assertEquals( [ 1, 1, 1 ], [ $x, $y, $z ], "Busy work done" );
105
106 $loop = new WaitConditionLoopFakeTime(
107 function () use ( &$count, &$wallClock ) {
108 $wallClock += 3;
109 ++$count;
110
111 return true;
112 },
113 0.0,
114 $this->newBusyWork( $x, $y, $z, $wallClock )
115 );
116 $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke() );
117
118 $count = 0;
119 $loop = new WaitConditionLoopFakeTime(
120 function () use ( &$count, &$wallClock ) {
121 $wallClock += 3;
122 ++$count;
123
124 return $count > 10 ? true : false;
125 },
126 0,
127 $this->newBusyWork( $x, $y, $z, $wallClock )
128 );
129 $this->assertEquals( $loop::CONDITION_FAILED, $loop->invoke() );
130 }
131
132 public function testCallbackAborted() {
133 $x = 0;
134 $wallClock = microtime( true );
135 $loop = new WaitConditionLoopFakeTime(
136 function () use ( &$x, &$wallClock ) {
137 $wallClock += 2;
138 ++$x;
139
140 return $x > 2 ? WaitConditionLoop::CONDITION_ABORTED : false;
141 },
142 10.0,
143 $this->newBusyWork( $x, $y, $z, $wallClock )
144 );
145 $loop->setWallClock( $wallClock );
146 $this->assertEquals( $loop::CONDITION_ABORTED, $loop->invoke() );
147 }
148
149 private function newBusyWork(
150 &$x, &$y, &$z, &$wallClock = 1, &$dontCallMe = null, &$badCalls = 0
151 ) {
152 $x = $y = $z = 0;
153 $badCalls = 0;
154
155 $list = [];
156 $list[] = function () use ( &$x, &$wallClock ) {
157 $wallClock += 1;
158
159 return ++$x;
160 };
161 $dontCallMe = function () use ( &$badCalls ) {
162 ++$badCalls;
163 throw new RuntimeException( "TrollyMcTrollFace" );
164 };
165 $list[] =& $dontCallMe;
166 $list[] = function () use ( &$y, &$wallClock ) {
167 $wallClock += 15;
168
169 return ++$y;
170 };
171 $list[] = function () use ( &$z, &$wallClock ) {
172 $wallClock += 0.1;
173
174 return ++$z;
175 };
176
177 return $list;
178 }
179 }