Skip to content

Refactor Firestore tests to use targetBackend parameter #6999

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 14 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@
"--exit"
],
"env": {
"FIRESTORE_EMULATOR_PORT" : "8080",
"FIRESTORE_EMULATOR_PROJECT_ID" : "test-emulator"
"FIRESTORE_TARGET_BACKEND" : "emulator",
},
"sourceMaps": true,
"protocol": "inspector"
Expand All @@ -95,8 +94,7 @@
],
"env": {
"USE_MOCK_PERSISTENCE": "YES",
"FIRESTORE_EMULATOR_PORT" : "8080",
"FIRESTORE_EMULATOR_PROJECT_ID" : "test-emulator"
"FIRESTORE_TARGET_BACKEND" : "emulator",
},
"sourceMaps": true,
"protocol": "inspector"
Expand Down
40 changes: 16 additions & 24 deletions packages/firestore-compat/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ const karmaBase = require('../../config/karma.base');
const { argv } = require('yargs');

module.exports = function (config) {
const karmaConfig = Object.assign({}, karmaBase, {
const karmaConfig = {
...karmaBase,

// files to load into karma
files: getTestFiles(argv),

Expand All @@ -29,12 +31,20 @@ module.exports = function (config) {

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
frameworks: ['mocha']
};

client: Object.assign({}, karmaBase.client, {
firestoreSettings: getFirestoreSettings(argv)
})
});
if (argv.targetBackend) {
karmaConfig.client = {
...karmaConfig.client,
targetBackend: argv.targetBackend
};
} else if (argv.local) {
karmaConfig.client = {
...karmaConfig.client,
targetBackend: 'emulator'
};
}

config.set(karmaConfig);
};
Expand All @@ -48,22 +58,4 @@ function getTestFiles(argv) {
return [integrationTests];
}

/**
* If the --local argument is passed, returns a {host, ssl} FirestoreSettings
* object that point to localhost instead of production.
*/
function getFirestoreSettings(argv) {
if (argv.local) {
return {
host: 'localhost:8080',
ssl: false
};
} else {
return {
host: 'firestore.googleapis.com',
ssl: true
};
}
}

module.exports.files = getTestFiles(argv);
79 changes: 59 additions & 20 deletions packages/firestore-compat/test/util/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
* limitations under the License.
*/

import * as firestore from '@firebase/firestore-types';

/**
* NOTE: These helpers are used by api/ tests and therefore may not have any
* dependencies on src/ files.
Expand All @@ -25,38 +23,79 @@ import * as firestore from '@firebase/firestore-types';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare const __karma__: any;

enum TargetBackend {
EMULATOR = 'emulator',
QA = 'qa',
NIGHTLY = 'nightly',
PROD = 'prod'
}

// eslint-disable-next-line @typescript-eslint/no-require-imports
const PROJECT_CONFIG = require('../../../../config/project.json');

const EMULATOR_PORT = process.env.FIRESTORE_EMULATOR_PORT;
const EMULATOR_PROJECT_ID = process.env.FIRESTORE_EMULATOR_PROJECT_ID;
export const USE_EMULATOR = !!EMULATOR_PORT;
const TARGET_BACKEND: TargetBackend = getTargetBackend();

const EMULATOR_FIRESTORE_SETTING = {
host: `localhost:${EMULATOR_PORT}`,
ssl: false
};
export const USE_EMULATOR: boolean = TARGET_BACKEND === TargetBackend.EMULATOR;

const PROD_FIRESTORE_SETTING = {
host: 'firestore.googleapis.com',
ssl: true
export const DEFAULT_SETTINGS = {
host: getFirestoreHost(TARGET_BACKEND),
ssl: getSslEnabled(TARGET_BACKEND)
};

export const DEFAULT_SETTINGS = getDefaultSettings();

// eslint-disable-next-line no-console
console.log(`Default Settings: ${JSON.stringify(DEFAULT_SETTINGS)}`);

function getDefaultSettings(): firestore.Settings {
function parseTargetBackend(targetBackend: string): TargetBackend {
switch (targetBackend) {
case 'emulator':
return TargetBackend.EMULATOR;
case 'qa':
return TargetBackend.QA;
case 'nightly':
return TargetBackend.NIGHTLY;
case 'prod':
return TargetBackend.PROD;
default:
throw Error('Unknown backend configuration used for integration tests.');
}
}

function getTargetBackend(): TargetBackend {
const karma = typeof __karma__ !== 'undefined' ? __karma__ : undefined;
if (karma && karma.config.firestoreSettings) {
return karma.config.firestoreSettings;
} else {
return USE_EMULATOR ? EMULATOR_FIRESTORE_SETTING : PROD_FIRESTORE_SETTING;
if (karma && karma.config.targetBackend) {
return parseTargetBackend(karma.config.targetBackend);
}
if (process.env.FIRESTORE_TARGET_BACKEND) {
return parseTargetBackend(process.env.FIRESTORE_TARGET_BACKEND);
}
if (process.env.FIRESTORE_EMULATOR_PORT) {
return TargetBackend.EMULATOR;
}
return TargetBackend.PROD;
}

function getFirestoreHost(targetBackend: TargetBackend): string {
switch (targetBackend) {
case TargetBackend.EMULATOR: {
const emulatorPort: string =
process.env.FIRESTORE_EMULATOR_PORT || '8080';
return `localhost:${emulatorPort}`;
}
case TargetBackend.QA:
return 'staging-firestore.sandbox.googleapis.com';
case TargetBackend.NIGHTLY:
return 'test-firestore.sandbox.googleapis.com';
case TargetBackend.PROD:
default:
return 'firestore.googleapis.com';
}
}

function getSslEnabled(targetBackend: TargetBackend): boolean {
return targetBackend !== TargetBackend.EMULATOR;
}

export const DEFAULT_PROJECT_ID = USE_EMULATOR
? EMULATOR_PROJECT_ID
? process.env.FIRESTORE_EMULATOR_PROJECT_ID || 'test-emulator'
: PROJECT_CONFIG.projectId;
export const ALT_PROJECT_ID = 'test-db2';
2 changes: 1 addition & 1 deletion packages/firestore/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ yarn test:browser --integration

# Run browser integration tests against a Firestore server running on
# localhost:8080.
yarn test:browser --integration --local
yarn test:browser:emulator --integration

# Run all node tests once (unit and integration) against the emulator.
yarn test:node
Expand Down
39 changes: 15 additions & 24 deletions packages/firestore/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const karmaBase = require('../../config/karma.base');
const { argv } = require('yargs');

module.exports = function (config) {
const karmaConfig = Object.assign({}, karmaBase, {
const karmaConfig = {
...karmaBase,
browsers: getTestBrowsers(argv),
// files to load into karma
files: getTestFiles(argv),
Expand All @@ -30,12 +31,20 @@ module.exports = function (config) {

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
frameworks: ['mocha']
};

client: Object.assign({}, karmaBase.client, {
firestoreSettings: getFirestoreSettings(argv)
})
});
if (argv.targetBackend) {
karmaConfig.client = {
...karmaConfig.client,
targetBackend: argv.targetBackend
};
} else if (argv.local) {
karmaConfig.client = {
...karmaConfig.client,
targetBackend: 'emulator'
};
}

config.set(karmaConfig);
};
Expand Down Expand Up @@ -68,22 +77,4 @@ function getTestBrowsers(argv) {
return browsers;
}

/**
* If the --local argument is passed, returns a {host, ssl} FirestoreSettings
* object that point to localhost instead of production.
*/
function getFirestoreSettings(argv) {
if (argv.local) {
return {
host: 'localhost:8080',
ssl: false
};
} else {
return {
host: 'firestore.googleapis.com',
ssl: true
};
}
}

module.exports.files = getTestFiles(argv);
16 changes: 8 additions & 8 deletions packages/firestore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@
"lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
"lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
"prettier": "prettier --write '*.js' '@(lite|src|test)/**/*.ts'",
"test:lite": "node ./scripts/run-tests.js --emulator --platform node_lite --main=lite/index.ts 'test/lite/**/*.test.ts'",
"test:lite:prod": "node ./scripts/run-tests.js --platform node_lite --main=lite/index.ts 'test/lite/**/*.test.ts'",
"test:lite": "ts-node ./scripts/run-tests.ts --emulator --platform node_lite --main=lite/index.ts 'test/lite/**/*.test.ts'",
"test:lite:prod": "ts-node ./scripts/run-tests.ts --platform node_lite --main=lite/index.ts 'test/lite/**/*.test.ts'",
"test:lite:browser": "karma start --single-run --lite",
"test:lite:browser:debug": "karma start --browsers=Chrome --lite --auto-watch",
"test": "run-s lint test:all",
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:all:ci",
"test:all:ci": "run-p test:browser test:lite:browser test:travis",
"test:all": "run-p test:browser test:lite:browser test:travis test:minified",
"test:browser": "karma start --single-run",
"test:browser:emulator:debug": "karma start --browsers=Chrome --local",
"test:browser:emulator": "karma start --single-run --local",
"test:browser:emulator:debug": "karma start --browsers=Chrome --targetBackend=emulator",
"test:browser:emulator": "karma start --single-run --targetBackend=emulator",
"test:browser:unit": "karma start --single-run --unit",
"test:browser:debug": "karma start --browsers=Chrome --auto-watch",
"test:node": "node ./scripts/run-tests.js --main=test/register.ts --emulator 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node:prod": "node ./scripts/run-tests.js --main=test/register.ts 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node:persistence": "node ./scripts/run-tests.js --main=test/register.ts --persistence --emulator 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node:persistence:prod": "node ./scripts/run-tests.js --main=test/register.ts --persistence 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node": "ts-node ./scripts/run-tests.ts --main=test/register.ts --emulator 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node:prod": "ts-node ./scripts/run-tests.ts --main=test/register.ts 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node:persistence": "ts-node ./scripts/run-tests.ts --main=test/register.ts --persistence --emulator 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:node:persistence:prod": "ts-node ./scripts/run-tests.ts --main=test/register.ts --persistence 'test/{,!(browser|lite)/**/}*.test.ts'",
"test:travis": "ts-node --compiler-options='{\"module\":\"commonjs\"}' ../../scripts/emulator-testing/firestore-test-runner.ts",
"test:minified": "(cd ../../integration/firestore ; yarn test)",
"api-report:main": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' ts-node ../../repo-scripts/prune-dts/extract-public-api.ts --package firestore --packageRoot . --typescriptDts ./dist/firestore/src/index.d.ts --rollupDts ./dist/private.d.ts --untrimmedRollupDts ./dist/internal.d.ts --publicDts ./dist/index.d.ts",
Expand Down
17 changes: 0 additions & 17 deletions packages/firestore/scripts/run-tests.js

This file was deleted.

3 changes: 1 addition & 2 deletions packages/firestore/scripts/run-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ let args = [
];

if (argv.emulator) {
process.env.FIRESTORE_EMULATOR_PORT = '8080';
process.env.FIRESTORE_EMULATOR_PROJECT_ID = 'test-emulator';
process.env.FIRESTORE_TARGET_BACKEND = 'emulator';
}

if (argv.persistence) {
Expand Down
19 changes: 16 additions & 3 deletions packages/firestore/test/integration/browser/webchannel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { expect } from 'chai';
import { WebChannelConnection } from '../../../src/platform/browser/webchannel_connection';
import * as api from '../../../src/protos/firestore_proto_api';
import { getDefaultDatabaseInfo } from '../util/internal_helpers';
import { DEFAULT_PROJECT_ID } from '../util/settings';
import { DEFAULT_PROJECT_ID, USE_EMULATOR } from '../util/settings';

/* eslint-disable no-restricted-globals */

Expand All @@ -33,7 +33,13 @@ const describeFn =
xdescribe;

describeFn('WebChannel', () => {
it('receives error messages', done => {
// Test does not run on Emulator because emulator does not impose restriction
// on project id. This is likely because emulator does not require creation
// of project or database before using it. However, it might wrong for
// emulator to allow sharing the same stream across different projects and
// databases.
// eslint-disable-next-line no-restricted-properties
(USE_EMULATOR ? it.skip : it)('receives error messages', done => {
const projectId = DEFAULT_PROJECT_ID;
const info = getDefaultDatabaseInfo();
const conn = new WebChannelConnection(info);
Expand Down Expand Up @@ -64,9 +70,16 @@ describeFn('WebChannel', () => {

// Wait until we receive data, then send a bad "addTarget" request, causing
// the stream to be closed with an error. In this case, bad means having a
// different database ID.
// different project id.
stream.onMessage(msg => {
if (msg.targetChange) {
// Assertion will fail when additional targets are added. This works so
// long as backend target id counts up from 1. We expect the second
// target to be a bad payload. If this does not fail stream, then we
// might receive message that it was successfully added. The following
// assertion will catch failure to validate data on backend.
expect(msg.targetChange?.targetIds).to.not.include(2);

payload.database = 'projects/some-other-project-id/databases/(default)';
didSendBadPayload = true;
stream.send(payload);
Expand Down
Loading