From a4392340d5a37357fd00546c5320b0acb00c9548 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 14 Nov 2023 19:10:06 +0100 Subject: [PATCH 1/3] BUGFIX: Avoid doctrine to drop `cr_*` tables via `doctrine:migrationgenerate` --- Neos.ContentRepositoryRegistry/Configuration/Settings.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml index bab78f378aa..650abaaff54 100644 --- a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml +++ b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml @@ -1,5 +1,11 @@ Neos: Flow: + persistence: + doctrine: + migrations: + ignoredTables: + 'cr_.*': true + # Improve debug output for node objects by ignoring large classes error: debugger: From 7f319fc60ec75e7e8f909ee4ae16308647c8053d Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 14 Nov 2023 19:22:42 +0100 Subject: [PATCH 2/3] TASK speedup behavioral test by ninety-three percent With this change we setup the content repository only once for all tests `$contentRepository->setUp();`. The projections contents are cleared in each iteration via `$contentRepository->resetProjectionStates();` and this works quite well for the escr core tests. For tests using the `@flowEntities` annotation and database reset we must avoid to drop all the escr tables as otherwise we would need to setup the cr again. This will be fixed in https://github.com/neos/behat/pull/37. Why are we going through so much hassle to (hackily) setup the cr only once? Because each projection calls `$schemaManager->createSchema()` twice when being setup and this slows down test enormously by 80% --- .../TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php | 5 +++-- .../Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php | 4 +--- .../Classes/Behavior/CRRegistrySubjectProvider.php | 5 +++-- .../Tests/Behavior/Features/Bootstrap/FeatureContext.php | 5 ++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php b/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php index bfcb0806fc9..24d758de0f4 100644 --- a/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php +++ b/Neos.ContentRepository.BehavioralTests/Classes/TestSuite/Behavior/CRBehavioralTestsSubjectProvider.php @@ -36,7 +36,7 @@ trait CRBehavioralTestsSubjectProvider * A runtime cache of all content repositories already set up, represented by their ID * @var array */ - protected array $alreadySetUpContentRepositories = []; + protected static array $alreadySetUpContentRepositories = []; protected ?ContentRepository $currentContentRepository = null; @@ -169,8 +169,9 @@ protected function setUpContentRepository(ContentRepositoryId $contentRepository * Catch Up process and the testcase reset. */ $contentRepository = $this->createContentRepository($contentRepositoryId); - if (!in_array($contentRepository->id, $this->alreadySetUpContentRepositories)) { + if (!in_array($contentRepository->id, self::$alreadySetUpContentRepositories)) { $contentRepository->setUp(); + self::$alreadySetUpContentRepositories[] = $contentRepository->id; } /** @var EventStoreInterface $eventStore */ $eventStore = (new \ReflectionClass($contentRepository))->getProperty('eventStore')->getValue($contentRepository); diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 304d9cab357..48335274b84 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -80,15 +80,13 @@ trait CRTestSuiteTrait use WorkspaceDiscarding; use WorkspacePublishing; - protected function setupCRTestSuiteTrait(bool $alwaysRunCrSetup = false): void + protected function setupCRTestSuiteTrait(): void { if (getenv('CATCHUPTRIGGER_ENABLE_SYNCHRONOUS_OPTION')) { CatchUpTriggerWithSynchronousOption::enableSynchronicityForSpeedingUpTesting(); } } - private static bool $wasContentRepositorySetupCalled = false; - /** * @BeforeScenario * @throws \Exception diff --git a/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php b/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php index 104fe983c8a..6bacd50a538 100644 --- a/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php +++ b/Neos.ContentRepositoryRegistry.TestSuite/Classes/Behavior/CRRegistrySubjectProvider.php @@ -34,7 +34,7 @@ trait CRRegistrySubjectProvider /** * @var array */ - protected array $alreadySetUpContentRepositories = []; + protected static array $alreadySetUpContentRepositories = []; /** * @template T of object @@ -62,8 +62,9 @@ public function iInitializeContentRepository(string $contentRepositoryId): void $eventTableName = sprintf('cr_%s_events', $contentRepositoryId); $databaseConnection->executeStatement('TRUNCATE ' . $eventTableName); - if (!in_array($contentRepository->id, $this->alreadySetUpContentRepositories)) { + if (!in_array($contentRepository->id, self::$alreadySetUpContentRepositories)) { $contentRepository->setUp(); + self::$alreadySetUpContentRepositories[] = $contentRepository->id; } $contentRepository->resetProjectionStates(); } diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php index a7c9f3ce289..d67a312c3a6 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php @@ -11,7 +11,6 @@ */ use Behat\Behat\Context\Context as BehatContext; -use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Neos\Behat\FlowBootstrapTrait; use Neos\Behat\FlowEntitiesTrait; use Neos\ContentRepository\BehavioralTests\TestSuite\Behavior\CRBehavioralTestsSubjectProvider; @@ -50,7 +49,7 @@ public function __construct() $this->environment = $this->getObject(Environment::class); $this->contentRepositoryRegistry = $this->getObject(ContentRepositoryRegistry::class); - $this->setupCRTestSuiteTrait(true); + $this->setupCRTestSuiteTrait(); } /* @@ -63,7 +62,7 @@ public function __construct() /** * @BeforeScenario */ - public function resetContentRepositoryComponents(BeforeScenarioScope $scope): void + public function resetContentRepositoryComponents(): void { GherkinTableNodeBasedContentDimensionSourceFactory::reset(); GherkinPyStringNodeBasedNodeTypeManagerFactory::reset(); From 0505bb2ca3a7067a5189f4be2baaee2f472a5f76 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 14 Nov 2023 19:25:50 +0100 Subject: [PATCH 3/3] TASK speedup Neos.Neos behavioral test by removing `sleep(2);` Currently we run tests only in sync mode `CATCHUPTRIGGER_ENABLE_SYNCHRONOUS_OPTION=1` as the async mode is broken: https://github.com/neos/neos-development-collection/issues/4612 I presume the `sleep(2)` is an artefact for the async tests to work at some earlier point. --- Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php index d67a312c3a6..10f73e2a200 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php @@ -73,9 +73,6 @@ public function resetContentRepositoryComponents(): void */ public function resetPersistenceManagerAndFeedbackCollection() { - // FIXME: we have some strange race condition between the scenarios; my theory is that - // somehow projectors still run in the background when we start from scratch... - sleep(2); $this->getObject(\Neos\Flow\Persistence\PersistenceManagerInterface::class)->clearState(); // FIXME: FeedbackCollection is a really ugly, hacky SINGLETON; so it needs to be RESET! $this->getObject(\Neos\Neos\Ui\Domain\Model\FeedbackCollection::class)->reset();