Repository: getsentry/sentry-php (php)

Issue:
`Hub::startTransaction` ignores `sentry-trace` sampling decision
### Problem Statement

From https://github.com/getsentry/sentry-laravel/issues/595

https://github.com/getsentry/sentry-php/blob/27c8b04c5e1e56ced4ccd28bf518f1265413153c/src/State/Hub.php#L225-L229

If the SDK is not configured for tracing, we currently falsely ignore the sampling decision made by the head SDK.

This might have an impact on existing applications, but given the fact that the `sentry-trace` header has to be manually enabled via `tracingOrigins`, I think we can add the new behaviour as a bug fix release.

Pull request description:
Fix sampling decision when parent is sampled
The current sampling decision always set the transaction to not sampled if sampling is disabled in the SDK not taking in account the parent sampling decision which is considered a bug.

This resolved that by also looking at the parent sampling decision when starting a transaction.

Fixes #1405.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bef0354..0a6b64e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,8 @@
 
 ## Unreleased
 
+- fix: Sampling now correctly takes in account the parent sampling decision if available instead of always being `false` when tracing is disabled (#1407)
+
 ## 3.9.1 (2022-10-11)
 
 - fix: Suppress errors on is_callable (#1401)
diff --git a/src/State/Hub.php b/src/State/Hub.php
index 2131146..d22baf0 100644
--- a/src/State/Hub.php
+++ b/src/State/Hub.php
@@ -222,7 +222,7 @@ public function startTransaction(TransactionContext $context, array $customSampl
         $client = $this->getClient();
         $options = null !== $client ? $client->getOptions() : null;
 
-        if (null === $options || !$options->isTracingEnabled()) {
+        if (null === $options || (!$options->isTracingEnabled() && true !== $context->getParentSampled())) {
             $transaction->setSampled(false);
 
             return $transaction;


Test patch:
diff --git a/tests/Tracing/TransactionTest.php b/tests/Tracing/TransactionTest.php
index d7843d5..c0fe446 100644
--- a/tests/Tracing/TransactionTest.php
+++ b/tests/Tracing/TransactionTest.php
@@ -4,12 +4,14 @@
 
 namespace Sentry\Tests\Tracing;
 
+use Generator;
 use PHPUnit\Framework\TestCase;
 use Sentry\ClientInterface;
 use Sentry\Event;
 use Sentry\EventId;
 use Sentry\EventType;
 use Sentry\Options;
+use Sentry\State\Hub;
 use Sentry\State\HubInterface;
 use Sentry\Tracing\Span;
 use Sentry\Tracing\SpanContext;
@@ -84,4 +86,47 @@ public function testFinishDoesNothingIfSampledFlagIsNotTrue(): void
         $transaction = new Transaction(new TransactionContext(), $hub);
         $transaction->finish();
     }
+
+    /**
+     * @dataProvider parentTransactionContextDataProvider
+     */
+    public function testTransactionIsSampledCorrectlyWhenTracingIsDisabledInOptions(TransactionContext $context, bool $expectedSampled): void
+    {
+        $client = $this->createMock(ClientInterface::class);
+        $client->expects($this->once())
+            ->method('getOptions')
+            ->willReturn(
+                new Options([
+                    'traces_sampler' => null,
+                    'traces_sample_rate' => 0,
+                ])
+            );
+
+        $transaction = (new Hub($client))->startTransaction($context);
+
+        $this->assertSame($expectedSampled, $transaction->getSampled());
+    }
+
+    public function parentTransactionContextDataProvider(): Generator
+    {
+        yield [
+            new TransactionContext(TransactionContext::DEFAULT_NAME, true),
+            true,
+        ];
+
+        yield [
+            new TransactionContext(TransactionContext::DEFAULT_NAME, false),
+            false,
+        ];
+
+        yield [
+            TransactionContext::fromHeaders('566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-1', ''),
+            true,
+        ];
+
+        yield [
+            TransactionContext::fromHeaders('566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-0', ''),
+            false,
+        ];
+    }
 }