-
Notifications
You must be signed in to change notification settings - Fork 289
Porting the legacy integration test suite #2
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
Conversation
* Reformatted all source files * Separated unit and integration tests * Added maven checkstyle plugin * Got the basic build and unit tests working * Scrubbed the codebase for private keys, certificates etc.
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.
This is too big to actually review in detail, but I tried to spot-check it (especially the utils and stuff) and overall it looks good and clearly gets us into a much better state. Thanks for tackling! I left a few questions / comments.
fail("Found error on run loop"); | ||
} | ||
} | ||
} |
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.
Can you explain why this code is going away? Have you verified that an exception on the test event target still causes tests to fail and the error to be reported nicely?
I honestly don't remember the full context, but I assume if you e.g. added a snapshot listener and the listener implementation threw an exception (e.g. because a test assertion failed), it wasn't being reliably reported in a friendly way.
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.
This method works with a set of made up contexts and a TestEventTarget. The new integration tests uses the actual database context and the actual ThreadPoolEventTarget, and therefore this method will not work for us anymore. Also we were calling this method from tearDown events, which is kind of broken.
However, I do understand the point you're making about assertions checked in async event handlers. I've fixed a bunch of them so that the assertions are checked outside the event handlers in a blocking manner. However, I'm pretty sure there are plenty left to fix, which I will get around to eventually. The good news is however, whenever an async event handler encounters a failed assertion it throws an exception, which Maven logs to the console. I don't see any of those in the test output.
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.
Hrm... Are you saying that right now, asynchronous test failures log an exception instead of fail the test? And the plan going forward is to rewrite them to not do asynchronous assertions? I'm not sure I'm a fan of that... It seems like a lot of work and easy to forget / miss cases. What was the motivation for undoing the existing approach?
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.
We shouldn't be running assertions in tearDown methods. This can lead to test environment not getting cleaned up properly. Also this requires using a non-default RunLoop implementation that keeps track of errors. I'm not sure if that's a good idea, since we will not be testing the actual run loop that a typical users get.
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.
Let me also try to figure out how often we do async assertions.
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.
Ok, we do this kind of thing often enough, so we should implement some way to check for async errors. But this requires messing with both RunLoop and EventTarget. Specifically we need to modify them during tests to catch errors. This is going to require some work, and so I'd rather do them later.
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.
Okay. Just keep in mind that means many test failures may not fail travis / whatever we're using for CI and thus may not be caught until later (if/when somebody happens to notice the log messages I guess). Given we're not making a lot of changes, this is probably okay. But if we start doing nontrivial development or start receiving pull requests from the community, this debt could easily bite us.
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.
Noted. I've been experimenting with some changes, and I think I have a way to fix this properly. I will send a PR with the fix soon, once the open sourcing stuff is sufficiently under control. Thanks Michael for pointing this problem out.
FirebaseApp.initializeApp( | ||
new FirebaseOptions.Builder() | ||
.setCredential(FirebaseCredentials.fromCertificate(ServiceAccount.EDITOR.asStream())) | ||
.setDatabaseUrl("http://tests.fblocal.com:9000") |
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.
Don't we want to point this elsewhere?
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.
This is now only used in unit tests (DataSnapshotTest, DefaultPersistenceManagetTest etc.). So it doesn't matter where it points to.
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.
To be consistent, I've changed this to admin-java-sdk.firebaseio.com
TestRunLoop runLoop = new TestRunLoop(); | ||
DatabaseConfig config = new DatabaseConfig(); | ||
config.setLogLevel(Logger.Level.DEBUG); | ||
config.setLogLevel(Logger.Level.WARN); |
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'm curious why you're changing this. It's probably fine, but the logs are often useful for debugging test failures.
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.
The debug logs clutter up the test output. Ideally we should use a proper logging framework like JUL or SLF4J, so that the user/developer can control the log level (for both released code, and tests) externally. I'm planning to do this in the future. But for now I'd prefer to have a simple and less verbose test output as the default.
import java.net.URI; | ||
import org.junit.Test; | ||
|
||
public class RepoInfoTest { | ||
|
||
@Test | ||
public void getConnectionURLTestOverloadWorks() { | ||
final String repo = "tests"; | ||
final String server = "fblocal.com:9000"; |
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 guess maybe this is okay because we're not actually starting a connection, but I think we should remove as many references to fblocal.com as possible. This is a legacy hack we used for testing against a local Firebase instance, and more problematically, fblocal.com is a real domain name and we do not own it. :-/
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.
We could probably switch to fb.local or something instead if we have references we want to keep.
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.
Changed to admin-java-sdk.firebaseio.com
info.internalHost = info.host; | ||
info.secure = false; | ||
info.namespace = TestConstants.TEST_REPO; | ||
info.namespace = repo; | ||
URI url = info.getConnectionURL(null); | ||
assertEquals("ws://tests.fblocal.com:9000/.ws?ns=tests&v=5", url.toString()); |
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.
And this?
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.
Changed to firebaseio.com URL
@@ -47,15 +46,13 @@ public void startListening( | |||
ListenHashProvider hash, | |||
SyncTree.CompletionListener onListenComplete) { | |||
Path path = query.getPath(); | |||
logger.debug("Listening at " + path + " for Tag " + tag + ")"); |
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.
why remove all this logging?
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.
This was also to prevent the default test output from getting cluttered up. But I've added it back with log level set to WARN, so it won't be as verbose. We can fix it better once the logging stuff is implemented properly.
import org.junit.BeforeClass; | ||
import org.junit.Test; | ||
|
||
public class KeepSyncedTestIT { |
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.
What is IT?
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.
Stands for Integration Test. Maven surefire and failsafe plugins use this naming convention to differentiate between unit tests and integration tests. I will document this in my next pull request.
I've added some of the logging code back, and dropped all references to fblocal domain. |
import java.net.URI; | ||
import org.junit.Test; | ||
|
||
public class RepoInfoTest { | ||
|
||
@Test | ||
public void getConnectionURLTestOverloadWorks() { | ||
final String repo = "tests"; | ||
final String server = "admin-java-sdk.firebaseio.com:9000"; |
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.
Get rid of the port in all three places in this file.
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.
Done
Thanks for the changes. LGTM. |
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. Thanks Hiranya!
This PR ports the legacy integration test suite (most of it) to run against Firebase production. This requires a Firebase project. Create a project in Firebase console, and download the service account key file. Then run the test suite as:
mvn verify -Dfirebase.it.certificate=[path/to/serviceAccountKey.json] -Dfirebase.it.url=[DB URL]
The IntegrationTestUtils class handles reading the service account key, and making it available to all integration tests.
This PR also cleans up the test sources. In particular:
There's a lot more that can be done to fix and improve the integration test suite, but I feel this is a great starting point since we didn't have a working test suite for a while (and definitely not one that runs against Firebase prod). I will send in more improvements in future PRs.