From c64db73bd32ce542829607d20285a8e72ec5f04a Mon Sep 17 00:00:00 2001 From: vgrams Date: Fri, 25 Oct 2024 16:16:15 +0600 Subject: [PATCH] feat: implement support for `brianium/paratest` package to run tests in different workers; --- config/auto-doc.php | 2 + src/Drivers/BaseDriver.php | 18 +++-- src/Drivers/LocalDriver.php | 2 +- src/Drivers/RemoteDriver.php | 2 +- src/Drivers/StorageDriver.php | 2 +- src/Services/SwaggerService.php | 7 +- .../ApplicationFinishedSubscriber.php | 68 +++++++++++++++++++ .../ApplicationStartedSubscriber.php | 29 ++++++++ .../SwaggerSaveDocumentationSubscriber.php | 26 ------- .../PHPUnit/Extensions/SwaggerExtension.php | 6 +- 10 files changed, 125 insertions(+), 37 deletions(-) create mode 100644 src/Support/PHPUnit/EventSubscribers/ApplicationFinishedSubscriber.php create mode 100644 src/Support/PHPUnit/EventSubscribers/ApplicationStartedSubscriber.php delete mode 100644 src/Support/PHPUnit/EventSubscribers/SwaggerSaveDocumentationSubscriber.php diff --git a/config/auto-doc.php b/config/auto-doc.php index 1ed5fe9..b6bdbfe 100644 --- a/config/auto-doc.php +++ b/config/auto-doc.php @@ -125,6 +125,8 @@ */ 'documentation_viewer' => env('SWAGGER_SPEC_VIEWER', 'swagger'), + 'tmp_dir' => storage_path('tmp_documentation'), + 'drivers' => [ 'local' => [ 'class' => LocalDriver::class, diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index 0bef982..839325d 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -2,6 +2,8 @@ namespace RonasIT\AutoDoc\Drivers; +use Illuminate\Support\Facades\File; +use Illuminate\Support\Facades\ParallelTesting; use RonasIT\AutoDoc\Contracts\SwaggerDriverContract; abstract class BaseDriver implements SwaggerDriverContract @@ -10,11 +12,19 @@ abstract class BaseDriver implements SwaggerDriverContract public function __construct() { - $this->tempFilePath = storage_path('temp_documentation.json'); + $tmpDir = config('auto-doc.tmp_dir'); + + $this->tempFilePath = ($token = ParallelTesting::token()) + ? $tmpDir . "/temp_documentation_{$token}.json" + : $tmpDir . '/temp_documentation.json'; } public function saveTmpData($data): void { + if (!is_dir(dirname($this->tempFilePath))) { + mkdir(dirname($this->tempFilePath)); + } + file_put_contents($this->tempFilePath, json_encode($data)); } @@ -29,10 +39,8 @@ public function getTmpData(): ?array return null; } - protected function clearTmpData(): void + protected function clearTmpDir(): void { - if (file_exists($this->tempFilePath)) { - unlink($this->tempFilePath); - } + File::deleteDirectory(config('auto-doc.tmp_dir')); } } diff --git a/src/Drivers/LocalDriver.php b/src/Drivers/LocalDriver.php index f8b7f27..307694b 100755 --- a/src/Drivers/LocalDriver.php +++ b/src/Drivers/LocalDriver.php @@ -24,7 +24,7 @@ public function saveData(): void { file_put_contents($this->prodFilePath, json_encode($this->getTmpData())); - $this->clearTmpData(); + $this->clearTmpDir(); } public function getDocumentation(): array diff --git a/src/Drivers/RemoteDriver.php b/src/Drivers/RemoteDriver.php index 16b5233..cc8f47c 100755 --- a/src/Drivers/RemoteDriver.php +++ b/src/Drivers/RemoteDriver.php @@ -28,7 +28,7 @@ public function saveData(): void 'Content-Type: application/json', ]); - $this->clearTmpData(); + $this->clearTmpDir(); } public function getDocumentation(): array diff --git a/src/Drivers/StorageDriver.php b/src/Drivers/StorageDriver.php index e08646d..c0346db 100755 --- a/src/Drivers/StorageDriver.php +++ b/src/Drivers/StorageDriver.php @@ -28,7 +28,7 @@ public function saveData(): void { $this->disk->put($this->prodFilePath, json_encode($this->getTmpData())); - $this->clearTmpData(); + $this->clearTmpDir(); } public function getDocumentation(): array diff --git a/src/Services/SwaggerService.php b/src/Services/SwaggerService.php index 5c8cf87..a86d6e8 100755 --- a/src/Services/SwaggerService.php +++ b/src/Services/SwaggerService.php @@ -802,6 +802,11 @@ public function saveProductionData() $this->driver->saveData(); } + public function saveTmpData(array $data): void + { + $this->driver->saveTmpData($data); + } + public function getDocFileContent() { $documentation = $this->driver->getDocumentation(); @@ -971,7 +976,7 @@ protected function getOpenAPIFileContent(string $filePath): array return $fileContent; } - protected function mergeOpenAPIDocs(array &$documentation, array $additionalDocumentation): void + public function mergeOpenAPIDocs(array &$documentation, array $additionalDocumentation): void { $paths = array_keys($additionalDocumentation['paths']); diff --git a/src/Support/PHPUnit/EventSubscribers/ApplicationFinishedSubscriber.php b/src/Support/PHPUnit/EventSubscribers/ApplicationFinishedSubscriber.php new file mode 100644 index 0000000..3207b18 --- /dev/null +++ b/src/Support/PHPUnit/EventSubscribers/ApplicationFinishedSubscriber.php @@ -0,0 +1,68 @@ +createApplication(); + + if ($this->isReadyToSaveProductionData()) { + app(SwaggerService::class)->saveProductionData(); + } + } + + protected function createApplication(): void + { + $app = require Application::inferBasePath() . '/bootstrap/app.php'; + + $app->loadEnvironmentFrom('.env.testing'); + $app->make(Kernel::class)->bootstrap(); + } + + protected function isReadyToSaveProductionData(): bool + { + if ($token = ParallelTesting::token()) { + unlink(config('auto-doc.tmp_dir') . "/worker_{$token}_in_progress.flag"); + + if (empty(glob(config('auto-doc.tmp_dir') . '/worker_*_in_progress.flag'))) { + $this->mergeTempDocumentation(); + + return true; + } + } else { + return true; + } + + return false; + } + + protected function mergeTempDocumentation(): void + { + $swaggerService = app(SwaggerService::class); + + $resultDoc = []; + + $tmpPaths = glob(config('auto-doc.tmp_dir') . '/temp_documentation_*.json'); + + foreach ($tmpPaths as $tmpDocFilePath) { + $tmpDoc = json_decode(file_get_contents($tmpDocFilePath), true); + + if (empty($resultDoc)) { + $resultDoc = $tmpDoc; + } else { + $swaggerService->mergeOpenAPIDocs($resultDoc, $tmpDoc); + } + } + + $swaggerService->saveTmpData($resultDoc); + } +} diff --git a/src/Support/PHPUnit/EventSubscribers/ApplicationStartedSubscriber.php b/src/Support/PHPUnit/EventSubscribers/ApplicationStartedSubscriber.php new file mode 100644 index 0000000..4bbf27e --- /dev/null +++ b/src/Support/PHPUnit/EventSubscribers/ApplicationStartedSubscriber.php @@ -0,0 +1,29 @@ +createApplication(); + + if ($token = ParallelTesting::token()) { + touch(config('auto-doc.tmp_dir') . "/worker_{$token}_in_progress.flag"); + } + } + + protected function createApplication(): void + { + $app = require Application::inferBasePath() . '/bootstrap/app.php'; + + $app->loadEnvironmentFrom('.env.testing'); + $app->make(Kernel::class)->bootstrap(); + } +} diff --git a/src/Support/PHPUnit/EventSubscribers/SwaggerSaveDocumentationSubscriber.php b/src/Support/PHPUnit/EventSubscribers/SwaggerSaveDocumentationSubscriber.php deleted file mode 100644 index 6e3f2f3..0000000 --- a/src/Support/PHPUnit/EventSubscribers/SwaggerSaveDocumentationSubscriber.php +++ /dev/null @@ -1,26 +0,0 @@ -createApplication(); - - app(SwaggerService::class)->saveProductionData(); - } - - protected function createApplication(): void - { - $app = require base_path('bootstrap/app.php'); - - $app->loadEnvironmentFrom('.env.testing'); - $app->make(Kernel::class)->bootstrap(); - } -} diff --git a/src/Support/PHPUnit/Extensions/SwaggerExtension.php b/src/Support/PHPUnit/Extensions/SwaggerExtension.php index 0b7c566..8d8ebf1 100644 --- a/src/Support/PHPUnit/Extensions/SwaggerExtension.php +++ b/src/Support/PHPUnit/Extensions/SwaggerExtension.php @@ -6,12 +6,14 @@ use PHPUnit\Runner\Extension\Facade as EventFacade; use PHPUnit\Runner\Extension\ParameterCollection; use PHPUnit\TextUI\Configuration\Configuration; -use RonasIT\AutoDoc\Support\PHPUnit\EventSubscribers\SwaggerSaveDocumentationSubscriber; +use RonasIT\AutoDoc\Support\PHPUnit\EventSubscribers\ApplicationFinishedSubscriber; +use RonasIT\AutoDoc\Support\PHPUnit\EventSubscribers\ApplicationStartedSubscriber; final class SwaggerExtension implements PhpunitExtension { public function bootstrap(Configuration $configuration, EventFacade $facade, ParameterCollection $parameters): void { - $facade->registerSubscriber(new SwaggerSaveDocumentationSubscriber()); + $facade->registerSubscriber(new ApplicationStartedSubscriber()); + $facade->registerSubscriber(new ApplicationFinishedSubscriber()); } }