ext/dba/tests: sort expected test output (#14962)

* ext/dba/tests/setup/setup_dba_tests.inc: sort test output

Iterating through a database with firstkey() and nextkey() is
guaranteed to retrieve all rows, but apparently not in any particular
order. This is causing a test failure for at least one user, so we
steal the sort() approach from GDBM to ensure that the output is
predictable.

* ext/dba/tests/dba_*.phpt: sort expected test output

The actual output is now sorted for consistency, so we need to update
the expected output as well. As a nice side effect, some differences
in the expected outputs for the various engines have been eliminated.

Closes GH-14786

* ext/pgsql/tests/80_bug14383.phpt: sort expected test output

This test uses a routine from ext/dba that now sorts its (actual)
output, so we have to sort the expected output here as well.

* ext/dba/tests/setup/setup_dba_tests.inc: update comment

After doing some more digging, it looks like GDBM isn't the only
engine where the iteration order with firstkey() and nextkey()
might change unexpectedly.
This commit is contained in:
Michael Orlitzky 2024-07-25 20:16:52 -04:00 committed by GitHub
parent ab449a7e46
commit 44b0baf705
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 47 additions and 32 deletions

View File

@ -29,12 +29,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
[key10]name10: Content String 10
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
[key10]name10: Content String 10
[key30]name30: Content String 30
Total keys: 6
Key 1 exists? N
Key 2 exists? Y

View File

@ -35,12 +35,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
key4: Another Content String
key2: Content String 2
key5: The last content string
[key10]name10: Content String 10
name9: Content String 9
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
Total keys: 6
Key 1 exists? N
Key 2 exists? Y
@ -81,12 +81,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
key4: Another Content String
key2: Content String 2
key5: The last content string
[key10]name10: Content String 10
name9: Content String 9
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
Total keys: 6
Key 1 exists? N
Key 2 exists? Y

View File

@ -30,14 +30,14 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
[key10]:
[key10]name10: Content String 10
[key30]:
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
Total keys: 8
Key 1 exists? N
Key 2 exists? Y

View File

@ -36,12 +36,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
key4: Another Content String
key2: Content String 2
key5: The last content string
[key10]name10: Content String 10
name9: Content String 9
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
Total keys: 6
Key 1 exists? N
Key 2 exists? Y
@ -82,12 +82,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
key4: Another Content String
key2: Content String 2
key5: The last content string
[key10]name10: Content String 10
name9: Content String 9
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
Total keys: 6
Key 1 exists? N
Key 2 exists? Y

View File

@ -35,12 +35,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
[key10]name10: Content String 10
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
[key10]name10: Content String 10
[key30]name30: Content String 30
Total keys: 6
Key 1 exists? N
Key 2 exists? Y
@ -81,12 +81,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
[key10]name10: Content String 10
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
[key10]name10: Content String 10
[key30]name30: Content String 30
Total keys: 6
Key 1 exists? N
Key 2 exists? Y

View File

@ -30,12 +30,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
[key10]name10: Content String 10
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
[key10]name10: Content String 10
[key30]name30: Content String 30
Total keys: 6
Key 1 exists? N
Key 2 exists? Y

View File

@ -102,14 +102,29 @@ function run_standard_tests_ex(string $handler, string $name, LockFlag $lock, bo
echo 'Try to remove key 1 again', \PHP_EOL;
var_dump(dba_delete("key1", $db_writer));
// Fetch data
// Fetch and sort data. We sort to guarantee that the output is
// consistent across invocations and architectures. When iterating
// with firstkey() and nextkey(), several engines (GDBM, LMDB,
// QDBM) make no promise about the iteration order. Others (TCADB,
// DBM) explicitly state that the order is arbitrary. With GDBM at
// least, the order appears platform-dependent -- we have a report
// in Github issue 14786. GDBM's own test suite sorts this output,
// suggesting that sorting is a reasonable workaround for the issue.
$output = [];
$key = dba_firstkey($db_writer);
$total_keys = 0;
while ($key) {
echo $key, ': ', dba_fetch($key, $db_writer), \PHP_EOL;
$output[] = $key . ': ' . dba_fetch($key, $db_writer) . \PHP_EOL;
$key = dba_nextkey($db_writer);
$total_keys++;
}
sort($output, SORT_STRING);
foreach ($output as $line) {
echo $line;
}
echo 'Total keys: ', $total_keys, \PHP_EOL;
for ($i = 1; $i < 6; $i++) {
echo "Key $i exists? ", dba_exists("key$i", $db_writer) ? 'Y' : 'N', \PHP_EOL;

View File

@ -39,12 +39,12 @@ bool(true)
bool(true)
Try to remove key 1 again
bool(false)
[key10]name10: Content String 10
[key30]name30: Content String 30
key2: Content String 2
key4: Another Content String
key5: The last content string
name9: Content String 9
[key10]name10: Content String 10
[key30]name30: Content String 30
Total keys: 6
Key 1 exists? N
Key 2 exists? Y