-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Allow single server instance in test suite #7262
Conversation
Codecov Report
@@ Coverage Diff @@
## master #7262 +/- ##
==========================================
- Coverage 94.03% 93.97% -0.06%
==========================================
Files 179 179
Lines 13137 13140 +3
==========================================
- Hits 12353 12348 -5
- Misses 784 792 +8
Continue to review full report at Codecov.
|
Interesting, let's see if I got this right... You are saying that currently for each test a new server is spun up and therefore each test runs on a clean server instance. Some tests may currently only be passing, because they run on a clean server instance. Your approach to identify poorly written tests is to not spin up a new server for every test and see whether they fail. But couldn't the opposite be just as true? A test may rely on a previously run test and the change that test did to the server? |
Thats basically it. There are a lot of other benefits to using this approach. I have noticed some weird behavior. The current I'm still looking into this as this is just a first pass. I would like to never have to use Got the test suite to 5-7 minutes. |
Interesting approach. I think if the server is not restarted for every test, then the tests should run in random order. Otherwise the likeliness that a test passes only based on a previously run test increases. I think randomizing the order will reveal a lot, did you try that?
Very cool, especially now that we increased the test environments |
These problems also exist in the JS SDK. Specifically the user spec. I'll randomize that suite first then this one. |
I updated my original post with a list of possible test suites to investigate. If anyone wants to give me a hand that would be much appreciated. |
@mtrezza I am comfortable with where this is at. Here is some of my observations with using single instance server.
I may have possibly fixed all Push related flaky tests. |
What is the general pattern we want to follow and enforce in future PRs? I think we need to decide on a pattern that we think works best to mitigate flaky tests and yield best code robustness, excluding any special cases a developer may want to test. That should be documented in the contribution guide as well, otherwise we'll always have a mix of patterns. I do not see a clear pattern before or after this PR, as the server is reconfigured at different points, sometimes in I think randomizing is a big step forward, and luckily that is controlled globally for all tests. Your suggestion of a global afterEach / beforeEach hits the points in this regard, maybe it is actually something we want? |
@mtrezza Sorry I updated my previous comment. |
There we go. I am not surprised, because a developer may as well deliberately (not) reconfigure a server between test. I think we need to decide on a pattern, document it and clean up existing tests to conform with it, which may take a while and happen gradually. Is it possible to randomize only certain files? That would help us to make this change gradually. In regards to pattern, that depends on whether randomized means all tests across all files or only tests within describes?
Me too! To not block #7214, maybe we can just clean up push tests with the new pattern we decide on and then already merge, and the rest afterwards.
How would the server then be reconfigured with a different configuration? |
My main goal for this PR was to fix #7080. I'm currently saving 4 minutes per mongo test. If we can keep this speed improvement while documenting a pattern I'm all for it.
Cleaning up existing tests would reduce the speed improvement. Here are some improvements in this PR and my reasoning behind them. I'll start with the first 2 test files. For clarity In this file there is 1 In this file each test has an After typing all that I came to a conclusion. The |
Thanks for explaining. I know you've done all the work already, but your explanation confirms for me that we need to find a pattern that works for all, it has to be documentable to guide developers and PR reviewers. My 2cts:
So these would already be rules:
Another suggestion:
This is the kind of rule set that we are currently missing I think. Ideally we can even build a CI test to enforce it. I assume this would bring a speed improvement, but maybe not the improvement we currently see in this PR, and that's also fine if there is a benefit in return. |
Another thing we should document is the use of In the following example, you should get the config after you reconfigureServer. I also noticed a few tests setting the config directly like
|
Yes, I'm using a similar pattern sometimes, and one has to be careful with this. We could disallow that in our "Test Quality Guide" if we think it's likely to be used incorrectly by developers. |
afterAll and afterEach has their uses.
I added automatic detection if a tests changes the single instance server. If a change is detected it calls resets it. This way users don't have to worry about it. I also added jasmine test reporter for debugging also. @davimacedo @mtrezza I think this is good to go. |
|
I see what you are saying, lucky our afterEach have little effect on randomness. If we want randomness there are a few things we need to do.
|
if (Object.keys(openConnections).length > 0) { | ||
fail('There were open connections to the server left after the test finished'); | ||
} | ||
TestUtils.destroyAllDataPermanently(true).then(done, done); | ||
await TestUtils.destroyAllDataPermanently(true); | ||
if (didChangeConfiguration) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a clever idea, but doesn't that cause an unnecessary reconfiguration in many cases?
I'm thinking:
- Test A does reconfiguration with custom config
- afterEach does reconfiguration with default config
- Test B does reconfiguration with custom config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test A does reconfiguration with custom config
afterEach does reconfiguration with default config
Test B doesn't do reconfiguration (unaffected by Test A Config)
afterEach doesn't do reconfiguration
Test C doesn't do reconfiguration (unaffected by Test A Config)
afterEach doesn't do reconfiguration
Test D does reconfiguration with custom config
The net reconfiguration is the same. If you are interested I left a counter in the test suite
https://github.com/parse-community/parse-server/runs/2099411665
As you can see it reconfigures 461 times. Which is much better than the 2825 it was before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm getting it. You are assuming that the tests B and C do not need a reconfig, therefore none should be done. And removing these unnecessary reconfigs, was something this PR also does (among other things)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured out how random testing works.
- Randomize the test suites and run them.
- Before a test suite runs randomize the test within them.
Basically randomizing a single test suite can isolate the problem instead of running the entire suite.
I'll try it in a separate PR. Only 40 failing tests to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great discovery! And just to be clear, no tests were removed or disabled in this PR, correct? I noticed re-ordering and re-grouping, but not sure whether I've missed something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is correct.
Edit: I have removed some of the duplicate tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
I don't think we need UserPII in its current form. It seems to be just testing whether a logged out user can access a user object in various ways which are effectively all the same and unnecessary. That doesn't require a distinct test suite IMO, and should be covered already in the login / logout or object access tests. Regarding a "Test Quality Guide" for how to write tests, which rules would you say it should include, given the insight you have now after digging into the tests? (I will open a separate PR for this). |
* initial pass * reconfigureServer when needed * finish postgres tests * mongo tests * more tests * clean up * re-add skipped test * Fix transaction tests * handle batch * AuthenticationAdapter fix * More reconfiguration * clean up * properly terminate cli servers * handle Parse.Push * Flaky PushController * ensure reconfigureServer when changed * fix postgres tests * remove console.log * LiveQuery spec remove duplicates and listeners
🎉 This change has been released in version 5.0.0-beta.1 |
🎉 This change has been released in version 5.0.0 |
New Pull Request Checklist
Issue Description
Closes: #7080
After cleaning up the JS SDK test suite I realized the test suite in this repo could use some TLC.
With the recent addition of Github Action and compatibility testing. We are constantly running into flaky tests. This can be a hinderance for future development. With the test suite growing everyday we should start looking for poorly written tests.
Approach
The goal of this PR is to create a single server at the start of the tests. This means every test will run against the same instance unless a separate instance is created for an individual test. The database is deleted after each test. Since a clean server isn't created before tests we can find tests that relies on it. If a tests relies on that means a test is affected by another test in the same file (that test isn't properly cleaned up) or by another test file (server instances created between files).
beforeAll
allowedThis is a first pass. If you see
await reconfigureServer()
at the start of the test. This may mean there are poorly written tests in the file that require a new server instance to be created. There are a lot of reasons why a test is poorly written. The main reason would be invariants, the state of the test suite should be the same before and after every test.Let me know if you have any questions on the decisions made for any changes to any tests.
TODOs before merging