feat(carreirs): implement environment context getter setter

Closes #1566
This commit is contained in:
Evan Chuang 2025-07-16 11:47:21 +08:00 committed by Evan Chuang
parent e54a43d262
commit f67f8cfc77
2 changed files with 166 additions and 0 deletions

View File

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace OpenTelemetry\Context\Propagation;
use InvalidArgumentException;
/**
* @see https://github.com/open-telemetry/opentelemetry-specification/blob/v1.44.0/specification/context/env-carriers.md
*
* Default implementation of {@see ExtendedPropagationGetterInterface} and {@see PropagationSetterInterface}.
* This type uses environment variables as a carrier for context propagation.
* It is provided to {@see TextMapPropagatorInterface::inject()} or {@see TextMapPropagatorInterface::extract()}.
*/
final class EnvironmentGetterSetter implements ExtendedPropagationGetterInterface, PropagationSetterInterface
{
private static ?self $instance = null;
public static function getInstance(): self
{
return self::$instance ??= new self();
}
public function keys($carrier): array
{
$envs = getenv();
if (!is_array($envs)) {
return [];
}
return array_map('strtolower', array_keys($envs));
}
public function get($carrier, string $key): ?string
{
$value = getenv(strtoupper($key));
return is_string($value) ? $value : null;
}
public function getAll($carrier, string $key): array
{
$value = getenv(strtoupper($key));
return is_string($value) ? [$value] : [];
}
public function set(&$carrier, string $key, string $value): void
{
if ($key === '') {
throw new InvalidArgumentException('Unable to set value with an empty key');
}
putenv(sprintf('%s=%s', strtoupper($key), $value));
}
}

View File

@ -0,0 +1,109 @@
<?php
declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\Context\Propagation;
use InvalidArgumentException;
use OpenTelemetry\Context\Propagation\EnvironmentGetterSetter;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(EnvironmentGetterSetter::class)]
class EnvironmentGetterSetterTest extends TestCase
{
protected function tearDown(): void
{
putenv('A');
putenv('B');
putenv('1');
}
public function test_get_instance(): void
{
$instance = EnvironmentGetterSetter::getInstance();
$this->assertInstanceOf(EnvironmentGetterSetter::class, $instance);
}
public function test_keys_from_map_array(): void
{
$carrier = [];
putenv('A=alpha');
putenv('B=beta=bravo');
$map = new EnvironmentGetterSetter();
$keys = $map->keys($carrier);
$this->assertContains('a', $keys);
$this->assertContains('b', $keys);
}
public function test_get_values_from_environment(): void
{
putenv('A=alpha');
putenv('B=beta');
$map = new EnvironmentGetterSetter();
$this->assertSame('alpha', $map->get([], 'a'));
$this->assertSame('beta', $map->get([], 'b'));
}
public function test_for_empty_key(): void
{
$map = new EnvironmentGetterSetter();
$this->assertNull($map->get([], ''));
}
public function test_for_get_with_nonexistent_key(): void
{
$map = new EnvironmentGetterSetter();
$this->assertNull($map->get([], 'not_exist'));
}
public function test_can_get_integer_value(): void
{
putenv('1=1');
$map = new EnvironmentGetterSetter();
$this->assertSame('1', $map->get([], '1'));
}
public function test_can_get_all_values_from_environment(): void
{
putenv('A=alpha');
putenv('B=beta');
$map = new EnvironmentGetterSetter();
$this->assertSame(['alpha'], $map->getAll([], 'a'));
$this->assertSame(['beta'], $map->getAll([], 'b'));
}
public function test_for_get_all_with_nonexistent_key(): void
{
$map = new EnvironmentGetterSetter();
$this->assertSame([], $map->getAll([], 'not_exist'));
}
public function test_set_environment(): void
{
$carrier = [];
$map = new EnvironmentGetterSetter();
$map->set($carrier, 'b', 'beta');
$this->assertSame('beta', $map->get($carrier, 'b'));
$this->assertSame('beta', getenv('B'));
}
public function test_set_empty_key(): void
{
$carrier = [];
$map = new EnvironmentGetterSetter();
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Unable to set value with an empty key');
$map->set($carrier, '', 'alpha');
}
}