Add infection test tool (#1306)

* run unit tests in random order
running in random order highlights some interference between tests (mostly logging being enabled), and is a requirement for
mutation testing (ie, all tests must pass when executed in a random order).
* adding infection mutation testing
this adds the ability to run infection. It generates a lot of output, which is an exercise for another PR...
* infection max threads
This commit is contained in:
Brett McBride 2024-05-15 20:46:42 +10:00 committed by GitHub
parent 500f6ee1bd
commit 4f32817065
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 91 additions and 17 deletions

View File

@ -43,6 +43,8 @@ psalm-info: ## Run psalm and show info
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor-bin/psalm/vendor/bin/psalm --show-info=true --threads=1
phpstan: ## Run phpstan
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/phpstan analyse --memory-limit=256M
infection: ## Run infection (mutation testing)
$(DC_RUN_PHP) env XDEBUG_MODE=coverage php -d memory_limit=1024M vendor-bin/infection/vendor/bin/infection --threads=max
packages-composer: ## Validate composer packages
$(DC_RUN_PHP) env XDEBUG_MODE=off vendor/bin/otel packages:composer:validate
benchmark: ## Run phpbench

19
infection.json5 Normal file
View File

@ -0,0 +1,19 @@
{
"$schema": "https://raw.githubusercontent.com/infection/infection/0.28.1/resources/schema.json",
"source": {
"directories": [
"src"
],
"excludes": [
"Composer"
]
},
"logs": {
"text": "var/infection/infection.log",
"html": "var/infection/infection.html",
},
"timeout": 1,
"mutators": {
"@default": true
}
}

View File

@ -6,6 +6,7 @@
bootstrap="./tests/bootstrap.php"
cacheResult="false"
colors="false"
executionOrder="random"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace OpenTelemetry\API\Behavior\Internal;
use OpenTelemetry\API\Behavior\Internal\LogWriter\LogWriterInterface;
use OpenTelemetry\API\Behavior\Internal\LogWriter\NoopLogWriter;
use Psr\Log\LogLevel;
/**
@ -87,4 +88,9 @@ class Logging
self::$logLevel = null;
self::$writer = null;
}
public static function disable(): void
{
self::$writer = new NoopLogWriter();
}
}

View File

@ -38,6 +38,9 @@ final class LoggerHolder
return null !== self::$logger;
}
/**
* @internal
*/
public static function unset(): void
{
self::$logger = null;
@ -45,6 +48,7 @@ final class LoggerHolder
/**
* Disable psr-3 logging
* @internal
*/
public static function disable(): void
{

View File

@ -21,6 +21,11 @@ class LogWriterFactoryTest extends TestCase
{
use EnvironmentVariables;
public function setUp(): void
{
LoggerHolder::unset();
}
public function tearDown(): void
{
self::restoreEnvironmentVariables();

View File

@ -23,6 +23,7 @@ class LogsMessagesTraitTest extends TestCase
public function setUp(): void
{
Logging::reset();
$this->writer = $this->createMock(LogWriterInterface::class);
Logging::setLogWriter($this->writer);
}

View File

@ -14,6 +14,16 @@ use PHPUnit\Framework\TestCase;
*/
class ClockTest extends TestCase
{
public function setUp(): void
{
Clock::reset();
}
public function tearDown(): void
{
Clock::reset();
}
public function test_default_is_system_clock(): void
{
$this->assertInstanceOf(SystemClock::class, Clock::getDefault());

View File

@ -33,6 +33,11 @@ use PHPUnit\Framework\TestCase;
*/
final class InstrumentationTest extends TestCase
{
public function setUp(): void
{
Globals::reset();
}
public function tearDown(): void
{
Globals::reset();

View File

@ -19,6 +19,11 @@ class LoggerHolderTest extends TestCase
LoggerHolder::unset();
}
public function setUp(): void
{
LoggerHolder::unset();
}
public function test_constructor(): void
{
$logger = $this->createMock(LoggerInterface::class);

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\API\Trace\Propagation;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\API\Trace\SpanContext;
use OpenTelemetry\API\Trace\SpanContextInterface;
@ -16,7 +16,6 @@ use OpenTelemetry\Context\Context;
use OpenTelemetry\Context\ContextInterface;
use OpenTelemetry\SDK\Trace\Span;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\API\Trace\Propagation\TraceContextPropagator
@ -35,7 +34,7 @@ class TraceContextPropagatorTest extends TestCase
protected function setUp(): void
{
LoggerHolder::set(new NullLogger());
Logging::disable();
$this->traceContextPropagator = TraceContextPropagator::getInstance();
$this->traceState = (new TraceState())->with('bar', 'baz')->with('foo', 'bar');
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\Contrib\Otlp;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\Contrib\Otlp\LogsExporter;
use OpenTelemetry\SDK\Common\Export\TransportInterface;
use OpenTelemetry\SDK\Common\Future\CompletedFuture;
@ -24,6 +25,7 @@ class LogsExporterTest extends TestCase
$this->transport = $this->createMock(TransportInterface::class);
$this->transport->method('contentType')->willReturn('application/x-protobuf');
$this->exporter = new LogsExporter($this->transport);
Logging::disable();
}
public function test_export_with_transport_failure(): void

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\Contrib\Otlp;
use function fseek;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\API\Trace\SpanContext;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Common\Export\Stream\StreamTransport;
@ -26,6 +27,7 @@ class SpanExporterTest extends TestCase
public function setUp(): void
{
Logging::disable();
$this->transport = $this->createMock(TransportInterface::class);
$this->transport->method('contentType')->willReturn('application/x-protobuf');
$this->exporter = new SpanExporter($this->transport);

View File

@ -5,13 +5,12 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\SDK\Metrics;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\API\Metrics\MeterInterface;
use OpenTelemetry\SDK\Common\Configuration\KnownValues;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\Metrics\MeterProviderFactory;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\Metrics\MeterProviderFactory
@ -22,7 +21,7 @@ class MeterProviderFactoryTest extends TestCase
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
Logging::disable();
}
public function tearDown(): void

View File

@ -6,6 +6,7 @@ namespace OpenTelemetry\Tests\Unit\SDK\Metrics\Stream;
use function current;
use function extension_loaded;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\Context\Context;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Metrics\Aggregation\SumAggregation;
@ -44,6 +45,11 @@ use PHPUnit\Framework\TestCase;
*/
final class MetricStreamTest extends TestCase
{
public function setUp(): void
{
Logging::disable();
}
public function test_asynchronous_single_data_point(): void
{
$s = new AsynchronousMetricStream(new SumAggregation(), 3);

View File

@ -6,6 +6,7 @@ namespace OpenTelemetry\Tests\Unit\SDK\Propagation;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\Baggage\Propagation\BaggagePropagator;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Trace\Propagation\TraceContextPropagator;
use OpenTelemetry\Context\Propagation\MultiTextMapPropagator;
@ -18,7 +19,6 @@ use OpenTelemetry\SDK\Common\Configuration\KnownValues;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\Propagation\PropagatorFactory;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\Propagation\PropagatorFactory
@ -29,7 +29,8 @@ class PropagatorFactoryTest extends TestCase
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
LoggerHolder::disable();
Logging::disable();
}
public function tearDown(): void

View File

@ -7,14 +7,13 @@ namespace OpenTelemetry\Tests\Unit\SDK\Resource;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use Composer\InstalledVersions;
use Generator;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\SDK\Common\Attribute\Attributes;
use OpenTelemetry\SDK\Resource\Detectors;
use OpenTelemetry\SDK\Resource\ResourceInfo;
use OpenTelemetry\SDK\Resource\ResourceInfoFactory;
use OpenTelemetry\SemConv\ResourceAttributes;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\Resource\ResourceInfo
@ -25,7 +24,7 @@ class ResourceInfoTest extends TestCase
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
Logging::disable();
}
public function tearDown(): void

View File

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace OpenTelemetry\Tests\Unit\SDK;
use AssertWell\PHPUnitGlobalState\EnvironmentVariables;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\API\Globals;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Logs\NoopEventLoggerProvider;
use OpenTelemetry\API\Logs\NoopLoggerProvider;
use OpenTelemetry\API\Metrics\Noop\NoopMeterProvider;
@ -15,7 +15,6 @@ use OpenTelemetry\Context\Propagation\NoopTextMapPropagator;
use OpenTelemetry\SDK\Common\Configuration\Variables;
use OpenTelemetry\SDK\SdkAutoloader;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
/**
* @covers \OpenTelemetry\SDK\SdkAutoloader
@ -26,7 +25,7 @@ class SdkAutoloaderTest extends TestCase
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
Logging::disable();
Globals::reset();
}

View File

@ -6,14 +6,13 @@ namespace OpenTelemetry\Tests\Unit\SDK\Trace\SpanExporter;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use OpenTelemetry\API\LoggerHolder;
use OpenTelemetry\API\Behavior\Internal\Logging;
use OpenTelemetry\SDK\Common\Export\TransportInterface;
use OpenTelemetry\SDK\Common\Future\CompletedFuture;
use OpenTelemetry\SDK\Common\Future\ErrorFuture;
use OpenTelemetry\SDK\Common\Future\FutureInterface;
use OpenTelemetry\SDK\Trace\SpanExporterInterface;
use OpenTelemetry\Tests\Unit\SDK\Util\SpanData;
use Psr\Log\NullLogger;
/**
* @psalm-suppress UndefinedInterfaceMethod
@ -25,7 +24,7 @@ abstract class AbstractExporterTestCase extends MockeryTestCase
public function setUp(): void
{
LoggerHolder::set(new NullLogger());
Logging::disable();
$this->future = Mockery::mock(FutureInterface::class);
$this->future->allows([
'map' => $this->future,

View File

@ -0,0 +1,10 @@
{
"require-dev": {
"infection/infection": "^0.28.1"
},
"config": {
"allow-plugins": {
"infection/extension-installer": true
}
}
}