public function testMergeFailDelayed()
 {
     /*
      * Test concurrent merges by forking this process, if:
      * - not manually called with --use-bagostuff
      * - pcntl_fork is supported by the system
      * - cache type will correctly support calls over forks
      */
     $fork = (bool) $this->getCliArg('use-bagostuff');
     $fork &= function_exists('pcntl_fork');
     $fork &= !$this->cache instanceof HashBagOStuff;
     $fork &= !$this->cache instanceof EmptyBagOStuff;
     $fork &= !$this->cache instanceof MultiWriteBagOStuff;
     if (!$fork) {
         $this->markTestSkipped("Unable to fork, can't test merge");
     }
     $this->cache->set('key', 'value');
     $callback = function (\BagOStuff $cache, $key, $value) {
         // prepend merged to whatever is in cache
         return 'merged-' . (string) $value;
     };
     $this->bufferedCache->merge('key', $callback, 0, 1);
     // callback should take awhile now so that we can test concurrent merge attempts
     $pid = pcntl_fork();
     if ($pid == -1) {
         // can't fork, ignore this test...
     } elseif ($pid) {
         // wait a little, making sure that the child process is calling merge
         usleep(3000);
         // attempt a merge - this should fail to persist to real cache
         $this->bufferedCache->commit();
         // make sure the child's merge is completed and verify
         usleep(3000);
         // check that the values failed to merge
         $this->assertEquals(false, $this->bufferedCache->get('key'));
         $this->assertEquals(false, $this->cache->get('key'));
     } else {
         $this->bufferedCache->commit();
         // before exiting, tear down - MediaWikiTestCase will check for it
         // on destruct & throw an exception if it wasn't called
         $this->tearDown();
         // Note: I'm not even going to check if the merge worked, I'll
         // compare values in the parent process to test if this merge worked.
         // I'm just going to exit this child process, since I don't want the
         // child to output any test results (would be rather confusing to
         // have test output twice)
         exit;
     }
 }
 /**
  * @param string $key
  * @param Closure $callback
  * @param int $attempts
  * @return bool
  */
 public function merge($key, Closure $callback, $attempts = 10)
 {
     return $this->cache->merge($key, $callback, $this->exptime, $attempts);
 }