Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPLIB-981: Add tests for examples #1002

Merged
merged 13 commits into from
Nov 22, 2022

Conversation

alcaeus
Copy link
Member

@alcaeus alcaeus commented Nov 14, 2022

PHPLIB-981

This PR adds tests for the example scripts. To ensure good coverage, the tests attempt to match against the output of the example scripts. This requires a change in the examples to no longer output to STDERR, as PHPUnit considers any output to STDERR as condition to fail a test and doesn't allow asserting against it.

When running the tests, I noticed that the tests fail on sharded clusters, because the command replies are different. This would complicate the output matchers by quite a lot, so I'm wondering if it's actually worth matching against the actual command output, or if we're happy asserting that the rough information is the same.

I will likely also change the examples for type maps and persistable classes to no longer use var_dump. Having xdebug installed (which is likely on dev machines) produces different output for var_dump, making the tests fail on developer machines.


$expectedOutput = <<<'OUTPUT'
drop command started
command: { "drop" : "coll", "$db" : "test", "lsid" : { %s }%S }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command output here and all subsequent command documents could be replaced with { %s } if we're not interested in asserting the actual command results.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any reason to assert the command contents. Just use { %s } for everything, or rather: command: %s. I think the only point of testing these was to ensure they actually run with no PHP errors or uncaught exceptions. We don't need the same level of scrutiny as the doc snippets that go in the MongoDB manual.

];
}

public function testChangeStream(): void
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test (and testWithTransaction) below was extracted as it needs to check whether change streams are supported. I initially wanted to provide a closure in the data provider, but that causes errors due to closures not being serialisable (which is required to run tests in isolation). Instead of passing a string callable I opted for extracting the tests from the data provider and calling the original test method manually instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but that causes errors due to closures not being serialisable

Looks like a job for jeremeamia/super_closure! 🦸

Since deprecated for opis/closure. I'm not actually suggesting this.

Comment on lines -56 to +53
fprintf(STDERR, "Aborting after 3 seconds...\n");
printf("Aborting after 3 seconds...\n");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary to avoid PHPUnit considering the tests failed due to output, and to allow asserting against the full test output.

@alcaeus alcaeus changed the title PHPLIB-891: Add tests for examples PHPLIB-981: Add tests for examples Nov 14, 2022

$expectedOutput = <<<'OUTPUT'
drop command started
command: { "drop" : "coll", "$db" : "test", "lsid" : { %s }%S }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any reason to assert the command contents. Just use { %s } for everything, or rather: command: %s. I think the only point of testing these was to ensure they actually run with no PHP errors or uncaught exceptions. We don't need the same level of scrutiny as the doc snippets that go in the MongoDB manual.

];
}

public function testChangeStream(): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but that causes errors due to closures not being serialisable

Looks like a job for jeremeamia/super_closure! 🦸

Since deprecated for opis/closure. I'm not actually suggesting this.

{ "_id" : { "_data" : "%s" }, "operationType" : "insert", "clusterTime" : { "$timestamp" : { "t" : %d, "i" : %d } }%S, "fullDocument" : { "_id" : { "$oid" : "%s" }, "x" : 6 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : { "$oid" : "%s" } } }
{ "_id" : { "_data" : "%s" }, "operationType" : "insert", "clusterTime" : { "$timestamp" : { "t" : %d, "i" : %d } }%S, "fullDocument" : { "_id" : { "$oid" : "%s" }, "x" : 7 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : { "$oid" : "%s" } } }
{ "_id" : { "_data" : "%s" }, "operationType" : "insert", "clusterTime" : { "$timestamp" : { "t" : %d, "i" : %d } }%S, "fullDocument" : { "_id" : { "$oid" : "%s" }, "x" : 8 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : { "$oid" : "%s" } } }
{ "_id" : { "_data" : "%s" }, "operationType" : "insert", "clusterTime" : { "$timestamp" : { "t" : %d, "i" : %d } }%S, "fullDocument" : { "_id" : { "$oid" : "%s" }, "x" : 9 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : { "$oid" : "%s" } } }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fragile should the server introduce new response fields to change events. I'd suggest changing this to { %s } assertions for each line. You can also lower the number of inserts in the example (maybe 5 instead of 10) if you want to make this more concise. There's really no reason it needs to emit this much output.

@alcaeus alcaeus force-pushed the phplib-891-test-examples branch 2 times, most recently from c6f6ef1 to bd9d8d7 Compare November 15, 2022 09:48
On sharded cluster, collection deletion is sometimes not propagated across the cluster, leading to different output even if we drop the collection before the test.
@alcaeus alcaeus force-pushed the phplib-891-test-examples branch 2 times, most recently from e4161ce to 267535a Compare November 21, 2022 10:29
@alcaeus alcaeus force-pushed the phplib-891-test-examples branch from 267535a to b58811c Compare November 21, 2022 11:22
@@ -11,6 +11,10 @@ public function setUp(): void
{
parent::setUp();

if ($this->isShardedCluster()) {
$this->markTestSkipped('Examples are not tested on sharded clusters.');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obligatory @amschwerin:

20160923_andy_sharding

I am a creature of habit: mongodb/specifications#565 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried hard to keep those tests in, but unfortunately some tests failed on sharing due to a server error ("no progress was made executing batch op after 5 rounds"). Since we're only dealing with examples here I opted against spending more time on testing against sharded clusters and gave up trying.

@alcaeus alcaeus marked this pull request as ready for review November 22, 2022 07:39
@alcaeus alcaeus requested a review from jmikola November 22, 2022 07:39
@alcaeus
Copy link
Member Author

alcaeus commented Nov 22, 2022

Note: test failures against MongoDB latest tracked in PHPLIB-1044.

Copy link
Member

@jmikola jmikola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some optional suggestions to make the test collections consistent with their filename and consider a property hint instead of calling assert(). Everything else looks fine as-is.

@@ -325,6 +326,8 @@ public function execute(Server $server)
$type = key($operation);
$args = current($operation);

assert(is_array($args));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Since $operations is private couldn't you also just add an array property type hint to it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the error crept up due to a change in the baseline, so I've removed this assert call and updated the baseline instead. Fixing this would've required updating types in more than just this file, which is why it was initially deferred. We have follow-up tickets to fix issues like this one.

alcaeus and others added 2 commits November 22, 2022 09:57
Co-authored-by: Jeremy Mikola <jmikola@gmail.com>
Fixing this requires a larger-scale refactoring of the types involved, which was deferred to a later date.
@alcaeus alcaeus force-pushed the phplib-891-test-examples branch from 4cbe45a to f60243b Compare November 22, 2022 08:58
@alcaeus alcaeus merged commit b309cf8 into mongodb:master Nov 22, 2022
@alcaeus alcaeus deleted the phplib-891-test-examples branch November 22, 2022 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants