From 7a20b67764e4b205ea85bf8cc0cc25f73b4a4802 Mon Sep 17 00:00:00 2001 From: Dane Powell Date: Tue, 18 Oct 2022 22:13:05 -0700 Subject: [PATCH] CLI-861: Use virtual fs for tests (#1197) * CLI-861: Use virtual fs for tests * fixes * fix tsets --- .../CodeStudioPipelinesMigrateCommand.php | 17 ++-- tests/fixtures/{id_rsa.pub => ssh/.gitkeep} | 0 tests/phpunit/src/CommandTestBase.php | 1 - .../src/Commands/{ => App}/NewCommandTest.php | 12 ++- .../ConfigurePlatformEmailCommandTest.php | 83 ++++++++++--------- .../src/Commands/Pull/PullCommandTest.php | 11 +++ .../Remote/AliasesDownloadCommandTest.php | 9 ++ .../Commands/Ssh/SshKeyInfoCommandTest.php | 9 ++ .../Commands/Ssh/SshKeyListCommandTest.php | 9 ++ .../src/Misc/LocalMachineHelperTest.php | 4 + tests/phpunit/src/TestBase.php | 80 +++++++++++++----- 11 files changed, 163 insertions(+), 72 deletions(-) rename tests/fixtures/{id_rsa.pub => ssh/.gitkeep} (100%) rename tests/phpunit/src/Commands/{ => App}/NewCommandTest.php (97%) diff --git a/src/Command/CodeStudio/CodeStudioPipelinesMigrateCommand.php b/src/Command/CodeStudio/CodeStudioPipelinesMigrateCommand.php index 581081bef..94808d580 100644 --- a/src/Command/CodeStudio/CodeStudioPipelinesMigrateCommand.php +++ b/src/Command/CodeStudio/CodeStudioPipelinesMigrateCommand.php @@ -124,12 +124,17 @@ private function getAcquiaPipelinesFileContents(array $project): array { $this->localMachineHelper->getFilesystem()->exists($pipelines_filepath_yaml) ) { $this->gitLabClient->projects()->update($project['id'], ['ci_config_path' => '']); - $filename = implode('', glob("acquia-pipelines.*")); - $file_contents = file_get_contents($filename); - return [ - 'file_contents' => Yaml::parse($file_contents, Yaml::PARSE_OBJECT), - 'filename' => $filename - ]; + $pipelines_filenames = ['acquia-pipelines.yml', 'acquia-pipelines.yaml']; + foreach ($pipelines_filenames as $pipelines_filename) { + $pipelines_filepath = Path::join($this->repoRoot, $pipelines_filename); + if (file_exists($pipelines_filepath)) { + $file_contents = file_get_contents($pipelines_filepath); + return [ + 'file_contents' => Yaml::parse($file_contents, Yaml::PARSE_OBJECT), + 'filename' => $pipelines_filename + ]; + } + } } throw new AcquiaCliException("Missing 'acquia-pipelines.yml' file which is required to migrate the project to Code Studio."); diff --git a/tests/fixtures/id_rsa.pub b/tests/fixtures/ssh/.gitkeep similarity index 100% rename from tests/fixtures/id_rsa.pub rename to tests/fixtures/ssh/.gitkeep diff --git a/tests/phpunit/src/CommandTestBase.php b/tests/phpunit/src/CommandTestBase.php index 901dd2b8b..033515a1b 100644 --- a/tests/phpunit/src/CommandTestBase.php +++ b/tests/phpunit/src/CommandTestBase.php @@ -87,7 +87,6 @@ protected function setCommand(Command $command): void { */ protected function executeCommand(array $args = [], array $inputs = []): void { $cwd = $this->projectFixtureDir; - chdir($cwd); $tester = $this->getCommandTester(); $tester->setInputs($inputs); $command_name = $this->command->getName(); diff --git a/tests/phpunit/src/Commands/NewCommandTest.php b/tests/phpunit/src/Commands/App/NewCommandTest.php similarity index 97% rename from tests/phpunit/src/Commands/NewCommandTest.php rename to tests/phpunit/src/Commands/App/NewCommandTest.php index 35511d22c..8795de44b 100644 --- a/tests/phpunit/src/Commands/NewCommandTest.php +++ b/tests/phpunit/src/Commands/App/NewCommandTest.php @@ -1,6 +1,6 @@ setupFsFixture(); + } /** * {@inheritdoc} diff --git a/tests/phpunit/src/Commands/Email/ConfigurePlatformEmailCommandTest.php b/tests/phpunit/src/Commands/Email/ConfigurePlatformEmailCommandTest.php index 4faa960c1..50983f553 100644 --- a/tests/phpunit/src/Commands/Email/ConfigurePlatformEmailCommandTest.php +++ b/tests/phpunit/src/Commands/Email/ConfigurePlatformEmailCommandTest.php @@ -479,44 +479,43 @@ public function testConfigurePlatformEmailJsonOutput(): void { $mock_file_system = $this->mockGetFilesystem($local_machine_helper); $json_file_output = '[ - { - "type": "TXT", - "name": "_amazonses.example.com", - "value": "AB/CD4Hef1+c0D7+wYS2xQ+EBr3HZiXRWDJHrjEWOhs=" - }, - { - "type": "TXT", - "name": "_acquiaplatform.example.com", - "value": "aGh54oW35sd5LMGhas1fWrnRrticnsdndf,43=" - }, - { - "type": "MX", - "name": "mail.example.com", - "value": "10 feedback-smtp.us-east-1.amazonses.com" - }, - { - "type": "TXT", - "name": "mail.example.com", - "value": "v=spf1 include:amazonses.com ~all" - }, - { - "type": "CNAME", - "name": "abcdefgh1ijkl2mnopq34rstuvwxyz._domainkey.example.com", - "value": "abcdefgh1ijkl2mnopq34rstuvwxyz.dkim.amazonses.com" - }, - { - "type": "CNAME", - "name": "abcdefgh1ijkl2mnopq34rstuvwxyz._domainkey.example.com", - "value": "abcdefgh1ijkl2mnopq34rstuvwxyz.dkim.amazonses.com" - }, - { - "type": "CNAME", - "name": "abcdefgh1ijkl2mnopq34rstuvwxyz._domainkey.example.com", - "value": "abcdefgh1ijkl2mnopq34rstuvwxyz.dkim.amazonses.com" - } - ]'; + { + "type": "TXT", + "name": "_amazonses.example.com", + "value": "AB/CD4Hef1+c0D7+wYS2xQ+EBr3HZiXRWDJHrjEWOhs=" + }, + { + "type": "TXT", + "name": "_acquiaplatform.example.com", + "value": "aGh54oW35sd5LMGhas1fWrnRrticnsdndf,43=" + }, + { + "type": "MX", + "name": "mail.example.com", + "value": "10 feedback-smtp.us-east-1.amazonses.com" + }, + { + "type": "TXT", + "name": "mail.example.com", + "value": "v=spf1 include:amazonses.com ~all" + }, + { + "type": "CNAME", + "name": "abcdefgh1ijkl2mnopq34rstuvwxyz._domainkey.example.com", + "value": "abcdefgh1ijkl2mnopq34rstuvwxyz.dkim.amazonses.com" + }, + { + "type": "CNAME", + "name": "abcdefgh1ijkl2mnopq34rstuvwxyz._domainkey.example.com", + "value": "abcdefgh1ijkl2mnopq34rstuvwxyz.dkim.amazonses.com" + }, + { + "type": "CNAME", + "name": "abcdefgh1ijkl2mnopq34rstuvwxyz._domainkey.example.com", + "value": "abcdefgh1ijkl2mnopq34rstuvwxyz.dkim.amazonses.com" + } +]'; - $base_domain = 'www.test.com'; $inputs = [ // What's the domain name you'd like to register? @@ -537,7 +536,7 @@ public function testConfigurePlatformEmailJsonOutput(): void { $post_domains_response = $this->getMockResponseFromSpec('/subscriptions/{subscriptionUuid}/domains', 'post', '200'); $this->clientProphecy->request('post', "/subscriptions/{$subscriptions_response->_embedded->items[0]->uuid}/domains", [ 'form_params' => [ - 'domain' => $base_domain, + 'domain' => 'test.com', ], ])->willReturn($post_domains_response); @@ -550,6 +549,9 @@ public function testConfigurePlatformEmailJsonOutput(): void { $domains_registration_response_200->health->code = '200'; $this->clientProphecy->request('get', "/subscriptions/{$subscriptions_response->_embedded->items[0]->uuid}/domains/{$get_domains_response->_embedded->items[0]->uuid}")->willReturn($domains_registration_response_200); + $mock_file_system->remove('dns-records.yaml')->shouldBeCalled(); + $mock_file_system->remove('dns-records.json')->shouldBeCalled(); + $mock_file_system->remove('dns-records.zone')->shouldBeCalled(); $mock_file_system->dumpFile('dns-records.json', $json_file_output)->shouldBeCalled(); $applications_response = $this->mockApplicationsRequest(); @@ -560,7 +562,7 @@ public function testConfigurePlatformEmailJsonOutput(): void { $applications_response->_embedded->items[0]->subscription->uuid = $subscriptions_response->_embedded->items[0]->uuid; $associate_response = $this->getMockResponseFromSpec('/applications/{applicationUuid}/email/domains/{domainRegistrationUuid}/actions/associate', 'post', '200'); - $this->clientProphecy->request('post', "/applications/{$applications_response->_embedded->items[0]->uuid}/email/domains/{{$get_domains_response->_embedded->items[0]->uuid}}/actions/associate")->willReturn($associate_response); + $this->clientProphecy->request('post', "/applications/{$applications_response->_embedded->items[0]->uuid}/email/domains/{$get_domains_response->_embedded->items[0]->uuid}/actions/associate")->willReturn($associate_response); $environments_response = $this->mockEnvironmentsRequest($applications_response); $enable_response = $this->getMockResponseFromSpec('/environments/{environmentId}/email/actions/enable', 'post', '200'); @@ -569,6 +571,7 @@ public function testConfigurePlatformEmailJsonOutput(): void { $this->command->localMachineHelper = $local_machine_helper->reveal(); $this->executeCommand([], $inputs); $output = $this->getDisplay(); + $this->prophet->checkPredictions(); $this->assertEquals('0', $this->getStatusCode()); $this->assertStringContainsString('all set', $output); } @@ -692,7 +695,7 @@ public function testConfigurePlatformEmailWithAlreadyEnabledEnvs($base_domain, $ */ protected function mockGetFilesystem(ObjectProphecy|LocalMachineHelper $local_machine_helper): Filesystem|ObjectProphecy { $file_system = $this->prophet->prophesize(Filesystem::class); - $local_machine_helper->getFilesystem()->willReturn($file_system)->shouldBeCalled(); + $local_machine_helper->getFilesystem()->willReturn($file_system->reveal())->shouldBeCalled(); return $file_system; } diff --git a/tests/phpunit/src/Commands/Pull/PullCommandTest.php b/tests/phpunit/src/Commands/Pull/PullCommandTest.php index a7c09533c..910fbce74 100644 --- a/tests/phpunit/src/Commands/Pull/PullCommandTest.php +++ b/tests/phpunit/src/Commands/Pull/PullCommandTest.php @@ -14,6 +14,14 @@ */ class PullCommandTest extends PullCommandTestBase { + /** + * @throws \JsonException + */ + public function setUp($output = NULL): void { + parent::setUp($output); + $this->setupFsFixture(); + } + /** * {@inheritdoc} */ @@ -21,6 +29,9 @@ protected function createCommand(): Command { return $this->injectCommand(PullCommand::class); } + /** + * @throws \Exception + */ public function testMissingLocalRepo(): void { // Unset repo root. Mimics failing to find local git repo. Command must be re-created // to re-inject the parameter into the command. diff --git a/tests/phpunit/src/Commands/Remote/AliasesDownloadCommandTest.php b/tests/phpunit/src/Commands/Remote/AliasesDownloadCommandTest.php index aa3f067aa..c0df947d9 100644 --- a/tests/phpunit/src/Commands/Remote/AliasesDownloadCommandTest.php +++ b/tests/phpunit/src/Commands/Remote/AliasesDownloadCommandTest.php @@ -25,6 +25,15 @@ protected function createCommand(): Command { return $this->injectCommand(AliasesDownloadCommand::class); } + /** + * @throws \JsonException + */ + public function setUp($output = NULL): void { + parent::setUp($output); + $this->setupFsFixture(); + $this->command = $this->createCommand(); + } + /** * Test all Drush alias versions. */ diff --git a/tests/phpunit/src/Commands/Ssh/SshKeyInfoCommandTest.php b/tests/phpunit/src/Commands/Ssh/SshKeyInfoCommandTest.php index 2d0b72acc..bac46a3fe 100644 --- a/tests/phpunit/src/Commands/Ssh/SshKeyInfoCommandTest.php +++ b/tests/phpunit/src/Commands/Ssh/SshKeyInfoCommandTest.php @@ -16,6 +16,15 @@ protected function createCommand(): Command { return $this->injectCommand(SshKeyInfoCommand::class); } + /** + * @throws \JsonException + */ + public function setUp($output = NULL): void { + parent::setUp($output); + $this->setupFsFixture(); + $this->command = $this->createCommand(); + } + public function testInfo(): void { $this->mockListSshKeysRequest(); diff --git a/tests/phpunit/src/Commands/Ssh/SshKeyListCommandTest.php b/tests/phpunit/src/Commands/Ssh/SshKeyListCommandTest.php index b109a891b..ae4cc510a 100644 --- a/tests/phpunit/src/Commands/Ssh/SshKeyListCommandTest.php +++ b/tests/phpunit/src/Commands/Ssh/SshKeyListCommandTest.php @@ -20,6 +20,15 @@ protected function createCommand(): Command { return $this->injectCommand(SshKeyListCommand::class); } + /** + * @throws \JsonException + */ + public function setUp($output = NULL): void { + parent::setUp($output); + $this->setupFsFixture(); + $this->command = $this->createCommand(); + } + /** * Tests the 'ssh-key:upload' command. * @throws \Psr\Cache\InvalidArgumentException diff --git a/tests/phpunit/src/Misc/LocalMachineHelperTest.php b/tests/phpunit/src/Misc/LocalMachineHelperTest.php index a01e8696b..612245b68 100644 --- a/tests/phpunit/src/Misc/LocalMachineHelperTest.php +++ b/tests/phpunit/src/Misc/LocalMachineHelperTest.php @@ -52,7 +52,11 @@ public function testExecuteFromCmd($interactive, $is_tty, $print_output): void { } } + /** + * @throws \JsonException + */ public function testExecuteWithCwd(): void { + $this->setupFsFixture(); $local_machine_helper = $this->localMachineHelper; $process = $local_machine_helper->execute(['ls', '-lash'], NULL, $this->projectFixtureDir, FALSE); $this->assertTrue($process->isSuccessful()); diff --git a/tests/phpunit/src/TestBase.php b/tests/phpunit/src/TestBase.php index 38ff53503..a1a1b8b52 100644 --- a/tests/phpunit/src/TestBase.php +++ b/tests/phpunit/src/TestBase.php @@ -23,6 +23,8 @@ use AcquiaLogstream\LogstreamManager; use GuzzleHttp\Psr7\Response; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; +use org\bovigo\vfs\vfsStream; +use org\bovigo\vfs\vfsStreamDirectory; use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\Prophecy\ObjectProphecy; @@ -111,6 +113,8 @@ abstract class TestBase extends TestCase { protected \GuzzleHttp\Client|ObjectProphecy $httpClientProphecy; + protected vfsStreamDirectory $root; + /** * Filter an applications response in order to simulate query filters. * @@ -135,26 +139,13 @@ public function filterApplicationsResponse(object $applications_response, int $c } /** - * This method is called before each test. - * - * @param \Symfony\Component\Console\Output\OutputInterface|null $output + * @todo get rid of this method and use virtual file systems (setupVfsFixture) * + * @return void + * @throws \JsonException * @throws \Exception */ - protected function setUp(OutputInterface $output = NULL): void { - putenv('COLUMNS=85'); - if (!$output) { - $output = new BufferedOutput(); - } - $input = new ArrayInput([]); - - $this->application = new Application(); - $this->fs = new Filesystem(); - $this->prophet = new Prophet(); - $this->consoleOutput = new ConsoleOutput(); - $this->setClientProphecies(); - $this->setIo($input, $output); - + public function setupFsFixture(): void { $this->fixtureDir = $this->getTempDir(); $this->fs->mirror(realpath(__DIR__ . '/../../fixtures'), $this->fixtureDir); $this->projectFixtureDir = $this->fixtureDir . '/project'; @@ -168,6 +159,51 @@ protected function setUp(OutputInterface $output = NULL): void { $this->createDataStores(); $this->cloudCredentials = new CloudCredentials($this->datastoreCloud); $this->telemetryHelper = new TelemetryHelper($this->clientServiceProphecy->reveal(), $this->datastoreCloud); + chdir($this->projectFixtureDir); + } + + /** + * @return void + * @throws \JsonException + * @throws \Exception + */ + public function setupVfsFixture(): void { + $this->root = vfsStream::setup(); + vfsStream::copyFromFileSystem(realpath(__DIR__ . '/../../fixtures')); + $this->fixtureDir = $this->root->url(); + $this->projectFixtureDir = $this->fixtureDir . '/project'; + $this->acliRepoRoot = $this->projectFixtureDir; + $this->dataDir = $this->fixtureDir . '/.acquia'; + $this->sshDir = $this->root->url() . '/ssh'; + $this->acliConfigFilename = '.acquia-cli.yml'; + $this->cloudConfigFilepath = $this->dataDir . '/cloud_api.conf'; + $this->acliConfigFilepath = $this->projectFixtureDir . '/' . $this->acliConfigFilename; + $this->createMockConfigFiles(); + $this->createDataStores(); + $this->cloudCredentials = new CloudCredentials($this->datastoreCloud); + $this->telemetryHelper = new TelemetryHelper($this->clientServiceProphecy->reveal(), $this->datastoreCloud); + } + + /** + * This method is called before each test. + * + * @param \Symfony\Component\Console\Output\OutputInterface|null $output + * + * @throws \Exception + */ + protected function setUp(OutputInterface $output = NULL): void { + putenv('COLUMNS=85'); + $this->output = $output ?: new BufferedOutput(); + $this->input = new ArrayInput([]); + + $this->application = new Application(); + $this->fs = new Filesystem(); + $this->prophet = new Prophet(); + $this->consoleOutput = new ConsoleOutput(); + $this->setClientProphecies(); + $this->setIo(); + + $this->setupVfsFixture(); $this->logStreamManagerProphecy = $this->prophet->prophesize(LogstreamManager::class); $this->httpClientProphecy = $this->prophet->prophesize(\GuzzleHttp\Client::class); ClearCacheCommand::clearCaches(); @@ -228,14 +264,12 @@ public static function unsetEnvVars($env_vars): void { } } - protected function setIo($input, $output): void { - $this->input = $input; - $this->output = $output; - $this->logger = new ConsoleLogger($output); - $this->localMachineHelper = new LocalMachineHelper($input, $output, $this->logger); + private function setIo(): void { + $this->logger = new ConsoleLogger($this->output); + $this->localMachineHelper = new LocalMachineHelper($this->input, $this->output, $this->logger); // TTY should never be used for tests. $this->localMachineHelper->setIsTty(FALSE); - $this->sshHelper = new SshHelper($output, $this->localMachineHelper, $this->logger); + $this->sshHelper = new SshHelper($this->output, $this->localMachineHelper, $this->logger); } /**