public function testShouldDoWork()
{
if (!class_exists('\\duncan3dc\\Helpers\\Fork') && !class_exists('\\duncan3dc\\Forker\\Fork')) {
$this->markTestSkipped(sprintf('%s uses fork-helper as a dependency. You can install it by running: ' . 'composer require duncan3dc/fork-helper', get_class($this->client)));
}
$memory = shmop_open($this->shmKey, 'c', 0644, $this->shmLimit);
if (false === $memory) {
$this->markTestSkipped('Cannot create shared memory block');
} else {
shmop_close($memory);
}
$expected = ['test-tube-1' => '1', 'test-tube-2' => '2'];
# Check if we are using Fork1.0 (php < 7)
if (class_exists('duncan3dc\\Helpers\\Fork')) {
$fork = new \duncan3dc\Helpers\Fork();
} else {
$fork = new \duncan3dc\Forker\Fork();
}
$fork->call(function () use($expected) {
foreach ($expected as $tube => $value) {
$this->client->addWorker($tube, function (Job $job) {
// Store string "test-tube-%JOB_BODY%" in a shared memory
$memory = shmop_open($this->shmKey, 'c', 0644, $this->shmLimit);
$output = trim(shmop_read($memory, 0, $this->shmLimit));
$output .= sprintf("\ntest-tube-%s", $job->getBody());
shmop_write($memory, $output, 0);
shmop_close($memory);
throw new \RuntimeException('Forced exception to stop worker');
});
$this->assertNotEquals(false, $this->client->putInTube($tube, $value));
}
$this->client->doWork();
exit(0);
});
$reflectionFork = new \ReflectionClass($fork);
$reflectionThreads = $reflectionFork->getProperty('threads');
$reflectionThreads->setAccessible(true);
sleep(2);
$reflectionThreads->setValue($fork, []);
unset($fork);
$memory = shmop_open($this->shmKey, 'a', 0, 0);
$output = shmop_read($memory, 0, $this->shmLimit);
$this->assertTrue(shmop_delete($memory));
shmop_close($memory);
$this->assertNotEmpty($output);
$actual = explode("\n", trim($output));
// Compare number of items in expected list with lines in shared memory
$this->assertEquals(count($expected), count($actual));
foreach ($actual as $value) {
$this->assertArrayHasKey($value, $expected);
}
}