Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ abstract class AbstractHandlerProcessTestCase extends FunctionalTestCase {
protected function setUp(): void {
parent::setUp();

static::envUnsetPrefix('VORTEX_');
static::envUnsetPrefix('DRUPAL_');
static::envUnsetPrefix('LAGOON_');
static::envUnset('WEBROOT');
static::envUnset('TZ');
static::envUnsetProjectVars();

static::applicationInitFromCommand(InstallCommand::class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ abstract class AbstractHandlerDiscoveryTestCase extends UnitTestCase {
protected function setUp(): void {
parent::setUp();

static::envUnsetProjectVars();

static::tuiSetUp();

static::$sut = File::mkdir(static::$sut . DIRECTORY_SEPARATOR . 'myproject');
Expand Down
47 changes: 47 additions & 0 deletions .vortex/installer/tests/Unit/SelfTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@
#[CoversClass(UnitTestCase::class)]
class SelfTest extends UnitTestCase {

const AMBIENT_VAR = 'VORTEX_TEST_AMBIENT_VAR';

const LEAKED_VAR = 'VORTEX_TEST_LEAKED_VAR';

/**
* @var string|false
*/
protected static $ambientOriginal;

public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();

static::$ambientOriginal = getenv(self::AMBIENT_VAR);
putenv(self::AMBIENT_VAR . '=ambient');
}

public static function tearDownAfterClass(): void {
if (static::$ambientOriginal === FALSE) {
putenv(self::AMBIENT_VAR);
}
else {
putenv(self::AMBIENT_VAR . '=' . static::$ambientOriginal);
}

parent::tearDownAfterClass();
}

public function testEnvCleanup1SetVariables(): void {
static::envSet('VORTEX_TEST_VAR_1', 'value1');
static::envSet('VORTEX_TEST_VAR_2', 'value2');
Expand All @@ -34,4 +61,24 @@ public function testEnvCleanup2VerifyCleanup(): void {
$this->assertFalse(getenv('VORTEX_TEST_VAR_4'), 'VORTEX_TEST_VAR_4 should be cleaned up after previous test');
}

public function testEnvRestore1WriteRawValues(): void {
// envSet() is bypassed here to reproduce what production code does when it
// writes the environment directly.
putenv(self::LEAKED_VAR . '=leaked');
putenv(self::AMBIENT_VAR . '=changed');
$_ENV[self::LEAKED_VAR] = 'leaked';
$_SERVER[self::LEAKED_VAR] = 'leaked';

$this->assertSame('leaked', getenv(self::LEAKED_VAR));
$this->assertSame('changed', getenv(self::AMBIENT_VAR));
}

#[Depends('testEnvRestore1WriteRawValues')]
public function testEnvRestore2VerifyRestored(): void {
$this->assertFalse(getenv(self::LEAKED_VAR), 'A variable added by the previous test should not outlive it');
$this->assertSame('ambient', getenv(self::AMBIENT_VAR), 'A variable changed by the previous test should be back to its original value');
$this->assertArrayNotHasKey(self::LEAKED_VAR, $_ENV);
$this->assertArrayNotHasKey(self::LEAKED_VAR, $_SERVER);
}

}
65 changes: 65 additions & 0 deletions .vortex/installer/tests/Unit/UnitTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,35 @@ abstract class UnitTestCase extends UpstreamUnitTestCase {
use SnapshotTrait;
use EnvTrait;

/**
* The process environment before the test ran.
*
* @var array<string,string>
*/
protected array $processEnvBackup;

/**
* The $_ENV superglobal before the test ran.
*
* @var array<string,mixed>
*/
protected array $globalEnvBackup;

/**
* The $_SERVER superglobal before the test ran.
*
* @var array<string,mixed>
*/
protected array $globalServerBackup;

/**
* {@inheritdoc}
*/
protected function setUp(): void {
$this->processEnvBackup = getenv();
$this->globalEnvBackup = $_ENV;
$this->globalServerBackup = $_SERVER;

$cwd = getcwd();
if ($cwd === FALSE) {
throw new \RuntimeException('Failed to determine current working directory.');
Expand All @@ -43,9 +68,49 @@ protected function setUp(): void {
*/
protected function tearDown(): void {
static::envReset();
$this->envRestore();
parent::tearDown();
}

/**
* Restore the process environment captured before the test ran.
*
* EnvTrait::envReset() only reverses names recorded by envSet(). Code under
* test can call putenv() directly, and those values would otherwise be read
* by every later test in the same process.
*/
protected function envRestore(): void {
foreach (array_keys(getenv()) as $name) {
if (!array_key_exists($name, $this->processEnvBackup)) {
putenv($name);
}
}

foreach ($this->processEnvBackup as $name => $value) {
if (getenv($name) !== $value) {
putenv($name . '=' . $value);
}
}

$_ENV = $this->globalEnvBackup;
$_SERVER = $this->globalServerBackup;
}

/**
* Unset the environment variables that a project's .env file defines.
*
* Handlers read the environment before the project's .env file, so a
* variable exported by the shell running the suite would win over the
* fixture.
*/
protected static function envUnsetProjectVars(): void {
static::envUnsetPrefix('VORTEX_');
static::envUnsetPrefix('DRUPAL_');
static::envUnsetPrefix('LAGOON_');
static::envUnset('WEBROOT');
static::envUnset('TZ');
}

/**
* {@inheritdoc}
*/
Expand Down
24 changes: 0 additions & 24 deletions .vortex/installer/tests/Unit/Utils/EnvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,6 @@
#[RunTestsInSeparateProcesses]
class EnvTest extends UnitTestCase {

/**
* @var array
*/
protected $backupServer;

/**
* @var array
*/
protected $backupEnv;

protected function setUp(): void {
$this->backupEnv = $GLOBALS['_ENV'];
$this->backupServer = $GLOBALS['_SERVER'];

parent::setUp();
}

protected function tearDown(): void {
$GLOBALS['_ENV'] = $this->backupEnv;
$GLOBALS['_SERVER'] = $this->backupServer;

parent::tearDown();
}

#[DataProvider('dataProviderGet')]
public function testGet(string $name, string $value, ?string $default, ?string $expected): void {
static::envSet($name, $expected);
Expand Down