objectcache: allow for callbacks to mask SYNC_WRITE latency
[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
107 public function testCallbackAborted() {
108 $x = 0;
109 $wallClock = microtime( true );
110 $loop = new WaitConditionLoopFakeTime(
111 function () use ( &$x, &$wallClock ) {
112 $wallClock += 2;
113 ++$x;
114
115 return $x > 2 ? WaitConditionLoop::CONDITION_ABORTED : false;
116 },
117 10.0,
118 $this->newBusyWork( $x, $y, $z, $wallClock )
119 );
120 $loop->setWallClock( $wallClock );
121 $this->assertEquals( $loop::CONDITION_ABORTED, $loop->invoke() );
122 }
123
124 private function newBusyWork(
125 &$x, &$y, &$z, &$wallClock = 1, &$dontCallMe = null, &$badCalls = 0
126 ) {
127 $x = $y = $z = 0;
128 $badCalls = 0;
129
130 $list = [];
131 $list[] = function () use ( &$x, &$wallClock ) {
132 $wallClock += 1;
133
134 return ++$x;
135 };
136 $dontCallMe = function () use ( &$badCalls ) {
137 ++$badCalls;
138 throw new RuntimeException( "TrollyMcTrollFace" );
139 };
140 $list[] =& $dontCallMe;
141 $list[] = function () use ( &$y, &$wallClock ) {
142 $wallClock += 15;
143
144 return ++$y;
145 };
146 $list[] = function () use ( &$z, &$wallClock ) {
147 $wallClock += 0.1;
148
149 return ++$z;
150 };
151
152 return $list;
153 }
154 }