Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

ab#215600 - Metrics Service Build Issues #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
@@ -1,7 +1,6 @@
.idea/
coverage/
node_modules/
lib/
temp
yarn.lock
*.log
Expand Down
1 change: 1 addition & 0 deletions lib/environment.d.ts
@@ -0,0 +1 @@
export {};
25 changes: 25 additions & 0 deletions lib/environment.js
@@ -0,0 +1,25 @@
"use strict";

var _jestEnvironmentNode = require("jest-environment-node");
/* eslint-disable no-console */

const debug = require('debug')('jest-dynamodb');
module.exports = class DynamoDBEnvironment extends _jestEnvironmentNode.TestEnvironment {
constructor(config, context) {
super(config, context);
}
async setup() {
debug('Setup DynamoDB Test Environment');
await super.setup();
}
async teardown() {
debug('Teardown DynamoDB Test Environment');
await super.teardown();
}

// @ts-ignore
runScript(script) {
// @ts-ignore
return super.runScript(script);
}
};
7 changes: 7 additions & 0 deletions lib/index.d.ts
@@ -0,0 +1,7 @@
export * from './types';
declare const _default: {
globalSetup: string;
globalTeardown: string;
testEnvironment: string;
};
export default _default;
25 changes: 25 additions & 0 deletions lib/index.js
@@ -0,0 +1,25 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
var _exportNames = {};
exports.default = void 0;
var _path = require("path");
var _types = require("./types");
Object.keys(_types).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
if (key in exports && exports[key] === _types[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _types[key];
}
});
});
var _default = exports.default = {
globalSetup: (0, _path.resolve)(__dirname, './setup.js'),
globalTeardown: (0, _path.resolve)(__dirname, './teardown.js'),
testEnvironment: (0, _path.resolve)(__dirname, './environment.js')
};
1 change: 1 addition & 0 deletions lib/setup.d.ts
@@ -0,0 +1 @@
export default function (): Promise<void>;
68 changes: 68 additions & 0 deletions lib/setup.js
@@ -0,0 +1,68 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _dynamodbLocal = _interopRequireDefault(require("dynamodb-local"));
var _clientDynamodb = require("@aws-sdk/client-dynamodb");
var _getConfig = _interopRequireDefault(require("./utils/get-config"));
var _deleteTables = _interopRequireDefault(require("./utils/delete-tables"));
var _waitForLocalhost = _interopRequireDefault(require("./utils/wait-for-localhost"));
var _getRelevantTables = _interopRequireDefault(require("./utils/get-relevant-tables"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const debug = require('debug')('jest-dynamodb');
const DEFAULT_PORT = 8000;
const DEFAULT_HOST = 'localhost';
const DEFAULT_OPTIONS = ['-sharedDb'];
const sleep = time => new Promise(res => setTimeout(res, time));
async function _default() {
const {
tables: newTables,
clientConfig,
installerConfig,
port = DEFAULT_PORT,
hostname = DEFAULT_HOST,
options = DEFAULT_OPTIONS
} = await (0, _getConfig.default)(debug);
const dynamoDB = new _clientDynamodb.DynamoDB({
endpoint: `http://${hostname}:${port}`,
tls: false,
region: 'local-env',
credentials: {
accessKeyId: 'fakeMyKeyId',
secretAccessKey: 'fakeSecretAccessKey'
},
...clientConfig
});
global.__DYNAMODB_CLIENT__ = dynamoDB;
try {
const promises = [dynamoDB.listTables({})];
if (!global.__DYNAMODB__) {
promises.push((0, _waitForLocalhost.default)(port, hostname));
}
const [TablesList] = await Promise.all(promises);
const tableNames = TablesList === null || TablesList === void 0 ? void 0 : TablesList.TableNames;
if (tableNames) {
await (0, _deleteTables.default)(dynamoDB, (0, _getRelevantTables.default)(tableNames, newTables));
}
} catch (err) {
// eslint-disable-next-line no-console
debug(`fallback to launch DB due to ${err}`);
if (installerConfig) {
_dynamodbLocal.default.configureInstaller(installerConfig);
}
if (!global.__DYNAMODB__) {
debug('spinning up a local ddb instance');
global.__DYNAMODB__ = await _dynamodbLocal.default.launch(port, null, options);
debug(`dynamodb-local started on port ${port}`);
await (0, _waitForLocalhost.default)(port, hostname);
}
}
debug(`dynamodb-local is ready on port ${port}`);
await createTables(dynamoDB, newTables);
await sleep(2000);
}
function createTables(dynamoDB, tables) {
return Promise.all(tables.map(table => dynamoDB.createTable(table)));
}
2 changes: 2 additions & 0 deletions lib/teardown.d.ts
@@ -0,0 +1,2 @@
import type { JestArgs } from './types';
export default function (jestArgs: JestArgs): Promise<void>;
33 changes: 33 additions & 0 deletions lib/teardown.js
@@ -0,0 +1,33 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
var _dynamodbLocal = _interopRequireDefault(require("dynamodb-local"));
var _deleteTables = _interopRequireDefault(require("./utils/delete-tables"));
var _getConfig = _interopRequireDefault(require("./utils/get-config"));
var _getRelevantTables = _interopRequireDefault(require("./utils/get-relevant-tables"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const debug = require('debug')('jest-dynamodb');
async function _default(jestArgs) {
// eslint-disable-next-line no-console
debug('Teardown DynamoDB');
if (global.__DYNAMODB__) {
const watching = jestArgs.watch || jestArgs.watchAll;
if (!watching) {
await _dynamodbLocal.default.stopChild(global.__DYNAMODB__);
}
} else {
const dynamoDB = global.__DYNAMODB_CLIENT__;
const {
tables: targetTables
} = await (0, _getConfig.default)(debug);
const {
TableNames: tableNames
} = await dynamoDB.listTables({});
if (tableNames !== null && tableNames !== void 0 && tableNames.length) {
await (0, _deleteTables.default)(dynamoDB, (0, _getRelevantTables.default)(tableNames, targetTables));
}
}
}
84 changes: 84 additions & 0 deletions lib/types.d.ts
@@ -0,0 +1,84 @@
/// <reference types="node" />
import type { DynamoDB } from '@aws-sdk/client-dynamodb';
import type { CreateTableCommandInput } from '@aws-sdk/client-dynamodb';
import type { DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
import type { ChildProcess } from 'child_process';
import type { InstallerConfig } from 'dynamodb-local';
import type { argValues } from 'dynamodb-local';
declare global {
var __DYNAMODB_CLIENT__: DynamoDB;
var __DYNAMODB__: ChildProcess;
}
export type JestArgs = {
bail: number;
changedSince?: string;
changedFilesWithAncestor: boolean;
ci: boolean;
collectCoverage: boolean;
collectCoverageFrom: Array<string>;
collectCoverageOnlyFrom?: {
[key: string]: boolean;
};
coverageDirectory: string;
coveragePathIgnorePatterns?: Array<string>;
coverageProvider: object;
coverageReporters: object;
coverageThreshold?: object;
detectLeaks: boolean;
detectOpenHandles: boolean;
expand: boolean;
filter?: string;
findRelatedTests: boolean;
forceExit: boolean;
json: boolean;
globalSetup?: string;
globalTeardown?: string;
lastCommit: boolean;
logHeapUsage: boolean;
listTests: boolean;
maxConcurrency: number;
maxWorkers: number;
noStackTrace: boolean;
nonFlagArgs: Array<string>;
noSCM?: boolean;
notify: boolean;
notifyMode: object;
outputFile?: string;
onlyChanged: boolean;
onlyFailures: boolean;
passWithNoTests: boolean;
projects: Array<string>;
replname?: string;
reporters?: Array<object>;
runTestsByPath: boolean;
rootDir: string;
shard?: object;
silent?: boolean;
skipFilter: boolean;
snapshotFormat: object;
errorOnDeprecated: boolean;
testFailureExitCode: number;
testNamePattern?: string;
testPathPattern: string;
testResultsProcessor?: string;
testSequencer: string;
testTimeout?: number;
updateSnapshot: object;
useStderr: boolean;
verbose?: boolean;
watch: boolean;
watchAll: boolean;
watchman: boolean;
watchPlugins?: Array<{
path: string;
config: Record<string, unknown>;
}> | null;
};
export type Config = {
tables: CreateTableCommandInput[];
clientConfig?: DynamoDBClientConfig;
installerConfig?: InstallerConfig;
port?: number;
hostname?: string;
options?: argValues[];
};
1 change: 1 addition & 0 deletions lib/types.js
@@ -0,0 +1 @@
"use strict";
2 changes: 2 additions & 0 deletions lib/utils/delete-tables.d.ts
@@ -0,0 +1,2 @@
import type { DynamoDB } from '@aws-sdk/client-dynamodb';
export default function deleteTables(dynamoDB: DynamoDB, tableNames: string[]): Promise<import("@aws-sdk/client-dynamodb").DeleteTableCommandOutput[]>;
11 changes: 11 additions & 0 deletions lib/utils/delete-tables.js
@@ -0,0 +1,11 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = deleteTables;
function deleteTables(dynamoDB, tableNames) {
return Promise.all(tableNames.map(tableName => dynamoDB.deleteTable({
TableName: tableName
})));
}
2 changes: 2 additions & 0 deletions lib/utils/get-config.d.ts
@@ -0,0 +1,2 @@
import type { Config } from '../types';
export default function getConfig(debug: any): Promise<Config>;
15 changes: 15 additions & 0 deletions lib/utils/get-config.js
@@ -0,0 +1,15 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getConfig;
var _path = require("path");
var _cwd = _interopRequireDefault(require("cwd"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
async function getConfig(debug) {
const path = process.env.JEST_DYNAMODB_CONFIG || (0, _path.resolve)((0, _cwd.default)(), 'jest-dynamodb-config.js');
const config = require(path);
debug('config:', config);
return typeof config === 'function' ? await config() : config;
}
2 changes: 2 additions & 0 deletions lib/utils/get-relevant-tables.d.ts
@@ -0,0 +1,2 @@
import type { CreateTableCommandInput } from '@aws-sdk/client-dynamodb';
export default function getRelevantTables(dbTables: string[], configTables: CreateTableCommandInput[]): string[];
10 changes: 10 additions & 0 deletions lib/utils/get-relevant-tables.js
@@ -0,0 +1,10 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getRelevantTables;
function getRelevantTables(dbTables, configTables) {
const configTableNames = configTables.map(configTable => configTable.TableName);
return dbTables.filter(dbTable => configTableNames.includes(dbTable));
}
1 change: 1 addition & 0 deletions lib/utils/wait-for-localhost.d.ts
@@ -0,0 +1 @@
export default function waitForLocalhost(port: number, host: string): Promise<void>;
34 changes: 34 additions & 0 deletions lib/utils/wait-for-localhost.js
@@ -0,0 +1,34 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = waitForLocalhost;
//
// This is copied from https://github.com/sindresorhus/wait-for-localhost/blob/v3.3.0/index.js
// With 1 change
// We rely on status code 400 instead of 200 to ensure local DDB is up and running
//

const http = require('http');
function waitForLocalhost(port, host) {
return new Promise(resolve => {
const retry = () => setTimeout(main, 200);
const main = () => {
const request = http.request({
method: 'GET',
port,
host,
path: '/'
}, response => {
if (response.statusCode === 400) {
return resolve();
}
retry();
});
request.on('error', retry);
request.end();
};
main();
});
}
3 changes: 3 additions & 0 deletions src/setup.ts
Expand Up @@ -14,6 +14,8 @@ const DEFAULT_PORT = 8000;
const DEFAULT_HOST = 'localhost';
const DEFAULT_OPTIONS: argValues[] = ['-sharedDb'];

const sleep = (time: number) => new Promise(res => setTimeout(res, time))

export default async function () {
const {
tables: newTables,
Expand Down Expand Up @@ -72,6 +74,7 @@ export default async function () {
debug(`dynamodb-local is ready on port ${port}`);

await createTables(dynamoDB, newTables);
await sleep(2000);
}

function createTables(dynamoDB: DynamoDB, tables: CreateTableCommandInput[]) {
Expand Down