Skip to content

Commit

Permalink
Added automatic selection of PHPUnit configuration file (elastic#893)
Browse files Browse the repository at this point in the history
* Added automatic selection of PHPUnit configuration file

* Separated options that should not be parsed by composer

Fixed static-check-unit-test.sh so that the options for composer script are mistakenly parsed by composer as its options

* Fixed issue found static analysis

* Added SelectPhpUnitConfigFileComponentTest::testAllExpectedFilesExist

* Fixed hardcoded path to runSelectPhpUnitConfigFile.php

* Fixed hardcoded path to runSelectPhpUnitConfigFile.php PART 2

* Fixed algorithm used by component tests to find free port to listen

* Fixed issues found by static analysis

* Removed SelectPhpUnitConfigFileUnitTest as redundant

* Added clarifying comments

* Replaced 'ls -1' by PHP's scandir()

* Added missing check for false as potential result of scandir
  • Loading branch information
SergeyKleyman authored Mar 22, 2023
1 parent 7c9e829 commit 12c1d3a
Show file tree
Hide file tree
Showing 11 changed files with 571 additions and 6 deletions.
9 changes: 7 additions & 2 deletions .ci/static-check-unit-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,13 @@ env | grep ELASTIC || true
# Install 3rd party dependencies
composer install

# Run static_check_and_run_unit_tests
composer run-script static_check_and_run_unit_tests
# Run static checks
composer run-script static_check

# Run unit tests
phpUnitConfigFile=$(php ./tests/ElasticApmTests/Util/runSelectPhpUnitConfigFile.php --tests-type=unit)
composer run-script -- run_unit_tests_custom_config -c "${phpUnitConfigFile}"
ls -l ./build/unit-tests-phpunit-junit.xml

# Generate junit output for phpstan
composer phpstan-junit-report-for-ci
Expand Down
9 changes: 7 additions & 2 deletions .ci/validate_agent_installation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ function runComponentTests () {
local composerCommand=(composer run-script --)

if [ -z "${ELASTIC_APM_PHP_TESTS_APP_CODE_HOST_KIND}" ] || [ "${ELASTIC_APM_PHP_TESTS_APP_CODE_HOST_KIND}" == "all" ]; then
composerCommand=("${composerCommand[@]}" run_component_tests)
composerCommand=("${composerCommand[@]}" run_component_tests_custom_config)
else
composerCommand=("${composerCommand[@]}" run_component_tests_configured)
composerCommand=("${composerCommand[@]}" run_component_tests_configured_custom_config)
fi

phpUnitConfigFile=$(php ./tests/ElasticApmTests/Util/runSelectPhpUnitConfigFile.php --tests-type=component)
composerCommand=("${composerCommand[@]}" -c "${phpUnitConfigFile}")

if [ -n "${ELASTIC_APM_PHP_TESTS_GROUP}" ] ; then
composerCommand=("${composerCommand[@]}" --group "${ELASTIC_APM_PHP_TESTS_GROUP}")
fi
Expand Down Expand Up @@ -46,6 +49,8 @@ function runComponentTests () {
ls -l ./build/
echo "Content of ./build/ end"

ls -l ./build/component-tests-phpunit-junit.xml

echo "${composerCommand[*]} exited with an error code ${composerCommandExitCode}"
if [ ${composerCommandExitCode} -eq 0 ] ; then
local shouldPrintTheMostRecentSyslogFile=false
Expand Down
16 changes: 16 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
"run_unit_tests": [
"phpunit"
],
"run_unit_tests_custom_config": [
"phpunit"
],
"run_unit_tests_filter": [
"phpunit --filter"
],
Expand All @@ -87,6 +90,9 @@
"run_component_tests_configured": [
"phpunit -c phpunit_component_tests.xml"
],
"run_component_tests_configured_custom_config": [
"phpunit"
],
"run_component_tests_cli_filter": [
"composer run-script -- run_component_tests_cli --filter"
],
Expand All @@ -97,12 +103,22 @@
"composer run-script -- run_component_tests_http",
"composer run-script -- run_component_tests_cli"
],
"run_component_tests_custom_config": [
"composer run-script -- run_component_tests_http_custom_config",
"composer run-script -- run_component_tests_cli_custom_config"
],
"run_component_tests_cli": [
"ELASTIC_APM_ENABLED=false ELASTIC_APM_PHP_TESTS_APP_CODE_HOST_KIND=CLI_script composer run-script -- run_component_tests_configured"
],
"run_component_tests_http": [
"ELASTIC_APM_ENABLED=false ELASTIC_APM_PHP_TESTS_APP_CODE_HOST_KIND=Builtin_HTTP_server composer run-script -- run_component_tests_configured"
],
"run_component_tests_cli_custom_config": [
"ELASTIC_APM_ENABLED=false ELASTIC_APM_PHP_TESTS_APP_CODE_HOST_KIND=CLI_script composer run-script -- run_component_tests_configured"
],
"run_component_tests_http_custom_config": [
"ELASTIC_APM_ENABLED=false ELASTIC_APM_PHP_TESTS_APP_CODE_HOST_KIND=Builtin_HTTP_server composer run-script -- run_component_tests_configured"
],
"run_tests": [
"composer run-script -- run_unit_tests",
"composer run-script -- run_component_tests"
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<ini name="memory_limit" value="2G"/>
</php>
<logging>
<junit outputFile="build/unit-tests-phpunit-junit.xml"/>
<junit outputFile="./build/unit-tests-phpunit-junit.xml"/>
</logging>
<testsuites>
<testsuite name="Tests">
Expand Down
2 changes: 1 addition & 1 deletion phpunit_component_tests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<ini name="memory_limit" value="2G"/>
</php>
<logging>
<junit outputFile="build/component-tests-phpunit-junit.xml"/>
<junit outputFile="./build/component-tests-phpunit-junit.xml"/>
</logging>
<testsuites>
<testsuite name="Tests">
Expand Down
37 changes: 37 additions & 0 deletions phpunit_component_tests_v8_format.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="false"
bootstrap="tests/bootstrap.php"
colors="true"
failOnRisky="true"
stopOnDefect="true"
stopOnError="true"
stopOnFailure="true"
stopOnIncomplete="true"
stopOnRisky="true"
stopOnWarning="true"
verbose="true"
testdox="true"
noInteraction="true"
>
<filter>
<whitelist>
<directory suffix=".php">./src/ElasticApm/</directory>
</whitelist>
</filter>
<php>
<ini name="memory_limit" value="2G"/>
</php>
<logging>
<log type="junit" target="./build/component-tests-phpunit-junit.xml"/>
</logging>
<testsuites>
<testsuite name="Tests">
<directory>./tests/ElasticApmTests/ComponentTests</directory>
</testsuite>
</testsuites>
<extensions>
<extension class="\ElasticApmTests\ComponentTests\Util\ComponentTestsPhpUnitExtension"/>
</extensions>
</phpunit>
37 changes: 37 additions & 0 deletions phpunit_v8_format.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="false"
bootstrap="tests/bootstrap.php"
colors="true"
failOnRisky="true"
stopOnDefect="true"
stopOnError="true"
stopOnFailure="true"
stopOnIncomplete="true"
stopOnRisky="true"
stopOnWarning="true"
verbose="true"
testdox="true"
noInteraction="true"
>
<filter>
<whitelist>
<directory suffix=".php">./src/ElasticApm/</directory>
</whitelist>
</filter>
<php>
<ini name="memory_limit" value="2G"/>
</php>
<logging>
<log type="junit" target="./build/unit-tests-phpunit-junit.xml"/>
</logging>
<testsuites>
<testsuite name="Tests">
<directory>./tests/ElasticApmTests/UnitTests</directory>
</testsuite>
</testsuites>
<extensions>
<extension class="\ElasticApmTests\UnitTests\Util\UnitTestsPhpUnitExtension"/>
</extensions>
</phpunit>
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

declare(strict_types=1);

namespace ElasticApmTests\ComponentTests\UtilTests;

use Elastic\Apm\Impl\Log\LoggableToString;
use Elastic\Apm\Impl\Util\ArrayUtil;
use ElasticApmTests\Util\AssertMessageBuilder;
use ElasticApmTests\Util\SelectPhpUnitConfigFile;
use ElasticApmTests\Util\TestCaseBase;
use PHPUnit\Runner\Version;

/**
* @group does_not_require_external_services
*/
final class SelectPhpUnitConfigFileComponentTest extends TestCaseBase
{
private const EXPECTED_CONFIG_FILES_PER_PHP_UNIT_MAJOR_VERSION = [
SelectPhpUnitConfigFile::TESTS_TYPE_UNIT => [8 => 'phpunit_v8_format.xml'],
SelectPhpUnitConfigFile::TESTS_TYPE_COMPONENT => [8 => 'phpunit_component_tests_v8_format.xml'],
];

private const EXPECTED_DEFAULT_CONFIG_FILES = [
SelectPhpUnitConfigFile::TESTS_TYPE_UNIT => 'phpunit.xml.dist',
SelectPhpUnitConfigFile::TESTS_TYPE_COMPONENT => 'phpunit_component_tests.xml',
];

public static function testAllExpectedFilesExist(): void
{
foreach (self::EXPECTED_CONFIG_FILES_PER_PHP_UNIT_MAJOR_VERSION as $phpUnitMajorVerionToFileName) {
foreach ($phpUnitMajorVerionToFileName as $fileName) {
self::assertFileExists($fileName);
}
}
}

private static function getCurrentPhpUnitMajorVersion(): int
{
$asDotSeparatedString = Version::id();
$dbgMsg = new AssertMessageBuilder(['asDotSeparatedString' => $asDotSeparatedString]);
// Limit to 2 parts since we are only interested in MAJOR part of the version
$partsAsStrings = explode(/* separator */ '.', $asDotSeparatedString, /* limit */ 2);
$dbgMsg->add('partsAsStrings', $partsAsStrings);
self::assertGreaterThanOrEqual(1, count($partsAsStrings), $dbgMsg->s());
$majorPartAsString = $partsAsStrings[0];
$dbgMsg->add('majorPartAsString', $majorPartAsString);
self::assertNotFalse(filter_var($majorPartAsString, FILTER_VALIDATE_INT), $dbgMsg->s());
return intval($majorPartAsString);
}

public static function testDiscoverPhpUnitMajorVersion(): void
{
self::assertSame(self::getCurrentPhpUnitMajorVersion(), SelectPhpUnitConfigFile::discoverPhpUnitMajorVersion());
}

private static function getExpectedPhpUnitConfigFile(string $testsType): string
{
$phpUnitMajorVerion = self::getCurrentPhpUnitMajorVersion();
$dbgMsg = new AssertMessageBuilder(['phpUnitMajorVerion' => $phpUnitMajorVerion]);

$phpUnitMajorVerionToFileName = ArrayUtil::getValueIfKeyExistsElse(
$testsType,
self::EXPECTED_CONFIG_FILES_PER_PHP_UNIT_MAJOR_VERSION,
null /* <- fallbackValue */
);
$dbgMsg->add('phpUnitMajorVerionToFileName', $phpUnitMajorVerionToFileName);
self::assertNotNull($phpUnitMajorVerionToFileName, $dbgMsg->s());

$fileName = ArrayUtil::getValueIfKeyExistsElse($phpUnitMajorVerion, $phpUnitMajorVerionToFileName, null);
return $fileName === null ? self::EXPECTED_DEFAULT_CONFIG_FILES[$testsType] : $fileName;
}

/**
* @param iterable<array<string, mixed>> $srcDataProvider
*
* @return iterable<string, array<mixed>>
*/
protected static function wrapDataProviderFromKeyValueMapToNamedDataSet(iterable $srcDataProvider): iterable
{
$dataSetIdex = 0;
foreach ($srcDataProvider as $namedValuesMap) {
$dataSetName = '#' . $dataSetIdex;
$dataSetName .= ' ' . LoggableToString::convert($namedValuesMap);
yield $dataSetName => array_values($namedValuesMap);
++$dataSetIdex;
}
}

/**
* @return iterable<array<string, string>>
*/
private static function dataProviderForTestSelectPhpUnitConfigFileImpl(): iterable
{
foreach (SelectPhpUnitConfigFile::ALL_TESTS_TYPES as $testsType) {
yield ['testsType' => $testsType];
}
}

/**
* @return iterable<string, array{string}>
*/
public static function dataProviderForTestSelectPhpUnitConfigFile(): iterable
{
/** @var iterable<string, array{string}> $wrappedDataProvider */
$wrappedDataProvider = self::wrapDataProviderFromKeyValueMapToNamedDataSet(
self::dataProviderForTestSelectPhpUnitConfigFileImpl()
);
return $wrappedDataProvider;
}

/**
* @dataProvider dataProviderForTestSelectPhpUnitConfigFile
*
* @param string $testsType
*/
public static function testSelectPhpUnitConfigFile(string $testsType): void
{
$expectedPhpUnitConfigFileName = self::getExpectedPhpUnitConfigFile($testsType);
$dbgMsg = new AssertMessageBuilder(['expectedPhpUnitConfigFileName' => $expectedPhpUnitConfigFileName]);

$command = 'php ' . '"' . SelectPhpUnitConfigFile::getFullPathToRunScript() . '"';
$command .= ' ' . '--' . SelectPhpUnitConfigFile::TESTS_TYPE_CMD_LINE_OPT_NAME . '=' . $testsType;
$dbgMsg->add('command', $command);
$outputLines = SelectPhpUnitConfigFile::execExternalCommand($command);
self::assertCount(1, $outputLines);
$actualPhpUnitConfigFileName = $outputLines[0];
$dbgMsg->add('actualPhpUnitConfigFileName', $actualPhpUnitConfigFileName);
self::assertSame($expectedPhpUnitConfigFileName, $actualPhpUnitConfigFileName, $dbgMsg->s());
}
}
Loading

0 comments on commit 12c1d3a

Please sign in to comment.