/**
  * Ensures that we can put objects of various types in shared memory and
  * retrieve them unchanged (between processes).
  */
 public function testInterProcessUsage()
 {
     $mem = new SharedMemory(self::$_mutex, SharedMemory::getRequiredBytes(array_values(self::$_testValues)));
     $bootstrapFile = realpath(__DIR__ . '/../classLoader.inc.php');
     $this->assertNotFalse($bootstrapFile);
     $cmd = 'env phpunit --no-configuration --bootstrap=' . $bootstrapFile . ' --filter=testPutValues ' . __FILE__ . ' > /dev/null';
     pclose(popen($cmd, 'r'));
     $this->_runTests($mem);
 }
Esempio n. 2
0
 /**
  * Handles certain setup tasks. This is the kind of thing that a
  * constructor would handle, but since this is an abstract class and I want
  * child classes to be free to accept any arguments they want, I'm not
  * using a constructor here.
  */
 private function _setupInstance()
 {
     if (!self::$_testedGenericSettings) {
         \PFXUtils::validateSettings(self::$_SETTINGS, self::$_SETTING_TESTS);
         self::_buildDefaultHTTPActionMap();
         self::$_validator = new \Validator();
     }
     /* If there is an exception type configured, validate that it really
     		exists. Otherwise default to RuntimeException. */
     if ($this->_EXCEPTION_TYPE) {
         if (!class_exists($this->_EXCEPTION_TYPE) || !is_a($this->_EXCEPTION_TYPE, 'Exception', true)) {
             throw new \Exception('Exception types registered in descendants of this ' . 'class must be valid Exception subclasses.');
         }
     } else {
         $this->_EXCEPTION_TYPE = 'RuntimeException';
     }
     if ($this->_responseFormat && array_key_exists($this->_responseFormat, self::$_STANDARD_PARSE_CALLBACKS)) {
         $callbackData = self::$_STANDARD_PARSE_CALLBACKS[$this->_responseFormat];
         $callback = array_shift($callbackData);
         $this->_registerParseCallback($callback, $callbackData);
     }
     self::$_validator->number($this->_responseTries, 'The number of attempts to use when connecting to API URLs ' . 'must be a non-zero integer.', \Validator::ASSERT_INT_DEFAULT);
     self::$_validator->number($this->_repeatPauseInterval, 'The number of seconds to wait before repeating an API ' . 'request must be a positive integer.', \Validator::ASSERT_INT | \Validator::ASSERT_POSITIVE);
     if ($this->_requestDelayInterval !== null) {
         self::$_validator->number($this->_requestDelayInterval, 'Delay intervals must be positive integers.', \Validator::ASSERT_INT | \Validator::ASSERT_POSITIVE);
         /* In order to observe this delay across processes, we need to have
         			a mutex and use shared memory. */
         try {
             if (!$this->_mutex) {
                 $this->_mutex = new \Mutex($this);
             }
             /* We will be keeping track of a millisecond timestamp, which
             			means 13 digits. */
             $allocBytes = \SharedMemory::getRequiredBytes(array(1000000000000));
             $this->_shmSegment = new \SharedMemory($this->_mutex, $allocBytes);
         } catch (\Exception $e) {
             throw new $this->_EXCEPTION_TYPE('Caught error while configuring shared memory segment.', null, $e);
         }
         /* Not only do we need to keep track of the delay interval, but we
         			also need a variable name that reflects the specific subclass for
         			which we are tracking this interval. */
         $this->_lastRequestTimeVarName = 'req' . get_class($this);
     }
     foreach (self::$_HTTP_RESPONSE_DEFAULT_MAP as $code => $action) {
         /* If the child has already registered certain actions in any of
         			these positions, skip them. */
         if (!array_key_exists($code, $this->_httpResponseActionMap)) {
             $this->_httpResponseActionMap[$code] = $action;
         }
     }
     $this->_instanceSetupComplete = true;
 }