Skip to content
This repository has been archived by the owner on Nov 29, 2021. It is now read-only.

Commit

Permalink
Merge pull request #52 from philkra/development
Browse files Browse the repository at this point in the history
Allow manually Transaction start time
  • Loading branch information
philkra authored Feb 21, 2019
2 parents 61b017b + ef83f84 commit 9bce623
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 14 deletions.
9 changes: 6 additions & 3 deletions src/Agent.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,19 @@ public function __construct(array $config, array $sharedContext = [], EventFacto
*
* @return Transaction
*/
public function startTransaction(string $name, array $context = []): Transaction
public function startTransaction(string $name, array $context = [], float $start = null): Transaction
{
// Create and Store Transaction
$this->transactionsStore->register(
$this->eventFactory->createTransaction($name, array_replace_recursive($this->sharedContext, $context))
$this->eventFactory->createTransaction($name, array_replace_recursive($this->sharedContext, $context), $start)
);

// Start the Transaction
$transaction = $this->transactionsStore->fetch($name);
$transaction->start();

if (null === $start) {
$transaction->start();
}

return $transaction;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Events/DefaultEventFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public function createError(\Throwable $throwable, array $contexts): Error
/**
* {@inheritdoc}
*/
public function createTransaction(string $name, array $contexts): Transaction
public function createTransaction(string $name, array $contexts, float $start = null): Transaction
{
return new Transaction($name, $contexts);
return new Transaction($name, $contexts, $start);
}
}
2 changes: 1 addition & 1 deletion src/Events/EventFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ public function createError(\Throwable $throwable, array $contexts): Error;
* @param string $name
* @param array $contexts
*/
public function createTransaction(string $name, array $contexts): Transaction;
public function createTransaction(string $name, array $contexts, float $start = null): Transaction;
}
4 changes: 2 additions & 2 deletions src/Events/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ class Transaction extends EventBean implements \JsonSerializable
* @param string $name
* @param array $contexts
*/
public function __construct(string $name, array $contexts)
public function __construct(string $name, array $contexts, $start = null)
{
parent::__construct($contexts);
$this->setTransactionName($name);
$this->timer = new Timer();
$this->timer = new Timer($start);
}

/**
Expand Down
13 changes: 13 additions & 0 deletions src/Exception/Timer/AlreadyRunningException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
namespace PhilKra\Exception\Timer;

/**
* Trying to stop a Timer that is already running
*/
class AlreadyRunningException extends \Exception {

public function __construct( string $message = '', int $code = 0, \Throwable $previous = NULL ) {
parent::__construct( 'Can\'t start a timer which is already running.', $code, $previous );
}

}
11 changes: 11 additions & 0 deletions src/Helper/Timer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PhilKra\Helper;

use PhilKra\Exception\Timer\AlreadyRunningException;
use PhilKra\Exception\Timer\NotStartedException;
use PhilKra\Exception\Timer\NotStoppedException;

Expand All @@ -24,13 +25,23 @@ class Timer
*/
private $stoppedOn = null;

public function __construct(float $startTime = null)
{
$this->startedOn = $startTime;
}

/**
* Start the Timer
*
* @return void
* @throws AlreadyRunningException
*/
public function start()
{
if (null !== $this->startedOn) {
throw new AlreadyRunningException();
}

$this->startedOn = microtime(true);
}

Expand Down
26 changes: 26 additions & 0 deletions tests/AgentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ public function testStartAndStopATransaction() {
$this->assertNotEmpty( $summary['backtrace'] );
}

/**
* @covers \PhilKra\Agent::__construct
* @covers \PhilKra\Agent::startTransaction
* @covers \PhilKra\Agent::stopTransaction
* @covers \PhilKra\Agent::getTransaction
*/
public function testStartAndStopATransactionWithExplicitStart() {
$agent = new Agent( [ 'appName' => 'phpunit_1' ] );

// Create a Transaction, wait and Stop it
$name = 'trx';
$agent->startTransaction( $name, [], microtime(true) - 1);
usleep( 500 * 1000 ); // sleep milliseconds
$agent->stopTransaction( $name );

// Transaction Summary must be populated
$summary = $agent->getTransaction( $name )->getSummary();

$this->assertArrayHasKey( 'duration', $summary );
$this->assertArrayHasKey( 'backtrace', $summary );

// Expect duration in milliseconds
$this->assertDurationIsWithinThreshold(1500, $summary['duration'], 150);
$this->assertNotEmpty( $summary['backtrace'] );
}

/**
* @depends testStartAndStopATransaction
*
Expand Down
28 changes: 28 additions & 0 deletions tests/Helper/TimerTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace PhilKra\Tests\Helper;

use PhilKra\Exception\Timer\AlreadyRunningException;
use \PhilKra\Helper\Timer;
use PhilKra\Tests\TestCase;

Expand Down Expand Up @@ -92,4 +93,31 @@ public function testCannotBeStoppedWithoutStart() {
$timer->stop();
}

/**
* @covers \PhilKra\Helper\Timer::start
* @covers \PhilKra\Helper\Timer::getDurationInMilliseconds
*/
public function testCanBeStartedWithExplicitStartTime() {
$timer = new Timer(microtime(true) - .5); // Start timer 500 milliseconds ago

usleep(500 * 1000); // Sleep for 500 milliseconds

$timer->stop();

$duration = $timer->getDurationInMilliseconds();

// Duration should be more than 1000 milliseconds
// sum of initial offset and sleep
$this->assertGreaterThanOrEqual(1000, $duration);
}

/**
* @covers \PhilKra\Helper\Timer::start
*/
public function testCannotBeStartedIfAlreadyRunning() {
$timer = new Timer(microtime(true));

$this->expectException(AlreadyRunningException::class);
$timer->start();
}
}
10 changes: 4 additions & 6 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@
abstract class TestCase extends \PHPUnit\Framework\TestCase
{

protected function assertDurationIsWithinThreshold(int $sleptMilliseconds, float $timedDuration)
protected function assertDurationIsWithinThreshold(int $expectedMilliseconds, float $timedDuration, float $maxOverhead = 10)
{
$this->assertGreaterThanOrEqual( $sleptMilliseconds, $timedDuration );
$this->assertGreaterThanOrEqual( $expectedMilliseconds, $timedDuration );

// Generally we should expect less than 1ms of overhead, but that is not guaranteed.
// 10ms should be enough unless the test system is really unresponsive.
$overhead = ($timedDuration - $sleptMilliseconds);
$this->assertLessThanOrEqual( 10, $overhead );
$overhead = ($timedDuration - $expectedMilliseconds);
$this->assertLessThanOrEqual( $maxOverhead, $overhead );
}

}

0 comments on commit 9bce623

Please sign in to comment.