-
Notifications
You must be signed in to change notification settings - Fork 938
Add code for managing emulators and running database/firestore emulator tests via yarn commands. #1435
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
Can you provide a brief comment explaining how the excluded tests are failing? Some of these failures would be new to me. |
owner: { name: 'Sebastian' }, | ||
'is.admin': true | ||
}; | ||
(!persistence && USE_EMULATOR ? it.skip : 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.
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 does persistence
come into play here? Also:
- Please add comments (ideally in the form of something like "TODO(b/...): Disabled because emulator currently ..."
- I don't trust my operator precedence assumptions, so if possible I'd throw some extra parents around
(!persistence && USE_EMULATOR)
.
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.
It is because that these tests failed only when persistence is false. I have categorized all the failure symptoms/messages in this doc. I can add some comments in code, but I'm not sure whether these failures are due to the sdk test itself or the emulator.
There is also a sample travis run that shows these failures (break down to each test 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.
Hrm, I see. I think before moving forward we should try to understand all the failures. If there are things we know are expected to fail with the emulator right now, great, we can exclude them (if you do know of any specific expected issues right now, maybe mark them in the doc?). But I think it's probably worth spending some time investigating the rest. I may be able to take a look later this week. Else it'll be January.
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 have tried to debug some failures, but couldn't tell whether it is because of the emulator itself, or we are calling the emulator in a wrong way, or there's more setup for the emulator that needs to be done before any test. I'll add more information I found in the doc.
So for this PR, do you think if it makes sense if I
- remove code for 1) excluding any tests, 2) including firestore emulator test on Travis;
- keep code for 1) starting/stoping emulators (a bit of refactoring), 2) yarn command to run database/firestore test with their emulators.
I want to have some partial result completed before the quarter ends, and it's probably easier for you to help debug failures this 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.
Sure, that sounds great.
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.
Here is the doc summarizing the failures, which are excluded in this pr. I'm not sure whether these failures are due to sdk test itself or emulator. I wonder if this is the best way to blacklist failures. Or maybe I should create a hot list, so that we can track each failure separately? |
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.
+1 to understanding why all these tests need to be disabled...
owner: { name: 'Sebastian' }, | ||
'is.admin': true | ||
}; | ||
(!persistence && USE_EMULATOR ? it.skip : 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.
Why does persistence
come into play here? Also:
- Please add comments (ideally in the form of something like "TODO(b/...): Disabled because emulator currently ..."
- I don't trust my operator precedence assumptions, so if possible I'd throw some extra parents around
(!persistence && USE_EMULATOR)
.
4c0cf0e
to
89e6203
Compare
d2b9268
to
2e8047d
Compare
Add yarn commands for running database/firestore tests with their emulators.
2e8047d
to
df00b9f
Compare
export const DEFAULT_SETTINGS = getDefaultSettings(); | ||
console.info(`Default Settings: ${JSON.stringify(DEFAULT_SETTINGS)}`); |
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 see from tslint config that we don't want console.log
. Do we allow console.info
?
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 prevent console.log / console.info because: 1) In the SDK, all logging should go through our official logging mechanism, 2) often developers accidentally leave debug console log statements in their PRs and this makes sure they don't get checked in.
So it's okay to use console logging in tests as long as it's used sparingly and it's intentional.
So in this case, I would just add a tslint suppression comment above it:
// tslint:disable-next-line:ban
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.
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.
Basically LGTM with a few nits.
|
||
constructor(port: number, namespace: string) { | ||
this.port = port; | ||
this.namespace = namespace; |
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.
namespace isn't used in this base class, and I think it only makes sense for database, so it should probably live in DatabaseEmulator.
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.
|
||
import { FirestoreEmulator } from './emulators/firestore-emulator'; | ||
|
||
async function runTest(port: number, namespace: string): Promise<any> { |
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.
namespace is really a database-only term. This should just be projectId.
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.
'https://storage.googleapis.com/firebase-preview-drop/emulator/firebase-database-emulator-v3.5.0.jar'; | ||
} | ||
|
||
async setPublicRules(): Promise<number> { |
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.
(possibly a question for @ryanpbrewster) Why don't we have similar rules for Firestore? Do the emulators have different default behavior for rules? Is that intentional?
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.
They do have different behavior, though not for any particularly principled reason. I'm considering having the RTDB emulator start open-by-default.
|
||
async setUp(): Promise<void> { | ||
return new Promise<void>((resolve, reject) => { | ||
const promise: any = spawn( |
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.
Generally speaking, any is not allowed. Since typing is not available for child-process-promise
, you can define the typing yourself as
interface ChildProcessPromise extends Promise<void> {
childProcess: number;
}
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.
}); | ||
} | ||
|
||
async tearDown(): Promise<void> { |
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.
async is not needed.
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.
this.projectId = projectId; | ||
this.binaryName = 'firestore-emulator.jar'; | ||
this.binaryUrl = | ||
'https://storage.googleapis.com/firebase-preview-drop/emulator/cloud-firestore-emulator-v1.2.1.jar'; |
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 a little concerned about the hard coded url. If we forgot to update the version, we will eventually become using an out dated emulator binary. @ryanpbrewster Is there any way to always get the latest binary?
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.
There was some discussion before on specifying emulator versions.
The conclusion seemed to be that it's probably better to have a locked version and update the version manually, than to always get the latest version and have risk that test may fail surprisingly with the new version.
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. That sounds fine to me. Can you please add a comment about it and include a pointer to where the latest emulator can be found?
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.
|
||
import { DatabaseEmulator } from './emulators/database-emulator'; | ||
|
||
async function runTest(port: number, namespace: string): Promise<any> { |
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.
async is not needed.
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.
'https://storage.googleapis.com/firebase-preview-drop/emulator/firebase-database-emulator-v3.5.0.jar'; | ||
} | ||
|
||
async setPublicRules(): Promise<number> { |
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.
async is not needed.
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.
this.port = port; | ||
} | ||
|
||
async download(): Promise<void> { |
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.
async is not needed.
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.
}); | ||
} | ||
|
||
async setUp(): Promise<void> { |
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.
async is not needed.
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.
|
||
import { FirestoreEmulator } from './emulators/firestore-emulator'; | ||
|
||
async function runTest(port: number, projectId: string): Promise<any> { |
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.
async is not needed.
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.
d7ffc77
to
8cc5e62
Compare
Refactor emulators managing code.
Exclude failing cases from firestore emulator tests.