Failing on PostgreSQL 9.1:
https://www.drupal.org/pift-ci-job/986641
https://www.drupal.org/pift-ci-job/991466
1) Drupal\KernelTests\Core\Database\SchemaTest::testSchemaChangePrimaryKey with data set "composite_primary_key" (array('test_field', 'other_test_field'), array('test_field_renamed', 'other_test_field'))
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
Array (
- 0 => 'test_field_renamed'
- 1 => 'other_test_field'
+ 0 => 'other_test_field'
+ 1 => 'test_field_renamed'
)
/var/www/html/core/tests/Drupal/KernelTests/KernelTestBase.php:1112
/var/www/html/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php:765
2) Drupal\KernelTests\Core\Database\SchemaTest::testSchemaChangePrimaryKey with data set "composite_primary_key_different_order" (array('other_test_field', 'test_field'), array('other_test_field', 'test_field_renamed'))
Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
Array (
- 0 => 'other_test_field'
- 1 => 'test_field_renamed'
+ 0 => 'test_field_renamed'
+ 1 => 'other_test_field'
)
/var/www/html/core/tests/Drupal/KernelTests/KernelTestBase.php:1112
/var/www/html/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php:765
Comments
Comment #2
tstoecklerCannot reproduce this on Postgres 10.4, which I have locally.
I ran the test 100 hundred times and verified that it passed each time. For anyone following along at home, this is what I did:
Will now try to run it with 9.2 as that's the oldest version that's on Docker Hub.
Comment #3
tstoecklerHmm... same result with
9.2.23:-/Comment #4
tstoecklerHehe, searching for "Postgres 9.1" on Docker Hub, I found this little fellow: drupalci/pgsql-9.1. So I ran the above again in the same environment that Drupal.org runs its tests and I again got the same results. So not really sure what to do here.
One thing I thought that may be happening is that due to the concurrency of the tests that there is a race between the different data sets
composite_primary_keyandcomposite_primary_key_different_orderin::testSchemaChangePrimaryKey()? I.e. while the first data set is being executed the second is being run as well and then the assertion on the first one fails because they are operating on the same table? That would explain the different order between expected and actual results.When running the tests locally, a different database prefix is used for each data set, so I can't reproduce this locally, but I don't really know much about how the tests are run on Drupal.org, so...
Comment #5
alexpottpostponed is not the correct status here. We have a confirmed random fail here.
Comment #7
alexpottTrying to have a patch that always exposes the problem.
Comment #9
alexpottSo we can reproduce it seemingly. I have a hunch that this is to do with the fact this query
$result = $this->connection->query("SELECT a.attname, i.indkey FROM pg_index i JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) WHERE i.indrelid = '{" . $table . "}'::regclass AND i.indisprimary")->fetchAllKeyed();is not quite working the way we expect it too. Seeing if the table name has anything to do with it.Comment #11
alexpottSo the fix looks effective. Not sure how to explain it though. Also not entirely sure that that matters.
Comment #12
alexpott#9 included an unrelated fix for cache clearing on menu save and that code in #9 can be ignored.
Comment #13
alexpottoh that's good #9 still failed eventually for the same reason so #11 doesn't work. Hmmm.
Comment #14
daffie commentedWhat also could be true is that the PostgreSQL table "pg_index" is not updated as fast as we are changing the table structure and testing the changes. It would explain why the patch from comment #10 would do the trick.
Comment #15
alexpott@daffie we drop all the tables in the tests ::tearDown() method. One thought is that since I've not seen this locally and I've run this test on Postgres test a lot recently is that one difference between my local and Drupal is concurrency. Maybe that is having an impact.
Also the fix proposed in #11 turned out not to work.
Comment #16
daffie commentedIs it maybe an idea to add some sleep methods, so that the PostgreSQL database has some time to update the pg_index table.
Comment #17
alexpott@daffie Postgres is a transactional database I'm pretty sure pg_index is consistent. If not this would bbe a major bug in postgres's ACID compliance.
Comment #18
daffie commented@alexpott: You are sure that every Schema class call is its own transaction?
Comment #19
alexpott@daffie it feels super weird if a schema change is not transactional. That said I'm not sure about how Postgres handles indexes that change as a result of schema changes. So maybe a sleep is worth trying.
Comment #20
daffie commented@alexpott: We can also split up the test in smaller pieces, so that every test only does one index change. Every test should then be its own transaction.
Comment #21
alexpott@daffie that doesn't help us get to the root cause - it'd be great to understand why this is happening. ATM it doesn't make much sense.
Comment #22
plachComment #24
krzysztof domańskiThe problem still exists.
https://www.drupal.org/pift-ci-job/1411152
https://www.drupal.org/pift-ci-job/1365057
https://www.drupal.org/pift-ci-job/1362262
https://www.drupal.org/pift-ci-job/1359942
Comment #26
krzysztof domańskiAfter renaming one of the columns, the
\Drupal\Core\Database\Driver\pgsql\DatabaseSchema::findPrimaryKeyColumns()method returns the correct primary keys but in the wrong order.alexpott confirmed in #9 that using different table names does not solve this problem.
I'm testing the impact of the PostgreSQL version and the
concurrencyparameter. I limit other factors. I'm only testing the field name change.Comment #27
krzysztof domańskiSee #26. The problem does not apply to the new version of PostgreSQL. Tests were successful in version 9.5. The number of tests run simultaneously matters (
concurrency: 1).Everything confirms alexpott's suggestion that the reason is in the SELECT query.
Maybe the solution is to add 'ORDER BY' to the SELECT query? Otherwise, the solution is unlikely to be trivial. I suggest that you first get rid of the troublesome random test failure. This is critical and applies only to tests run simultaneously when concurrency > 1.
I add a follow-up to solve this problem in another task. #3096608: On PostgreSQL 9.1 after renaming one of the fields, the DatabaseSchema::findPrimaryKeyColumns method returns the correct keys but in the wrong order.
Comment #28
mradcliffeThis might be related to orphaned sequences because of #3028706: New serial columns do not own sequences. Not specifically the addPrimaryKey assertion, but it being in the same test case as SchemaTest and due to concurrency, length of the key, and databases (re)used in test bots?
Comment #29
alexpott@Krzysztof Domański why do we need another task #3096608: On PostgreSQL 9.1 after renaming one of the fields, the DatabaseSchema::findPrimaryKeyColumns method returns the correct keys but in the wrong order - isn't that what this issue is going to solve?
Comment #30
krzysztof domańskiI close #3096608 then.
Comment #31
krzysztof domańskiIgnore
Comment #32
krzysztof domańskiIt also fails elsewhere.
Comment #33
krzysztof domańskiIgnore
Comment #34
krzysztof domańskiStupid mistake. Ignore.
Comment #35
krzysztof domańskiLooks like technical debt, but it works. One frequent random test failure less.
Comment #36
krzysztof domańskiSee #26 and #27. Primary key sorting works on PostgreSQL 9.1 in the real world. The problem occurs only in tests, because we use many machines, concurrency > 1.
Proposed solution:
Comment #37
daffie commented@Krzysztof Domański: Great work, thanks.
The problem with the solution from comment #36 is that if you run the test with a concurrency is 1 and with PostgreSQL < 9.5, the test will fail and it should pass. My suggestion would be to skip the tests for PostgreSQL versions < 9.5.
Comment #38
krzysztof domańskiLet's see what happens. Each test repeated 100 times.
Comment #39
krzysztof domańskiCorrection of a damaged previous patch.
Comment #40
krzysztof domańskiAll pass in PostgreSQL 9.5. Also pass when you run the test with a concurrency is 1 and with PostgreSQL 9.1.
We do not need to exclude tests for older versions. Sorting arrays before comparison will solve the problem.
Comment #41
alexpottI think the whole point of the test is to test the order of the columns so doing this makes the test invalid.
I think we need to understand why concurrency is impacting this test.
Comment #42
daffie commentedBack to needs work.
Comment #43
catchIf we do end up wanting to sort the arrays, a note that the way to do that now in phpunit is ::assertEqualsCanonicalizing.
But given we're testing the sorting of the primary key, agreed that's not a viable fix anyway.
Comment #44
tstoecklerBTW, I posted #3119170: Optimize pgsql/Schema::findPrimaryKeyColumns() for Postgres >= 9.6 which is probably of interest to people here. Not yet sure if it will actually impact this, but it's certainly related.
Comment #46
krzysztof domański1. Tests repeated 100 times confirmed that the problem only affects the old version (PostgreSQL 9.1). See #39.
2. PostgreSQL version requirements raised to 10.0 so this issue is no longer critical.
It may still appear in older versions of drupal (8.8 and 8.9), which is why I leave the issue open.
Affected Drupal 8 with PostgreSQL 9.1.
Comment #47
krzysztof domańskiConfirmation that it is no longer occur in Drupal 9.
Comment #50
krzysztof domańskiNo longer occur in Drupal 9 because PostgreSQL version requirements raised to 10.0.. Let's close this issue.
Comment #52
xjm