upgrade psalm to v5 (#1246)

This commit is contained in:
Brett McBride 2024-03-04 22:58:09 +11:00 committed by GitHub
parent f798bb6f01
commit bb07aca7a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 162 additions and 46 deletions

View File

@ -98,11 +98,11 @@
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^9.6",
"psalm/plugin-mockery": "^0.11",
"psalm/plugin-mockery": "^1",
"psalm/plugin-phpunit": "^0.18.4",
"psalm/psalm": "^4.30",
"psalm/psalm": "^5",
"qossmic/deptrac-shim": "^0.24 || ^1",
"rector/rector": ">=0.15.20",
"rector/rector": "^1",
"symfony/http-client": "^5.2",
"symfony/yaml": "^6 || ^5"
},

View File

@ -21,6 +21,7 @@ require dirname(__DIR__) . '/vendor/autoload.php';
* create a transport factory to override the default grpc one (for both traces and metrics):
* @psalm-suppress InvalidReturnType
* @psalm-suppress InvalidReturnStatement
* @psalm-suppress MissingTemplateParam
*/
$factory = new class() implements \OpenTelemetry\SDK\Common\Export\TransportFactoryInterface {
public function create(string $endpoint, string $contentType, array $headers = [], $compression = null, float $timeout = 10., int $retryDelay = 100, int $maxRetries = 3, ?string $cacert = null, ?string $cert = null, ?string $key = null): \OpenTelemetry\SDK\Common\Export\TransportInterface

View File

@ -6,12 +6,13 @@ namespace OpenTelemetry\Example;
require __DIR__ . '/../../../vendor/autoload.php';
use OpenTelemetry\Contrib\Otlp\ContentTypes;
use OpenTelemetry\Contrib\Otlp\OtlpHttpTransportFactory;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', 'application/json');
$transport = (new OtlpHttpTransportFactory())->create('http://collector:4318/v1/traces', ContentTypes::JSON);
$exporter = new SpanExporter($transport);
echo 'Starting OTLP+json example';

View File

@ -2,6 +2,8 @@
<psalm
errorLevel="3"
cacheDirectory="var/cache/psalm"
findUnusedBaselineEntry="false"
findUnusedCode="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd">
@ -24,5 +26,10 @@
<referencedClass name="GMP" />
</errorLevel>
</UndefinedClass>
<ArgumentTypeCoercion>
<errorLevel type="suppress">
<directory name="./examples" />
</errorLevel>
</ArgumentTypeCoercion>
</issueHandlers>
</psalm>

View File

@ -46,6 +46,7 @@ final class Parser
$metadata = null;
}
/** @psalm-suppress PossiblyUndefinedArrayOffset */
[$key, $value] = explode(self::EQUALS, $keyValue, 2);
$key = urldecode($key);

View File

@ -25,6 +25,10 @@ class Formatter
} else {
//get calling location, skipping over trait, formatter etc
$caller = debug_backtrace()[3];
/**
* @psalm-suppress PossiblyNullArgument
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
$message = sprintf(
'OpenTelemetry: [%s] %s in %s(%s)',
$level,

View File

@ -6,6 +6,7 @@ namespace OpenTelemetry\Context;
/**
* @internal
* @psalm-suppress MissingTemplateParam
*/
final class ContextKey implements ContextKeyInterface
{

View File

@ -6,6 +6,9 @@ namespace OpenTelemetry\Context;
use ArrayAccess;
/**
* @psalm-suppress MissingTemplateParam
*/
interface ContextStorageScopeInterface extends ScopeInterface, ArrayAccess
{
/**

View File

@ -29,6 +29,7 @@ final class GrpcTransportFactory implements TransportFactoryInterface
* @psalm-return TransportInterface<"application/x-protobuf">
* @psalm-suppress MoreSpecificImplementedParamType
* @psalm-suppress ImplementedReturnTypeMismatch
* @psalm-suppress NoValue
*/
public function create(
string $endpoint,

View File

@ -4,6 +4,9 @@ declare(strict_types=1);
namespace OpenTelemetry\Contrib\Otlp;
/**
* @todo enum (php >= 8.1)
*/
interface ContentTypes
{
public const PROTOBUF = 'application/x-protobuf';

View File

@ -8,6 +8,9 @@ use function array_key_exists;
use IteratorAggregate;
use Traversable;
/**
* @psalm-suppress MissingTemplateParam
*/
final class Attributes implements AttributesInterface, IteratorAggregate
{
/**

View File

@ -6,6 +6,9 @@ namespace OpenTelemetry\SDK\Common\Attribute;
use ArrayAccess;
/**
* @psalm-suppress MissingTemplateParam
*/
interface AttributesBuilderInterface extends ArrayAccess
{
public function build(): AttributesInterface;

View File

@ -7,6 +7,9 @@ namespace OpenTelemetry\SDK\Common\Attribute;
use Countable;
use Traversable;
/**
* @psalm-suppress MissingTemplateParam
*/
interface AttributesInterface extends Traversable, Countable
{
public function has(string $name): bool;

View File

@ -25,6 +25,7 @@ class MapParser
foreach (explode(self::VARIABLE_SEPARATOR, $value) as $pair) {
self::validateKeyValuePair($pair);
/** @psalm-suppress PossiblyUndefinedArrayOffset */
[$key, $value] = explode(self::KEY_VALUE_SEPARATOR, $pair, 2);
$result[trim($key)] = trim($value);
}

View File

@ -124,8 +124,8 @@ final class StackTraceFormatter
/**
* @psalm-return Frames
*
* @psalm-suppress PossiblyUndefinedArrayOffset
* @psalm-suppress InvalidArrayOffset
*/
private static function frames(Throwable $e): array
{

View File

@ -53,6 +53,9 @@ final class PsrTransport implements TransportInterface
return $this->contentType;
}
/**
* @psalm-suppress ArgumentTypeCoercion
*/
public function send(string $payload, ?CancellationInterface $cancellation = null): FutureInterface
{
if ($this->closed) {
@ -118,6 +121,9 @@ final class PsrTransport implements TransportInterface
return new CompletedFuture($body);
}
/**
* @return list<string>
*/
private static function parseContentEncoding(ResponseInterface $response): array
{
$encodings = [];

View File

@ -87,6 +87,7 @@ final class PsrUtils
/**
* @param list<string> $encodings
* @psalm-suppress InvalidArrayOffset
*/
public static function decode(string $value, array $encodings): string
{

View File

@ -7,6 +7,9 @@ namespace OpenTelemetry\SDK\Common\Future;
use Closure;
use Throwable;
/**
* @psalm-suppress MissingTemplateParam
*/
final class ErrorFuture implements FutureInterface
{
public function __construct(private Throwable $throwable)

View File

@ -40,11 +40,14 @@ function weaken(Closure $closure, ?object &$target = null): Closure
static $placeholder;
$placeholder ??= new stdClass();
/** @psalm-suppress PossiblyNullReference */
$closure = $closure->bindTo($placeholder);
$ref = WeakReference::create($target);
/** @psalm-suppress PossiblyInvalidFunctionCall */
/**
* @psalm-suppress all
*/
return $scope && $target::class === $scope->name && !$scope->isInternal()
? static fn (...$args) => ($obj = $ref->get()) ? $closure->call($obj, ...$args) : null
: static fn (...$args) => ($obj = $ref->get()) ? $closure->bindTo($obj)(...$args) : null;

View File

@ -25,7 +25,7 @@ class InMemoryExporter implements LogRecordExporterInterface
public function export(iterable $batch, ?CancellationInterface $cancellation = null): FutureInterface
{
foreach ($batch as $record) {
$this->storage[] = $record;
$this->storage->append($record);
}
return new CompletedFuture(true);

View File

@ -22,6 +22,9 @@ final class CriteriaViewRegistry implements ViewRegistryInterface
$this->views[] = $view;
}
/**
* @todo is null the best return type here? what about empty array or exception?
*/
public function find(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): ?iterable
{
$views = $this->generateViews($instrument, $instrumentationScope);

View File

@ -16,11 +16,17 @@ final class InstrumentNameCriteria implements SelectionCriteriaInterface
{
private string $pattern;
/**
* @param non-empty-string $name
*/
public function __construct(string $name)
{
$this->pattern = sprintf('/^%s$/', strtr(preg_quote($name, '/'), ['\\?' => '.', '\\*' => '.*']));
}
/**
* @psalm-suppress ArgumentTypeCoercion
*/
public function accepts(Instrument $instrument, InstrumentationScopeInterface $instrumentationScope): bool
{
return (bool) preg_match($this->pattern, $instrument->name);

View File

@ -28,7 +28,7 @@ class PropagatorFactory
}
/**
* @return array<TextMapPropagatorInterface>
* @return list<TextMapPropagatorInterface>
*/
private function buildPropagators(array $names): array
{

View File

@ -22,7 +22,7 @@ class InMemoryExporter implements SpanExporterInterface
protected function doExport(iterable $spans): bool
{
foreach ($spans as $span) {
$this->storage[] = $span;
$this->storage->append($span);
}
return true;

View File

@ -8,7 +8,7 @@ use OpenTelemetry\SDK\Resource\ResourceInfo;
class TracerProviderBuilder
{
// @var array<SpanProcessorInterface>
/** @var list<SpanProcessorInterface> */
private ?array $spanProcessors = [];
private ?ResourceInfo $resource = null;
private ?SamplerInterface $sampler = null;

View File

@ -51,6 +51,9 @@ class OtlpBench
$this->tracer = $provider->getTracer('io.opentelemetry.contrib.php');
}
/**
* @psalm-suppress MissingTemplateParam
*/
private function createTransport(string $contentType): TransportInterface
{
return new class($contentType) implements TransportInterface {

View File

@ -100,6 +100,7 @@ class ParserTest extends TestCase
'empty key' => ['=value'],
'key with invalid char' => ['@foo=bar'],
'value with invalid char' => ['foo="bar"'],
'missing value' => ['key1='],
];
}
}

View File

@ -28,18 +28,21 @@ class B3PropagatorTest extends TestCase
private const IS_SAMPLED = '1';
private const IS_NOT_SAMPLED = '0';
private $B3;
private $TRACE_ID;
private $SPAN_ID;
private $SAMPLED;
private string $b3;
private string $traceId;
private string $spanId;
private string $sampled;
/**
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
public function setUp(): void
{
[$this->B3] = B3SinglePropagator::getInstance()->fields();
[$this->b3] = B3SinglePropagator::getInstance()->fields();
$b3MultiFields = B3MultiPropagator::getInstance()->fields();
$this->TRACE_ID = $b3MultiFields[0];
$this->SPAN_ID = $b3MultiFields[1];
$this->SAMPLED = $b3MultiFields[3];
$this->traceId = $b3MultiFields[0];
$this->spanId = $b3MultiFields[1];
$this->sampled = $b3MultiFields[3];
}
public function test_b3multi_fields(): void
@ -75,9 +78,9 @@ class B3PropagatorTest extends TestCase
$this->assertSame(
[
$this->TRACE_ID => self::B3_TRACE_ID,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_SAMPLED,
$this->traceId => self::B3_TRACE_ID,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_SAMPLED,
],
$carrier
);
@ -97,7 +100,7 @@ class B3PropagatorTest extends TestCase
);
$this->assertSame(
[$this->B3 => self::B3_SINGLE_HEADER_SAMPLED],
[$this->b3 => self::B3_SINGLE_HEADER_SAMPLED],
$carrier
);
}
@ -105,7 +108,7 @@ class B3PropagatorTest extends TestCase
public function test_extract_only_b3single_sampled_context_with_b3single_instance(): void
{
$carrier = [
$this->B3 => self::B3_SINGLE_HEADER_SAMPLED,
$this->b3 => self::B3_SINGLE_HEADER_SAMPLED,
];
$propagator = B3Propagator::getB3SingleHeaderInstance();
@ -123,7 +126,7 @@ class B3PropagatorTest extends TestCase
public function test_extract_only_b3single_sampled_context_with_b3multi_instance(): void
{
$carrier = [
$this->B3 => self::B3_SINGLE_HEADER_SAMPLED,
$this->b3 => self::B3_SINGLE_HEADER_SAMPLED,
];
$propagator = B3Propagator::getB3MultiHeaderInstance();
@ -141,9 +144,9 @@ class B3PropagatorTest extends TestCase
public function test_extract_only_b3multi_sampled_context_with_b3single_instance(): void
{
$carrier = [
$this->TRACE_ID => self::B3_TRACE_ID,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_SAMPLED,
$this->traceId => self::B3_TRACE_ID,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_SAMPLED,
];
$propagator = B3Propagator::getB3SingleHeaderInstance();
@ -162,9 +165,9 @@ class B3PropagatorTest extends TestCase
public function test_extract_only_b3multi_sampled_context_with_b3multi_instance(string $traceId, string $expected): void
{
$carrier = [
$this->TRACE_ID => $traceId,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_SAMPLED,
$this->traceId => $traceId,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_SAMPLED,
];
$propagator = B3Propagator::getB3MultiHeaderInstance();
@ -210,10 +213,10 @@ class B3PropagatorTest extends TestCase
public function test_extract_both_sampled_context_with_b3single_instance(): void
{
$carrier = [
$this->TRACE_ID => self::B3_TRACE_ID,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_NOT_SAMPLED,
$this->B3 => self::B3_SINGLE_HEADER_SAMPLED,
$this->traceId => self::B3_TRACE_ID,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_NOT_SAMPLED,
$this->b3 => self::B3_SINGLE_HEADER_SAMPLED,
];
$propagator = B3Propagator::getB3SingleHeaderInstance();
@ -229,10 +232,10 @@ class B3PropagatorTest extends TestCase
public function test_extract_both_sampled_context_with_b3multi_instance(): void
{
$carrier = [
$this->TRACE_ID => self::B3_TRACE_ID,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_NOT_SAMPLED,
$this->B3 => self::B3_SINGLE_HEADER_SAMPLED,
$this->traceId => self::B3_TRACE_ID,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_NOT_SAMPLED,
$this->b3 => self::B3_SINGLE_HEADER_SAMPLED,
];
$propagator = B3Propagator::getB3MultiHeaderInstance();
@ -251,10 +254,10 @@ class B3PropagatorTest extends TestCase
public function test_extract_b3_single_invalid_and_b3_multi_valid_context_with_b3single_instance($headerValue): void
{
$carrier = [
$this->TRACE_ID => self::B3_TRACE_ID,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_NOT_SAMPLED,
$this->B3 => $headerValue,
$this->traceId => self::B3_TRACE_ID,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_NOT_SAMPLED,
$this->b3 => $headerValue,
];
$propagator = B3Propagator::getB3SingleHeaderInstance();
@ -273,10 +276,10 @@ class B3PropagatorTest extends TestCase
public function test_extract_b3_single_invalid_and_b3_multi_valid_context_with_b3multi_instance($headerValue): void
{
$carrier = [
$this->TRACE_ID => self::B3_TRACE_ID,
$this->SPAN_ID => self::B3_SPAN_ID,
$this->SAMPLED => self::IS_NOT_SAMPLED,
$this->B3 => $headerValue,
$this->traceId => self::B3_TRACE_ID,
$this->spanId => self::B3_SPAN_ID,
$this->sampled => self::IS_NOT_SAMPLED,
$this->b3 => $headerValue,
];
$propagator = B3Propagator::getB3MultiHeaderInstance();

View File

@ -32,6 +32,9 @@ class B3SinglePropagatorTest extends TestCase
private B3SinglePropagator $b3SinglePropagator;
/**
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
protected function setUp(): void
{
$this->b3SinglePropagator = B3SinglePropagator::getInstance();

View File

@ -30,6 +30,9 @@ class CloudTracePropagatorOneWayTest extends TestCase
private TextMapPropagatorInterface $cloudTracePropagator;
/**
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
protected function setUp(): void
{
$this->cloudTracePropagator = CloudTracePropagator::getOneWayInstance();

View File

@ -30,6 +30,9 @@ class CloudTracePropagatorTest extends TestCase
private TextMapPropagatorInterface $cloudTracePropagator;
/**
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
protected function setUp(): void
{
$this->cloudTracePropagator = CloudTracePropagator::getInstance();

View File

@ -48,6 +48,9 @@ class JaegerPropagatorTest extends TestCase
);
}
/**
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
protected function setUp(): void
{
$this->propagator = JaegerPropagator::getInstance();

View File

@ -270,6 +270,10 @@ class BatchLogRecordProcessorTest extends MockeryTestCase
$processor->forceFlush();
}
/**
* @psalm-suppress UndefinedVariable
* @psalm-suppress RedundantCondition
*/
public function test_queue_size_exceeded_drops_spans(): void
{
$exporter = $this->createMock(LogRecordExporterInterface::class);
@ -357,6 +361,7 @@ class BatchLogRecordProcessorTest extends MockeryTestCase
public function test_throwing_exporter_flush_cannot_rethrow_in_original_caller_logs_error(): void
{
$processor = null;
$exporter = $this->createMock(LogRecordExporterInterface::class);
$exporter->method('forceFlush')->willReturnCallback(function () use (&$processor) {
/** @var LogRecordProcessorInterface $processor */
@ -380,6 +385,7 @@ class BatchLogRecordProcessorTest extends MockeryTestCase
public function test_throwing_exporter_flush_rethrows_in_original_caller(): void
{
$exporter = $this->createMock(LogRecordExporterInterface::class);
$processor = null;
$exporter->method('forceFlush')->willReturnCallback(function () use (&$processor) {
/** @var LogRecordProcessorInterface $processor */
$record = $this->createMock(ReadWriteLogRecord::class);

View File

@ -261,6 +261,10 @@ final class MeterTest extends TestCase
$meter->createObservableCounter('name', 'unit', 'description');
}
/**
* @psalm-suppress InvalidOperand
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
public function test_uses_view_registry_to_create_views(): void
{
$aggregation = $this->createMock(AggregationInterface::class);
@ -289,6 +293,10 @@ final class MeterTest extends TestCase
$meter->createCounter('name');
}
/**
* @psalm-suppress InvalidOperand
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
public function test_uses_default_aggregation_if_view_aggregation_null(): void
{
$aggregation = $this->createMock(AggregationInterface::class);
@ -316,6 +324,10 @@ final class MeterTest extends TestCase
$meter->createCounter('name');
}
/**
* @psalm-suppress InvalidOperand
* @psalm-suppress PossiblyUndefinedArrayOffset
*/
public function test_uses_default_view_if_null_views_returned(): void
{
$aggregation = $this->createMock(AggregationInterface::class);

View File

@ -168,6 +168,9 @@ final class CollectingSourceRegistry implements MetricSourceRegistryInterface
*/
public array $sources = [];
/**
* @psalm-suppress InvalidPropertyAssignmentValue
*/
public function add(MetricSourceProviderInterface $provider, MetricMetadataInterface $metadata, StalenessHandlerInterface $stalenessHandler): void
{
$this->sources[] = func_get_args();

View File

@ -62,6 +62,9 @@ final class MetricRegistryTest extends TestCase
], Temporality::CUMULATIVE, true), $stream->collect($reader));
}
/**
* @psalm-suppress RedundantFunctionCall
*/
public function test_collect_and_push_invokes_requested_callback_only_once(): void
{
$this->expectOutputString('0');
@ -79,6 +82,9 @@ final class MetricRegistryTest extends TestCase
$registry->collectAndPush([$streamId0, $streamId1]);
}
/**
* @psalm-suppress RedundantFunctionCall
*/
public function test_collect_and_push_invokes_only_requested_callbacks(): void
{
$this->expectOutputString('0011');

View File

@ -28,6 +28,9 @@ final class CriteriaViewRegistryTest extends TestCase
));
}
/**
* @psalm-suppress InvalidOperand
*/
public function test_registry_returns_matching_entry(): void
{
$views = new CriteriaViewRegistry();

View File

@ -68,6 +68,7 @@ final class SelectionCriteriaTest extends TestCase
}
/**
* @param non-empty-string $pattern
* @covers \OpenTelemetry\SDK\Metrics\View\SelectionCriteria\InstrumentNameCriteria
* @dataProvider instrumentNameProvider
*/

View File

@ -271,6 +271,9 @@ class BatchSpanProcessorTest extends MockeryTestCase
$batchProcessor->forceFlush();
}
/**
* @psalm-suppress UndefinedVariable
*/
public function test_force_flush_ended_spans(): void
{
$batchSize = 3;
@ -311,6 +314,10 @@ class BatchSpanProcessorTest extends MockeryTestCase
$processor->forceFlush();
}
/**
* @psalm-suppress UndefinedVariable
* @psalm-suppress RedundantCondition
*/
public function test_queue_size_exceeded_drops_spans(): void
{
$exporter = $this->createMock(SpanExporterInterface::class);
@ -405,6 +412,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
public function test_throwing_exporter_flush_cannot_rethrow_in_original_caller_logs_error(): void
{
$processor = null;
$exporter = $this->createMock(SpanExporterInterface::class);
$exporter->method('forceFlush')->willReturnCallback(function () use (&$processor) {
/** @var SpanProcessorInterface $processor */
@ -429,6 +437,7 @@ class BatchSpanProcessorTest extends MockeryTestCase
public function test_throwing_exporter_flush_rethrows_in_original_caller(): void
{
$processor = null;
$exporter = $this->createMock(SpanExporterInterface::class);
$exporter->method('forceFlush')->willReturnCallback(function () use (&$processor) {
/** @var SpanProcessorInterface $processor */

View File

@ -100,6 +100,9 @@ class SimpleSpanProcessorTest extends MockeryTestCase
$this->simpleSpanProcessor->onEnd($this->readableSpan);
}
/**
* @psalm-suppress UndefinedVariable
*/
public function test_does_not_trigger_concurrent_export(): void
{
$spanData = new SpanData();