Repository navigation
Wait for the Flyway container and split the container lifecycle into segregated collaborators. - #30
Merged
Conversation
… into segregated collaborators.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FlywayDockerContainer::cleanAndMigrateslept a fixed 10 seconds after it started the Flyway container instead of waiting for it to finish. Under load, the integration suites of the services that consume the library started before the migrations ended and failed withSQLSTATE[42S02] Base table or view not foundandContainerWaitTimeout. I reproduced it with a migration that runsDO SLEEP(15), and the old code failed withTable 'test_adm.slow' doesn't exist.A second race sat in front of it. The container started before
docker cpcopied the migrations, so Flyway could read an empty folder, exit with 0 and apply nothing.The refactor also found four defects. The
CREATE DATABASEandGRANTsetup of the MySQL container never ran, because it reacheddocker execas a single argument and failed silently.runIfNotExists()did not wait for the database.run()ignored$waitAfterStarted.pullImage()never ran in the background, against what the README said.What changes
cleanAndMigrate,migrate,repairandvalidaterun the Flyway container to completion, with a timeout of 120 seconds by default. A failure raisesContainerExitUnsuccessfulwith the stderr of Flyway, a timeout raisesContainerWaitTimeout, and the container is removed on success, failure and timeout.docker cpand only then starts.TinyBlocks\Time\Duration. The lifecycle is split into small immutable collaborators with one responsibility each:ContainerLauncher,OneShotContainer,ContainerSharing,NetworkProvisioner,MySQLStartup,JdbcUrl,StrictExecutorandCommandLine. The sequence of create, copy, start, wait and read the exit lives once, inrunToCompletion.nullor a no-op.DockerCommandkeeps onlytoArguments(), andDockerCommandWithTimeoutaddstimeout(): Durationfor the two commands that have one.ContainerStartedkeeps what every started container does,DisposableContaineraddsremoveandstopOnShutdown, andSharedContaineraddswasReused.DockerClientandDockerCommandare the seams to Docker. They replace the protected constructor and theTestable*subclasses that existed only for tests.infection/infectiongoes to^0.35, which fixes thecacheResultdeprecation raised by PHPUnit 13.3. The--coverageargument leaves thetestsscript, because it handed the timings of the integration tests to the mutation run and 240 of 313 mutants were skipped by time.Public API
The change is breaking, so the release is
4.0.0.Removed:
DockerContainer,MySQLContainerandFlywayContainer,runWhenwithEnvironmentFlag,pullImage()andwithCleanDisabled().Changed:
from(image, ?name)becomesfrom(image)pluswithName().run()returns aDisposableContainerandrunIfNotExists()returns aSharedContainer. The Flyway verbs return anExecutionCompletedwith the output.withValidateMigrationNaming(bool)becomeswithMigrationNamingValidation(). The exceptions moved fromInternal\ExceptionstoExceptions.The README has a table to migrate from 3.x.
Names scoped to the runner
A service that runs two suites at once should give its containers a name scoped to the runner, for example
sprintf('<service>-adm-test-%s', gethostname()). Two runs that share a fixed name share one MySQL, and one of them cleans the schema the other is using. The README shows the bootstrap.Related issue
None.
Checklist
make reviewpasses.make testspasses. 161 tests, lines 100% (687/687), MSI 100% (284 of 284 killed).