Merge "i18n: Fix DEFAULTSORT alias in Ukrainian localization"
[mediawiki.git] / tests / phpunit / includes / libs / telemetry / TelemetryIntegrationTest.php
blobe7890e92ea5f51f58d4d6fa8c46e9526a32d894a
1 <?php
2 namespace Wikimedia\Tests\Telemetry;
4 use GuzzleHttp\Client;
5 use GuzzleHttp\Handler\MockHandler;
6 use GuzzleHttp\Psr7\Response;
7 use MediaWiki\MainConfigNames;
8 use MediaWikiIntegrationTestCase;
9 use Wikimedia\Telemetry\Clock;
10 use Wikimedia\Telemetry\NoopTracer;
11 use Wikimedia\Telemetry\SpanInterface;
12 use Wikimedia\Telemetry\Tracer;
13 use Wikimedia\Telemetry\TracerState;
15 /**
16 * @covers \Wikimedia\Telemetry\Tracer
17 * @covers \Wikimedia\Telemetry\OtlpHttpExporter
19 class TelemetryIntegrationTest extends MediaWikiIntegrationTestCase {
20 private const EXAMPLE_TRACING_CONFIG = [
21 'serviceName' => 'test-service',
22 'samplingProbability' => 100,
23 'endpoint' => 'http://198.51.100.42:4318/v1/traces'
26 private const EXAMPLE_TRACING_CONFIG_NO_SAMPLING = [
27 'serviceName' => 'test-service',
28 'samplingProbability' => 0,
29 'endpoint' => 'http://198.51.100.42:4318/v1/traces'
32 private MockHandler $handler;
34 protected function setUp(): void {
35 parent::setUp();
37 $this->handler = new MockHandler();
38 $this->setService( '_TracerHTTPClient', new Client( [
39 'handler' => $this->handler,
40 'http_errors' => false
41 ] ) );
44 protected function tearDown(): void {
45 parent::tearDown();
46 Clock::setMockTime( null );
47 TracerState::destroyInstance();
50 public function testShouldDoNothingWhenTracingDisabled(): void {
51 $this->overrideConfigValue( MainConfigNames::OpenTelemetryConfig, null );
53 $tracer = $this->getServiceContainer()->getTracer();
54 $span = $tracer->createSpan( 'test' )
55 ->start();
57 $span->end();
59 $tracer->shutdown();
61 $this->assertInstanceOf( NoopTracer::class, $tracer );
62 $this->assertNull( $this->handler->getLastRequest() );
65 public function testShouldDoNothingWhenNotSampled(): void {
66 $this->overrideConfigValue(
67 MainConfigNames::OpenTelemetryConfig,
68 self::EXAMPLE_TRACING_CONFIG_NO_SAMPLING
71 $tracer = $this->getServiceContainer()->getTracer();
72 $span = $tracer->createRootSpan( 'test' )
73 ->start();
74 $span->activate();
76 $child = $tracer->createSpan( 'child' )
77 ->start();
79 $child->end();
81 $span->end();
83 $tracer->shutdown();
85 $this->assertInstanceOf( Tracer::class, $tracer );
86 $this->assertNull( $this->handler->getLastRequest() );
89 public function testShouldNotExportDataWhenNoSpansWereCreated(): void {
90 $this->overrideConfigValue( MainConfigNames::OpenTelemetryConfig, self::EXAMPLE_TRACING_CONFIG );
92 $tracer = $this->getServiceContainer()->getTracer();
94 $tracer->shutdown();
96 $this->assertInstanceOf( Tracer::class, $tracer );
97 $this->assertNull( $this->handler->getLastRequest() );
100 public function testShouldNotExportDataWhenTracerWasNotExplicitlyShutdown(): void {
101 $this->overrideConfigValue( MainConfigNames::OpenTelemetryConfig, self::EXAMPLE_TRACING_CONFIG );
103 $tracer = $this->getServiceContainer()->getTracer();
104 $span = $tracer->createRootSpan( 'test' )
105 ->start();
107 $span->end();
109 $this->assertInstanceOf( Tracer::class, $tracer );
110 $this->assertNull( $this->handler->getLastRequest() );
113 public function testShouldExportDataOnShutdownWhenTracingEnabled(): void {
114 $this->overrideConfigValue( MainConfigNames::OpenTelemetryConfig, self::EXAMPLE_TRACING_CONFIG );
115 $this->handler->append( new Response( 200 ) );
117 $mockTime = 5481675965496;
118 Clock::setMockTime( $mockTime );
120 $tracer = $this->getServiceContainer()->getTracer();
121 $span = $tracer->createRootSpan( 'test' )
122 ->setSpanKind( SpanInterface::SPAN_KIND_SERVER )
123 ->start();
125 $span->activate();
127 $mockTime += 100;
128 Clock::setMockTime( $mockTime );
130 $childSpan = $tracer->createSpan( 'child' )
131 ->setAttributes( [ 'some-key' => 'test', 'ignored' => new \stdClass() ] )
132 ->start();
134 $mockTime += 250;
135 Clock::setMockTime( $mockTime );
137 $childSpan->end();
139 $mockTime += 74;
140 Clock::setMockTime( $mockTime );
142 $span->setSpanStatus( SpanInterface::SPAN_STATUS_ERROR );
143 $span->end();
145 $this->assertNull(
146 $this->handler->getLastRequest(),
147 'Exporting trace data should be deferred until the tracer is explicitly shut down'
150 $tracer->shutdown();
152 $request = $this->handler->getLastRequest();
154 $this->assertInstanceOf( Tracer::class, $tracer );
155 $this->assertSame( 'http://198.51.100.42:4318/v1/traces', (string)$request->getUri() );
156 $this->assertSame( 'application/json', $request->getHeaderLine( 'Content-Type' ) );
158 $expected = file_get_contents( __DIR__ . '/expected-trace-data.json' );
160 $expected = strtr( $expected, [
161 '<TRACE-ID>' => $span->getContext()->getTraceId(),
162 '<SPAN-1-ID>' => $span->getContext()->getSpanId(),
163 '<SPAN-2-ID>' => $childSpan->getContext()->getSpanId(),
164 '<HOST-NAME>' => wfHostname()
165 ] );
167 $this->assertJsonStringEqualsJsonString(
168 $expected,
169 (string)$request->getBody()