Skip to content

PHPLIB-582: Create JSON test result file for evergreen #787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,6 @@ functions:
chmod +x $i
done

"init test-results":
- command: shell.exec
params:
script: |
${PREPARE_SHELL}
echo '{"results": [{ "status": "FAIL", "test_file": "Build", "log_raw": "No test-results.json found was created" } ]}' > ${PROJECT_DIRECTORY}/test-results.json

"install dependencies":
- command: shell.exec
params:
Expand All @@ -275,7 +268,6 @@ pre:
- func: "prepare resources"
- func: "windows fix"
- func: "fix absolute paths"
- func: "init test-results"
- func: "make files executable"
- func: "install dependencies"

Expand Down
4 changes: 2 additions & 2 deletions .evergreen/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ PATH=/opt/php/${PHP_VERSION}-64bit/bin:$OLD_PATH
case "$TESTS" in
atlas-data-lake*)
MONGODB_URI="mongodb://mhuser:[email protected]:27017"
php vendor/bin/phpunit --testsuite "Atlas Data Lake Test Suite"
php vendor/bin/phpunit --configuration phpunit.evergreen.xml --testsuite "Atlas Data Lake Test Suite"
;;

*)
php vendor/bin/phpunit
php vendor/bin/phpunit --configuration phpunit.evergreen.xml
;;
esac
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"jean85/pretty-package-versions": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^6.4 || ^8.3",
"phpunit/phpunit": "^6.4",
"sebastian/comparator": "^2.0 || ^3.0",
"squizlabs/php_codesniffer": "^3.5, <3.5.5",
"symfony/phpunit-bridge": "^4.4@dev"
Expand Down
36 changes: 36 additions & 0 deletions phpunit.evergreen.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.3/phpunit.xsd"
beStrictAboutOutputDuringTests="true"
beStrictAboutChangesToGlobalState="true"
colors="true"
bootstrap="tests/bootstrap.php"
defaultTestSuite="Default Test Suite"
>

<php>
<ini name="error_reporting" value="-1"/>
<env name="MONGODB_URI" value="mongodb://127.0.0.1:27017/?serverSelectionTimeoutMS=100"/>
<env name="MONGODB_DATABASE" value="phplib_test"/>
</php>

<testsuites>
<testsuite name="Default Test Suite">
<directory>./tests/</directory>
</testsuite>

<testsuite name="Atlas Data Lake Test Suite">
<file>tests/SpecTests/AtlasDataLakeSpecTest.php</file>
</testsuite>
</testsuites>

<listeners>
<listener class="MongoDB\Tests\EvergreenLogListener">
<arguments>
<string>test-results.json</string>
</arguments>
</listener>
</listeners>
</phpunit>
205 changes: 205 additions & 0 deletions tests/EvergreenLogListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
<?php

namespace MongoDB\Tests;

use Exception;
use PHPUnit\Framework\AssertionFailedError;
use PHPUnit\Framework\SelfDescribing;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestFailure;
use PHPUnit\Framework\TestListener;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Framework\Warning;
use PHPUnit\Util\Filter;
use PHPUnit\Util\Printer;
use function get_class;
use function json_encode;
use function round;

// phpcs:disable SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException
class EvergreenLogListener extends Printer implements TestListener
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we already use symfony/phpunit-bridge, I noticed it has an alias for a SymfonyTestsListener interface. I think you could leverage that instead of implementing PHPUnit's interface directly and preserve our ability to test with PHPUnit 8.x.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, that class is not a generic implementation for test listeners, but rather a specific one to support the use-case of the PHPUnit bridge.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I just poked my head into SymfonyTestsListenerTrait.

{
/** @var array[] */
private $tests = [];

/** @var array|null */
private $currentTestCase = null;

/**
* Flush buffer and close output.
*/
public function flush()
{
$this->write($this->getJson());

parent::flush();
}

/**
* An error occurred.
*
* @param Test $test
* @param Exception $e
* @param float $time
*/
public function addError(Test $test, Exception $e, $time)
{
$this->doAddFault($test, $e, 'fail');
}

/**
* A warning occurred.
*
* @param Test $test
* @param Warning $e
* @param float $time
*/
public function addWarning(Test $test, Warning $e, $time)
{
// Do nothing for now
}

/**
* A failure occurred.
*
* @param Test $test
* @param AssertionFailedError $e
* @param float $time
*/
public function addFailure(Test $test, AssertionFailedError $e, $time)
{
$this->doAddFault($test, $e, 'fail');
}

/**
* Incomplete test.
*
* @param Test $test
* @param Exception $e
* @param float $time
*/
public function addIncompleteTest(Test $test, Exception $e, $time)
{
$this->doAddSkipped($test);
}

/**
* Risky test.
*
* @param Test $test
* @param Exception $e
* @param float $time
*/
public function addRiskyTest(Test $test, Exception $e, $time)
{
return;
}

/**
* Skipped test.
*
* @param Test $test
* @param Exception $e
* @param float $time
*/
public function addSkippedTest(Test $test, Exception $e, $time)
{
$this->doAddSkipped($test);
}

/**
* A testsuite started.
*
* @param TestSuite $suite
*/
public function startTestSuite(TestSuite $suite)
{
}

/**
* A testsuite ended.
*
* @param TestSuite $suite
*/
public function endTestSuite(TestSuite $suite)
{
}

/**
* A test started.
*
* @param Test $test
*/
public function startTest(Test $test)
{
$this->currentTestCase = [
'status' => 'pass',
'test_file' => get_class($test) . '::' . $test->getName(),
];
}

/**
* A test ended.
*
* @param Test $test
* @param float $time
*/
public function endTest(Test $test, $time)
{
if (! $this->currentTestCase) {
return;
}

$this->currentTestCase['elapsed'] = round($time, 6);

$this->tests[] = $this->currentTestCase;

$this->currentTestCase = null;
}

/**
* Returns the XML as a string.
*
* @return string
*/
public function getJson()
{
return json_encode(['results' => $this->tests]);
}

/**
* Method which generalizes addError() and addFailure()
*
* @param Test $test
* @param Exception $e
* @param string $type
*/
private function doAddFault(Test $test, Exception $e, $type)
{
if ($this->currentTestCase === null) {
return;
}

if ($test instanceof SelfDescribing) {
$buffer = $test->toString() . "\n";
} else {
$buffer = '';
}

$buffer .= TestFailure::exceptionToString($e) . "\n" .
Filter::getFilteredStacktrace($e);

$this->currentTestCase['status'] = $type;
$this->currentTestCase['raw_log'] = $buffer;
}

private function doAddSkipped(Test $test)
{
if ($this->currentTestCase === null) {
return;
}

$this->currentTestCase['status'] = 'skip';
}
}
// phpcs:enable SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException