Skip to content

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

Merged
merged 5 commits into from
Dec 20, 2018

Conversation

yifanyang
Copy link
Contributor

Refactor emulators managing code.

Exclude failing cases from firestore emulator tests.

@ryanpbrewster
Copy link
Contributor

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)(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

(!persistence && USE_EMULATOR ? it.skip : it) is a bit cumbersome, but it seems to be the way we exclude tests currently like here or here. I wonder if we want to have some customized runner, like what we have for firestore unit test here.

Copy link
Contributor

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:

  1. Please add comments (ideally in the form of something like "TODO(b/...): Disabled because emulator currently ..."
  2. I don't trust my operator precedence assumptions, so if possible I'd throw some extra parents around (!persistence && USE_EMULATOR).

Copy link
Contributor Author

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).

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, that sounds great.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@yifanyang
Copy link
Contributor Author

yifanyang commented Dec 19, 2018

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?

Copy link
Contributor

@mikelehen mikelehen left a 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)(
Copy link
Contributor

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:

  1. Please add comments (ideally in the form of something like "TODO(b/...): Disabled because emulator currently ..."
  2. I don't trust my operator precedence assumptions, so if possible I'd throw some extra parents around (!persistence && USE_EMULATOR).

@yifanyang yifanyang force-pushed the yifany-firestore-emulator-test branch from 4c0cf0e to 89e6203 Compare December 20, 2018 02:25
@yifanyang yifanyang changed the title Include firestore emulator tests in Travis. Add code for managing emulators and running database/firestore emulator tests via yarn commands. Dec 20, 2018
@yifanyang yifanyang force-pushed the yifany-firestore-emulator-test branch 3 times, most recently from d2b9268 to 2e8047d Compare December 20, 2018 03:18
Add yarn commands for running database/firestore tests with their emulators.
@yifanyang yifanyang force-pushed the yifany-firestore-emulator-test branch from 2e8047d to df00b9f Compare December 20, 2018 03:22
export const DEFAULT_SETTINGS = getDefaultSettings();
console.info(`Default Settings: ${JSON.stringify(DEFAULT_SETTINGS)}`);
Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

@mikelehen mikelehen left a 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;
Copy link
Contributor

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.

Copy link
Contributor Author

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> {
Copy link
Contributor

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.

Copy link
Contributor Author

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> {
Copy link
Contributor

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?

Copy link
Contributor

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.

@mikelehen mikelehen removed their assignment Dec 20, 2018

async setUp(): Promise<void> {
return new Promise<void>((resolve, reject) => {
const promise: any = spawn(
Copy link
Member

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;
}

Copy link
Contributor Author

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> {
Copy link
Member

Choose a reason for hiding this comment

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

async is not needed.

Copy link
Contributor Author

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';
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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?

Copy link
Contributor Author

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> {
Copy link
Member

Choose a reason for hiding this comment

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

async is not needed.

Copy link
Contributor Author

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> {
Copy link
Member

Choose a reason for hiding this comment

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

async is not needed.

Copy link
Contributor Author

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> {
Copy link
Member

Choose a reason for hiding this comment

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

async is not needed.

Copy link
Contributor Author

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> {
Copy link
Member

Choose a reason for hiding this comment

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

async is not needed.

Copy link
Contributor Author

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> {
Copy link
Member

Choose a reason for hiding this comment

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

async is not needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@yifanyang yifanyang force-pushed the yifany-firestore-emulator-test branch from d7ffc77 to 8cc5e62 Compare December 20, 2018 20:21
@yifanyang yifanyang merged commit 54df997 into master Dec 20, 2018
@yifanyang yifanyang deleted the yifany-firestore-emulator-test branch December 20, 2018 23:00
@firebase firebase locked and limited conversation to collaborators Oct 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants