Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracer references tests #759

Merged
merged 3 commits into from
Jul 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
adding tests for tracer provider behaviour
a recent bug highlighted that if there is no reference to a tracer provider, then the shared state will shutdown, even if that shared state is being used by active tracers. Adding a phpdoc comment explaining this behavior, and some tests to demonstrate it
  • Loading branch information
brettmc committed Jul 11, 2022
commit 30c7c4d739142935283f471a8d9cf4bdd7672aa6
4 changes: 2 additions & 2 deletions examples/traces/demo/src/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@

//middleware starts root span based on route pattern, sets status from http code
$app->add(function (Request $request, RequestHandler $handler) use ($tracer) {
$carrier = TraceContextPropagator::getInstance()->extract($request->getHeaders());
$parent = TraceContextPropagator::getInstance()->extract($request->getHeaders());
$routeContext = RouteContext::fromRequest($request);
$route = $routeContext->getRoute();
$root = $tracer->spanBuilder($route->getPattern())
->setStartTimestamp((int) ($request->getServerParams()['REQUEST_TIME_FLOAT'] * 1e9))
->setParent($carrier)
->setParent($parent)
->setSpanKind(SpanKind::KIND_SERVER)
->startSpan();
$root->activate();
Expand Down
6 changes: 5 additions & 1 deletion src/SDK/Trace/TracerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ public function forceFlush(): bool
return $this->tracerSharedState->getSpanProcessor()->forceFlush();
}

/** @inheritDoc */
/**
* @inheritDoc
* @note Getting a tracer without keeping a strong reference to the TracerProvider will cause the TracerProvider to
* immediately shut itself down including its shared state, ie don't do this: $tracer = (new TracerProvider())->getTracer('foo')
*/
public function getTracer(
string $name,
?string $version = null,
Expand Down
1 change: 1 addition & 0 deletions tests/Unit/SDK/Trace/TracerProviderFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Psr\Log\LoggerInterface;

/**
* @covers \OpenTelemetry\SDK\Trace\TracerProviderFactory
* @coversDefaultClass \OpenTelemetry\SDK\Trace\TracerProviderFactory
*/
class TracerProviderFactoryTest extends TestCase
Expand Down
37 changes: 37 additions & 0 deletions tests/Unit/SDK/Trace/TracerProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

use OpenTelemetry\API\Trace\NoopTracer;
use OpenTelemetry\SDK\Trace\SamplerInterface;
use OpenTelemetry\SDK\Trace\SpanProcessorInterface;
use OpenTelemetry\SDK\Trace\TracerProvider;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophet;
use WeakReference;

/**
Expand Down Expand Up @@ -130,4 +132,39 @@ public function test_tracer_register_shutdown_function_does_not_leak_reference()
$provider = null;
$this->assertTrue($reference->get() === null);
}

/**
* @doesNotPerformAssertions
*/
public function test_tracer_shuts_down_immediately_when_out_of_scope(): void
{
$prophet = new Prophet();
$spanProcessor = $prophet->prophesize(SpanProcessorInterface::class);
// @phpstan-ignore-next-line
$spanProcessor->shutdown()
->shouldBeCalledTimes(1);

/* because no reference is kept to the TracerProvider, it will immediately __destruct and shutdown,
which will also shut down span processors. This is a trade-off */
$tracer = (new TracerProvider($spanProcessor->reveal()))->getTracer('test');

$spanProcessor->checkProphecyMethodsPredictions();
}

/**
* @doesNotPerformAssertions
*/
public function test_tracer_remains_in_scope(): void
{
$prophet = new Prophet();
$spanProcessor = $prophet->prophesize(SpanProcessorInterface::class);
// @phpstan-ignore-next-line
$spanProcessor->shutdown()
->shouldBeCalledTimes(0);

$tracerProvider = new TracerProvider($spanProcessor->reveal());
$tracer = $tracerProvider->getTracer('test');

$spanProcessor->checkProphecyMethodsPredictions();
}
}