Skip to content

Commit 7aac985

Browse files
committed
Added process isolition for tests
1 parent 4984176 commit 7aac985

File tree

5 files changed

+197
-81
lines changed

5 files changed

+197
-81
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ before_install:
4444
cheprasov/redis-cluster-for-tests
4545
4646
- docker ps;
47-
- sleep 15;
47+
- sleep 5;
4848

4949
install:
5050
- composer install

phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
convertErrorsToExceptions = "true"
77
convertNoticesToExceptions = "true"
88
convertWarningsToExceptions = "true"
9-
processIsolation = "true"
9+
processIsolation = "false"
1010
stopOnFailure = "true"
1111
stopOnError = "true"
1212
stopOnIncomplete = "false"
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
/**
3+
* This file is part of RedisClient.
4+
* git: https://github.com/cheprasov/php-redis-client
5+
*
6+
* (C) Alexander Cheprasov <cheprasov.84@ya.ru>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
namespace Test\Unit\Client;
12+
13+
include_once(__DIR__ . '/../GlobalFunctionMock.php');
14+
15+
use RedisClient\Client\AbstractRedisClient;
16+
use RedisClient\Exception\MovedResponseException;
17+
use RedisClient\RedisClient;
18+
use Test\Unit\GlobalFunctionMock;
19+
20+
/**
21+
* @see AbstractRedisClient
22+
* @runTestsInSeparateProcesses
23+
*/
24+
class AbstractRedisClientIsolatedTest extends \PHPUnit_Framework_TestCase {
25+
26+
public function setUp() {
27+
$this->mockStream();
28+
}
29+
30+
protected function mockStream() {
31+
GlobalFunctionMock::mockFunction('RedisClient\Connection::stream_socket_client', function($s) {return $s;});
32+
GlobalFunctionMock::mockFunction('RedisClient\Connection::stream_set_timeout', function() {return true;});
33+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fwrite', function($h, $m, $c) {return $c;});
34+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fgets', function() {return '';});
35+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fread', function() {return '';});
36+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fclose', function() {return true;});
37+
}
38+
39+
public function test_mockStream() {
40+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fgets', function() {
41+
return "+TEST\r\n";
42+
});
43+
44+
$Redis = new RedisClient();
45+
$this->assertSame('TEST', $Redis->ping());
46+
unset($Redis);
47+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_socket_client'));
48+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_set_timeout'));
49+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fwrite'));
50+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fgets'));
51+
$this->assertSame(0, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fread'));
52+
$this->assertSame(0, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fclose'));
53+
}
54+
55+
public function test_MovedErrorResponse() {
56+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fwrite', function($h, $m, $c) {
57+
$this->assertSame('tcp://127.0.0.1:6379', $h);
58+
$this->assertSame("*2\r\n$3\r\nGET\r\n$3\r\nkey\r\n", $m);
59+
$this->assertSame(22, $c);
60+
return $c;
61+
});
62+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fgets', function() {
63+
return "-MOVED 42 server\r\n";
64+
});
65+
66+
$Redis = new RedisClient();
67+
try {
68+
$Redis->get('key');
69+
$this->assertTrue(false, 'Expect MovedResponseException');
70+
} catch (\Exception $Ex) {
71+
/** @var MovedResponseException $Ex*/
72+
$this->assertSame(true, $Ex instanceof MovedResponseException);
73+
$this->assertSame(42, $Ex->getSlot());
74+
$this->assertSame('server', $Ex->getServer());
75+
}
76+
77+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_socket_client'));
78+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_set_timeout'));
79+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fwrite'));
80+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fgets'));
81+
$this->assertSame(0, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fread'));
82+
}
83+
84+
public function test_ClusterEmptyMovedErrorResponse() {
85+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fwrite', function($h, $m, $c) {
86+
static $servers = [
87+
'tcp://127.0.0.1:7001',
88+
'tcp://127.0.0.1:7003',
89+
];
90+
$this->assertSame(array_shift($servers), $h);
91+
$this->assertSame("*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n", $m);
92+
$this->assertSame(22, $c);
93+
return $c;
94+
});
95+
96+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fgets', function() {
97+
static $data = [
98+
"-MOVED 12182 127.0.0.1:7003\r\n",
99+
"\$3\r\n",
100+
];
101+
return array_shift($data);
102+
});
103+
104+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fread', function() {
105+
return "bar\r\n";
106+
});
107+
108+
$Redis = new RedisClient([
109+
'server' => '127.0.0.1:7001',
110+
'cluster' => [
111+
'enabled' => true,
112+
'clusters' => []
113+
]
114+
]);
115+
116+
$this->assertSame('bar', $Redis->get('foo'));
117+
118+
$this->assertSame(2, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_socket_client'));
119+
$this->assertSame(2, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_set_timeout'));
120+
$this->assertSame(2, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fwrite'));
121+
$this->assertSame(2, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fgets'));
122+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fread'));
123+
}
124+
125+
public function test_ClusterFullMovedErrorResponse() {
126+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fwrite', function($h, $m, $c) {
127+
$this->assertSame('tcp://127.0.0.1:7003', $h);
128+
$this->assertSame("*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n", $m);
129+
$this->assertSame(22, $c);
130+
return $c;
131+
});
132+
133+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fgets', function() {
134+
return "\$3\r\n";
135+
});
136+
137+
GlobalFunctionMock::mockFunction('RedisClient\Connection::fread', function() {
138+
return "bar\r\n";
139+
});
140+
141+
$Redis = new RedisClient([
142+
'server' => '127.0.0.1:7001',
143+
'cluster' => [
144+
'enabled' => true,
145+
'clusters' => [
146+
5460 => '127.0.0.1:7001',
147+
10922 => '127.0.0.1:7002',
148+
16383 => '127.0.0.1:7003',
149+
]
150+
]
151+
]);
152+
153+
$this->assertSame('bar', $Redis->get('foo'));
154+
155+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_socket_client'));
156+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::stream_set_timeout'));
157+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fwrite'));
158+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fgets'));
159+
$this->assertSame(1, GlobalFunctionMock::getCountCalls('RedisClient\Connection::fread'));
160+
}
161+
}

tests/Unit/Client/AbstractRedisClientTest.php

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@
1111
namespace Test\Unit\Client;
1212

1313
use RedisClient\Client\AbstractRedisClient;
14-
use RedisClient\Exception\EmptyResponseException;
15-
use RedisClient\Exception\MovedResponseException;
1614
use RedisClient\RedisClient;
17-
use Test\Unit\GlobalFunctionMock;
1815

1916
/**
2017
* @see AbstractRedisClient
21-
* @runTestsInSeparateProcesses
2218
*/
2319
class AbstractRedisClientTest extends \PHPUnit_Framework_TestCase {
2420

@@ -100,65 +96,4 @@ public function test_getStructure($expect, $command, $params) {
10096
$this->assertSame($expect, $Method->invoke($Client, $command, $params));
10197
}
10298

103-
protected function mockStream() {
104-
include_once(__DIR__ . '/../GlobalFunctionMock.php');
105-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'stream_socket_client', function() {return true;});
106-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'stream_set_timeout', function() {return true;});
107-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fwrite', function($h, $m, $c) {return $c;});
108-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fgets', function() {return '';});
109-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fread', function() {return '';});
110-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fclose', function() {return true;});
111-
}
112-
113-
public function test_mockStream() {
114-
$this->mockStream();
115-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fgets', function() {
116-
return "+TEST\r\n";
117-
});
118-
119-
$Redis = new RedisClient();
120-
$this->assertSame('TEST', $Redis->ping());
121-
unset($Redis);
122-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('stream_socket_client'));
123-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('stream_set_timeout'));
124-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('fwrite'));
125-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('fgets'));
126-
$this->assertSame(0, GlobalFunctionMock::getCountCalls('fread'));
127-
$this->assertSame(0, GlobalFunctionMock::getCountCalls('fclose'));
128-
}
129-
130-
public function test_stream() {
131-
$Redis = new RedisClient();
132-
$this->assertSame('PONG', $Redis->ping());
133-
}
134-
135-
public function test_MovedErrorResponse() {
136-
$this->mockStream();
137-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fwrite', function($h, $m, $c) {
138-
$this->assertSame(true, $h);
139-
$this->assertSame("*2\r\n$3\r\nGET\r\n$3\r\nkey\r\n", $m);
140-
$this->assertSame(22, $c);
141-
return $c;
142-
});
143-
GlobalFunctionMock::mockFunction('RedisClient\Connection', 'fgets', function() {
144-
return "-MOVED 42 server\r\n";
145-
});
146-
147-
$Redis = new RedisClient();
148-
try {
149-
$Redis->get('key');
150-
$this->assertTrue(false, 'Expect MovedResponseException');
151-
} catch (\Exception $Ex) {
152-
/** @var MovedResponseException $Ex*/
153-
$this->assertSame(true, $Ex instanceof MovedResponseException);
154-
$this->assertSame(42, $Ex->getSlot());
155-
$this->assertSame('server', $Ex->getServer());
156-
}
157-
158-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('stream_socket_client'));
159-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('stream_set_timeout'));
160-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('fwrite'));
161-
$this->assertSame(1, GlobalFunctionMock::getCountCalls('fgets'));
162-
$this->assertSame(0, GlobalFunctionMock::getCountCalls('fread'));
163-
}
16499
}

tests/Unit/GlobalFunctionMock.php

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,40 @@ class GlobalFunctionMock {
1414

1515
protected static $mockedFunctions = [];
1616

17+
public static function resetMockFunctions() {
18+
static::$mockedFunctions = [];
19+
}
20+
1721
/**
18-
* @param string $namespace
19-
* @param string $name
22+
* @param string $fullname
2023
* @param callable $function
2124
*/
22-
public static function mockFunction($namespace, $name, $function) {
23-
if (empty(static::$mockedFunctions[$name])) {
25+
public static function mockFunction($fullname, $function) {
26+
if (false !== strpos($fullname, '::')) {
27+
list($namespace, $name) = explode('::', $fullname, 2);
28+
} else {
29+
$namespace = '';
30+
$name = $fullname;
31+
}
32+
if (empty(static::$mockedFunctions[$fullname])) {
2433
$eval = [];
2534
if ($namespace) {
2635
$eval[] = "namespace {$namespace};";
2736
}
2837
$eval[] = "function {$name}(){
29-
return call_user_func_array('\\Test\\Unit\\GlobalFunctionMock::{$name}', func_get_args());
38+
return \\Test\\Unit\\GlobalFunctionMock::invokeMockedFunction(
39+
'{$fullname}',
40+
'{$name}',
41+
'{$namespace}',
42+
func_get_args()
43+
);
3044
};";
3145
eval(implode("\n", $eval));
3246
}
33-
static::$mockedFunctions[$name] = [
47+
static::$mockedFunctions[$fullname] = [
48+
'fullname' => $fullname,
3449
'name' => $name,
50+
'namespace' => $namespace,
3551
'called' => 0,
3652
'function' => $function,
3753
];
@@ -49,21 +65,25 @@ public static function getCountCalls($name) {
4965
}
5066

5167
/**
52-
* @param string $name
53-
* @param array $args
68+
* @param $fullname
69+
* @param $name
70+
* @param $namespace
71+
* @param $args
5472
* @return mixed
5573
* @throws \Exception
5674
*/
57-
public static function __callStatic($name, $args) {
58-
if (empty(static::$mockedFunctions[$name])) {
59-
if (is_callable($name)) {
60-
return call_user_func_array($name, $args);
75+
public static function invokeMockedFunction($fullname, $name, $namespace, $args) {
76+
if (empty(static::$mockedFunctions[$fullname])) {
77+
if (is_callable('\\' . $name)) {
78+
$e = call_user_func_array('\\' . $name, $args);
79+
var_dump($e);exit;
80+
return $e;
6181
}
6282
throw new \Exception("Can not to call function '{$name}'");
6383
}
64-
$function = static::$mockedFunctions[$name]['function'];
84+
$function = static::$mockedFunctions[$fullname]['function'];
6585
$result = call_user_func_array($function, $args);
66-
static::$mockedFunctions[$name]['called'] += 1;
86+
static::$mockedFunctions[$fullname]['called'] += 1;
6787
return $result;
6888
}
6989

0 commit comments

Comments
 (0)