/** * <p> Only use if you require exact peak memory usage etc. * for certain invocations. * * <p> This method may fail if shared memory is getting unavailable due to * size of (in-)directly passed object(s). * * <p> Invocations that directly rely on reflections may not work properly. * * <p> Forked profiling requries PHP compiled with shared memory support * [--enable-sysvshm] and enabled extension [pcntl]. * * @return \Components\Debug_Profiler */ public static function profileCallForked(array $callable_, array $args_ = []) { if (false === static::isForkedProfilingSupported() || false === Memory_Shared_Shm::isSupported()) { throw new Exception_NotSupported('debug/profiler', 'Forked profiling is not supported on this platform\'s configuration.'); } if (false === is_callable($callable_)) { throw new Exception_IllegalArgument('debug/profiler', 'Valid callback expected.'); } $shm = Memory_Shared_Shm_Temporary::create(); $shm->attach(); self::$m_profileForkedArgs = $args_; self::$m_profileForkedCallable = $callable_; self::$m_profileForkedSegmentId = $shm->getSegmentId(); $pid = pcntl_fork(); if (-1 == $pid) { throw new Exception_IllegalState('debug/profiler', 'Unable to fork child process. Forked profiling failed.'); } if ($pid) { $pid = pcntl_wait($status); } else { ob_start(); $sessionId = static::start(); try { $returnValue = call_user_func_array(self::$m_profileForkedCallable, self::$m_profileForkedArgs); $profiler = static::stop($sessionId); $profiler->m_returnValue = $returnValue; } catch (\ErrorException $e) { $profiler = static::stop($sessionId); $profiler->m_exception = Exception_Flat::create($e); } catch (\Exception $e) { $profiler = static::stop($sessionId); $profiler->m_exception = Exception_Flat::create($e); } self::$m_profileForkedArgs = null; self::$m_profileForkedCallable = null; $segment = Memory_Shared_Shm::forSegment(self::$m_profileForkedSegmentId); $segment->attach(); $segment->set(1, ob_get_clean()); $segment->set(2, $profiler->result()->m_exception); $segment->set(3, $profiler->result()->m_memoryConsumptionAfter); $segment->set(4, $profiler->result()->m_memoryConsumptionBefore); $segment->set(5, $profiler->result()->m_memoryConsumptionPeak); $segment->set(6, $profiler->result()->m_posixSystemTime); $segment->set(7, $profiler->result()->m_posixUserTime); $segment->set(8, $profiler->result()->m_returnValue); $segment->set(9, $profiler->result()->m_timeStart); $segment->set(10, $profiler->result()->m_timeStop); $segment->set(11, $profiler->result()->m_splitTimeTable); exit(0); } echo $shm->get(1); $profiler = new static(); $profiler->m_profiling = false; $profiler->m_exception = $shm->get(2); $profiler->m_memoryConsumptionAfter = $shm->get(3); $profiler->m_memoryConsumptionBefore = $shm->get(4); $profiler->m_memoryConsumptionPeak = $shm->get(5); $profiler->m_posixSystemTime = $shm->get(6); $profiler->m_posixUserTime = $shm->get(7); $profiler->m_returnValue = $shm->get(8); $profiler->m_timeStart = $shm->get(9); $profiler->m_timeStop = $shm->get(10); $profiler->m_splitTimeTable = $shm->get(11); $shm->clear(); return $profiler; }
protected function invokeTest(Test_Unit_Internal_DynamicProxy $case_, \ReflectionMethod $test_, Test_Result $result_) { Assertion_Context::push(new Assertion_Context()); $start = microtime(true); $case_->{$test_->name}(); $result_->processingTime = microtime(true) - $start; $context = Assertion_Context::pop(); foreach ($context->getAssertions() as $assertion) { $assertionResult = $result_->create(Test_Result::TYPE_ASSERTION); $assertionResult->name = $assertion['name']; $assertionResult->output = $assertion['message']; if (false === $assertion['result']) { $assertionResult->addState(Test_Result::STATE_FAILED); } } $failed = $case_->isFailed($test_); $failedExpected = $case_->isFailedExpected($test_); $failedAssertions = $result_->count(Test_Result::TYPE_ASSERTION, Test_Result::STATE_FAILED, true); if (($failed || 0 < $failedAssertions) && false === $failedExpected || false === $failed && 1 > $failedAssertions && $failedExpected) { $result_->addState(Test_Result::STATE_FAILED); $result_->exception = $case_->getException($test_); if (null === $result_->exception && ($expectedExceptionClass = $case_->getExpectedExceptionClass($test_))) { $result_->exception = Exception_Flat::createEmpty(); $result_->exception->message = sprintf('Expected exception not thrown [%1$s].', $expectedExceptionClass); } } if ($profiler = $case_->getProfilerResult($test_)) { $result_->processingTime = $profiler->processingTime(); $result_->profilerMemoryConsumption = $profiler->memoryConsumptionAsString(); $result_->profilerPosixTimes = $profiler->posixTimesAsString(); $result_->profilerProcessingTime = $profiler->processingTimeAsString(); $result_->profilerSplitTimeTable = $profiler->splitTimeTable(); } $result_->output = $case_->getOutput($test_); }
public function __call($key_, $args_) { if (null === ($method = $this->getMethod($key_))) { return null; } // FIXME Re-integrate profiling. $profileMethod = 'profileCall'; if (Test_Profiler::isForkedProfilingSupported() && array_key_exists($method->name, $this->m_profileMethodsForked)) { $profileMethod = 'profileCallForked'; } ob_start(); $returnValue = null; if (true === array_key_exists($method->name, $this->m_profileMethods)) { $this->m_profileMethods[$method->name] = Test_Profiler::$profileMethod([$this->m_instance, $this->m_methods[$method->name]->name]); $this->m_exceptions[$method->name] = $this->m_profileMethods[$method->name]->exception(); $returnValue = $this->m_profileMethods[$method->name]->returnValue(); } else { try { if ($this->m_methods[$method->name]->isStatic()) { $returnValue = $this->m_methods[$method->name]->invoke($this->m_class); } else { $returnValue = $this->m_instance->{$this->m_methods[$method->name]->name}(); } } catch (\Exception $e) { $this->m_exceptions[$method->name] = Exception_Flat::create($e); } } $this->m_failed[$method->name] = true; if (false === isset($this->m_exceptionsExpected[$method->name]) && false === isset($this->m_exceptions[$method->name])) { $this->m_failed[$method->name] = false; } else { if (isset($this->m_exceptionsExpected[$method->name]) && isset($this->m_exceptions[$method->name])) { if ($this->m_exceptionsExpected[$method->name] == $this->m_exceptions[$method->name]->type) { $this->m_failed[$method->name] = false; } else { $exceptionReflection = new \ReflectionClass($this->m_exceptions[$method->name]); if ($exceptionReflection->isSubclassOf($this->m_exceptionsExpected[$method->name])) { $this->m_failed[$method->name] = false; } } } } if (trim($output = ob_get_clean())) { $this->m_output[$method->name] = $output; } return $returnValue; }