Add INFECTION and TEST_TOKEN environment variables for each Mutant process#1504
Add INFECTION and TEST_TOKEN environment variables for each Mutant process#1504maks-rafalko merged 2 commits intomasterfrom
INFECTION and TEST_TOKEN environment variables for each Mutant process#1504Conversation
…ocess to make it possible to run tests for different databases Same approach uses Paratest to avoid conflicts when 2 parallel processes can write to the same database.
|
|
||
| yield 'nominal' => [4]; | ||
|
|
||
| yield 'infinite' => [PHP_INT_MAX]; |
There was a problem hiding this comment.
Is this something we can no longer test?
There was a problem hiding this comment.
yes, since now we use range(1, $threadsCount), it leads to
1) Infection\Tests\Process\Runner\ParallelProcessRunnerTest::test_it_handles_all_kids_of_processes_with_infinite_threads with data set "infinite" (9223372036854775807)
ValueError: The supplied range exceeds the maximum array size: start=1 end=9223372036854775807
But I've added similar test in the next commit, where threads count is bigger than number of processes
INFECTION and TEST_TOKEN environment variables for each Mutant process
|
How did we decide that we need this token to be taken from a pool? Because this whole ordeal could be simplified, greatly so, if the token could be sequential, and the user would simply do: $serverID = $TEST_TOKEN % 3;If they have only three servers. A demo. With sequential tokens we will number the mutations as we create them, telling them to add a new env variable, and that will it, nothing more. |
|
I just thought that we don't need even that. If a user could know that tests are under mutation testing, they can implement a very simple algo to find a free server: And in Or it can be: So I'm not sure this complication was necessary in the first place. |
|
I've answered here with our use case for and for me, as a user of Infection, using And also, as I explained in the referenced issue, Paratest uses doctrine:
dbal:
dbname: 'db_%env(default:test_token:TEST_TOKEN)%' |
Add
INFECTIONandTEST_TOKENenvironment variables for each Mutant process to make it possible to run functional tests for different databases.Background:
We have a lot of functional tests that do real SQL queries to MySQL and decided to run tests in parallel. To achieve it, we integrated Paratest library.
Parallel processes can not write to the same database, because tests start to conflict with each other. To fix this issue, Paratest provides
TEST_TOKEN=<int>environment variable for each process that can be used to set up different connections to the databases.So if you have 3 parallel processes, these processes will use
db_1,db_2,db_3correspondingly.Infection's issue with functional tests
The same goes for Infection. As soon as we start using more than 1 thread, our
ParallelProcessRunnerruns processes in parallel, and withoutTEST_TOKENbeing passed, all those processes use the same database, which fails the test, making the majority of the Mutants killed.This PR adds
TEST_TOKEN=<int>env variable for each "mutant process".Note: we can't use round-robin for thread indexes, because different processes take different amount of time. Consider the following example:
Imagine -we run Infection with 3 threads:
infection -j3, and we have 4 mutations, so we need to run 4 processes when 3 of them can be in parallelIn this example, as soon as Process 3 finishes its work, we can run Process 4. It will mean that at the same time we will have exactly 3 parallel processes
But, since Process 1 takes too much time, round-robin algorithm gives
TEST_TOKENvalues of 1 for Process 4. And we have a situation where both processes Process 1 and Process 4 work with the same database at the same time.To avoid such an issue, in this PR
TEST_TOKENgets the first available (free) index that is not used at this point of time by any other processes. For example above, as soon as Process 3 finishes its job, Process 4 will getTEST_TOKEN=3, because values 1 and 2 are still busy.Process 1, TEST_TOKEN = 1 |--------------------------------------------------| Process 2, TEST_TOKEN = 2 |------------| Process 3, TEST_TOKEN = 3 |--| - Process 4, TEST_TOKEN = 1 + Process 4, TEST_TOKEN = 3 |-----------------------------------------------------|INFECTIONenv variableIn our application, we have a custom
bootstrupfor PHPUnit, where we removevar/cachefolderSince Infection runs PHPUnit in separate processes, this bootstrap file gets called for each Mutant, again breaking the whole process, because while Process 1 can work, Process 3 removes its cache.
So, we need to understand when PHPUnit process is executed from Infection, and skip such removing:
This PR:
INFECTIONandTEST_TOKENenvironment variables site#214