CredisTestCommon.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. // backward compatibility (https://stackoverflow.com/a/42828632/187780)
  3. if (!class_exists('\PHPUnit\Framework\TestCase') && class_exists('\PHPUnit_Framework_TestCase')) {
  4. class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
  5. }
  6. class CredisTestCommon extends \PHPUnit\Framework\TestCase
  7. {
  8. protected $useStandalone = false;
  9. protected $redisConfig = null;
  10. protected $slaveConfig = null;
  11. protected function setUp()
  12. {
  13. if ($this->redisConfig === null)
  14. {
  15. $configFile = dirname(__FILE__) . '/redis_config.json';
  16. if (!file_exists($configFile) || !($config = file_get_contents($configFile)))
  17. {
  18. $this->markTestSkipped('Could not load ' . $configFile);
  19. return;
  20. }
  21. $this->redisConfig = json_decode($config);
  22. $arrayConfig = array();
  23. foreach ($this->redisConfig as $config)
  24. {
  25. $arrayConfig[] = (array)$config;
  26. }
  27. $this->redisConfig = $arrayConfig;
  28. }
  29. if($this->useStandalone && !extension_loaded('redis')) {
  30. $this->fail('The Redis extension is not loaded.');
  31. }
  32. }
  33. /**
  34. * Verifies the slave has connected to the master and replication has caught up
  35. *
  36. * @return bool
  37. */
  38. protected function waitForSlaveReplication()
  39. {
  40. if ($this->slaveConfig === null)
  41. {
  42. foreach ($this->redisConfig as $config)
  43. {
  44. if ($config['alias'] === 'slave')
  45. {
  46. $this->slaveConfig = $config;
  47. break;
  48. }
  49. }
  50. if ($this->slaveConfig === null)
  51. {
  52. $this->markTestSkipped('Could not load slave config');
  53. return false;
  54. }
  55. }
  56. $masterConfig = new Credis_Client($this->redisConfig[0]['host'], $this->redisConfig[0]['port']);
  57. $masterConfig->forceStandalone();
  58. $slaveConfig = new Credis_Client($this->slaveConfig['host'], $this->slaveConfig['port']);
  59. $slaveConfig->forceStandalone();
  60. while (true)
  61. {
  62. $role = $slaveConfig->role();
  63. if ($role[0] !== 'slave')
  64. {
  65. $this->markTestSkipped('slave config does not points to a slave');
  66. return false;
  67. }
  68. if ($role[3] === 'connected')
  69. {
  70. $masterRole = $masterConfig->role();
  71. if ($masterRole[0] !== 'master')
  72. {
  73. $this->markTestSkipped('master config does not points to a master');
  74. return false;
  75. }
  76. if ($role[4] >= $masterRole[1])
  77. {
  78. return true;
  79. }
  80. }
  81. usleep(100);
  82. }
  83. // shouldn't get here
  84. return false;
  85. }
  86. public static function setUpBeforeClass()
  87. {
  88. if(preg_match('/^WIN/',strtoupper(PHP_OS))){
  89. echo "Unit tests will not work automatically on Windows. Please setup all Redis instances manually:".PHP_EOL;
  90. echo "\tredis-server redis-master.conf".PHP_EOL;
  91. echo "\tredis-server redis-slave.conf".PHP_EOL;
  92. echo "\tredis-server redis-2.conf".PHP_EOL;
  93. echo "\tredis-server redis-3.conf".PHP_EOL;
  94. echo "\tredis-server redis-4.conf".PHP_EOL;
  95. echo "\tredis-server redis-auth.conf".PHP_EOL;
  96. echo "\tredis-server redis-socket.conf".PHP_EOL;
  97. echo "\tredis-sentinel redis-sentinel.conf".PHP_EOL.PHP_EOL;
  98. } else {
  99. chdir(__DIR__);
  100. $directoryIterator = new DirectoryIterator(__DIR__);
  101. foreach($directoryIterator as $item){
  102. if(!$item->isfile() || !preg_match('/^redis\-(.+)\.conf$/',$item->getFilename()) || $item->getFilename() == 'redis-sentinel.conf'){
  103. continue;
  104. }
  105. exec('redis-server '.$item->getFilename());
  106. }
  107. copy('redis-master.conf','redis-master.conf.bak');
  108. copy('redis-slave.conf','redis-slave.conf.bak');
  109. copy('redis-sentinel.conf','redis-sentinel.conf.bak');
  110. exec('redis-sentinel redis-sentinel.conf');
  111. // wait for redis to initialize
  112. usleep(200);
  113. }
  114. }
  115. public static function tearDownAfterClass()
  116. {
  117. if(preg_match('/^WIN/',strtoupper(PHP_OS))){
  118. echo "Please kill all Redis instances manually:".PHP_EOL;
  119. } else {
  120. chdir(__DIR__);
  121. $directoryIterator = new DirectoryIterator(__DIR__);
  122. foreach($directoryIterator as $item){
  123. if(!$item->isfile() || !preg_match('/^redis\-(.+)\.pid$/',$item->getFilename())){
  124. continue;
  125. }
  126. $pid = trim(file_get_contents($item->getFilename()));
  127. if(function_exists('posix_kill')){
  128. posix_kill($pid,15);
  129. } else {
  130. exec('kill '.$pid);
  131. }
  132. }
  133. sleep(1); // give teardown some time to finish
  134. @unlink('dump.rdb');
  135. @unlink('redis-master.conf');
  136. @unlink('redis-slave.conf');
  137. @unlink('redis-sentinel.conf');
  138. @copy('redis-master.conf.bak','redis-master.conf');
  139. @copy('redis-slave.conf.bak','redis-slave.conf');
  140. @copy('redis-sentinel.conf.bak','redis-sentinel.conf');
  141. }
  142. }
  143. //
  144. /**
  145. * php 7.2 compat fix, as directly polyfilling for older PHPUnit causes a function signature compatibility issue
  146. * This is due to the defined return type
  147. *
  148. * Polyfill for older PHPUnit
  149. */
  150. protected function createMockShim($originalClassName)
  151. {
  152. if (method_exists($this, 'getMock')) {
  153. return $this->getMock($originalClassName);
  154. } else {
  155. return parent::createMock($originalClassName);
  156. }
  157. }
  158. /**
  159. * php 7.2 compat fix, as directly polyfilling for older PHPUnit causes a function signature compatibility issue
  160. * This is due to the defined return type
  161. */
  162. public function setExpectedExceptionShim($class, $message = NULL, $code = NULL)
  163. {
  164. if (method_exists($this, 'setExpectedException')) {
  165. $this->setExpectedException($class, $message, $code);
  166. } else {
  167. parent::expectException($class);
  168. if ($message !== null) {
  169. $this->expectExceptionMessage($message);
  170. }
  171. if ($code !== null) {
  172. $this->expectExceptionCode($code);
  173. }
  174. }
  175. }
  176. }