Fix db test run transient errors (#1074)

* Remove end calls

* Remove `t` param

* Try with db config setup inside before

* Console.log inside test

* Restructure tests

* Increase test timeout to 150 seconds

* Revert changes

* Don't timeout tap tests, rely on CI/CD timeout

* Remove `t.end` calls

* Remove remaining end calls

* Remove unused argument
This commit is contained in:
Aswin V 2023-04-13 03:03:05 +05:30 committed by GitHub
parent e62bd64222
commit a14823938b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 17 additions and 176 deletions

View File

@ -29,7 +29,7 @@
"db:migration:run:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
"db:migration:run:mssql": "cross-env DB_TYPE=mssql DB_URL='sqlserver://localhost:1433;database=master;username=sa;password=123ABabc!' ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run -d typeorm.ts",
"prepublishOnly": "npm run build",
"test": "cross-env BOXYHQ_NO_ANALYTICS=1 tap --ts --timeout=100 --coverage-map=map.js test/**/*.test.ts",
"test": "cross-env BOXYHQ_NO_ANALYTICS=1 tap -T --ts --coverage-map=map.js test/**/*.test.ts",
"sort": "npx sort-package-json"
},
"tap": {
@ -80,4 +80,4 @@
"node": ">=16",
"npm": ">=8"
}
}
}

View File

@ -166,7 +166,6 @@ if (process.env.DYNAMODB_URL) {
}
);
}
tap.before(async () => {
for (const idx in dbs) {
const opts = dbs[idx];
@ -182,17 +181,16 @@ tap.teardown(async () => {
process.exit(0);
});
tap.test('dbs', ({ end }) => {
tap.test('dbs', async () => {
for (const idx in connectionStores) {
const connectionStore = connectionStores[idx];
const ttlStore = ttlStores[idx];
let dbEngine = dbs[idx].engine!;
if (dbs[idx].type) {
dbEngine += ': ' + dbs[idx].type;
}
tap.test('put(): ' + dbEngine, async (t) => {
tap.test('put(): ' + dbEngine, async () => {
await connectionStore.put(
record1.id,
record1,
@ -222,8 +220,6 @@ tap.test('dbs', ({ end }) => {
value: record2.name,
}
);
t.end();
});
tap.test('get(): ' + dbEngine, async (t) => {
@ -232,8 +228,6 @@ tap.test('dbs', ({ end }) => {
t.same(ret1, record1, 'unable to get record1');
t.same(ret2, record2, 'unable to get record2');
t.end();
});
tap.test('getAll(): ' + dbEngine, async (t) => {
@ -282,8 +276,6 @@ tap.test('dbs', ({ end }) => {
1,
"getAll pagination should get only 1 record, order doesn't matter"
);
t.end();
});
tap.test('getByIndex(): ' + dbEngine, async (t) => {
@ -340,8 +332,6 @@ tap.test('dbs', ({ end }) => {
: [ret3.data[0], ret4.data[0]].sort((a, b) => a.id.localeCompare(b.id)),
'getByIndex pagination for index "city" failed'
);
t.end();
});
tap.test('delete(): ' + dbEngine, async (t) => {
@ -373,8 +363,6 @@ tap.test('dbs', ({ end }) => {
t.same(ret3.data, [], 'delete for record1 failed');
t.same(ret4.data, [], 'delete for record2 failed');
t.end();
});
tap.test('ttl indexes: ' + dbEngine, async (t) => {
@ -398,16 +386,12 @@ tap.test('dbs', ({ end }) => {
} catch (err) {
t.ok(err, 'got expected error');
}
t.end();
});
tap.test('ttl put(): ' + dbEngine, async (t) => {
tap.test('ttl put(): ' + dbEngine, async () => {
await ttlStore.put(record1.id, record1);
await ttlStore.put(record2.id, record2);
t.end();
});
tap.test('ttl get(): ' + dbEngine, async (t) => {
@ -416,14 +400,11 @@ tap.test('dbs', ({ end }) => {
t.same(ret1, record1, 'unable to get record1');
t.same(ret2, record2, 'unable to get record2');
t.end();
});
tap.test('ttl expiry: ' + dbEngine, async (t) => {
// mongo runs ttl task every 60 seconds
if (dbEngine.startsWith('mongo')) {
t.end();
return;
}
@ -434,8 +415,6 @@ tap.test('dbs', ({ end }) => {
t.same(ret1, null, 'ttl for record1 failed');
t.same(ret2, null, 'ttl for record2 failed');
t.end();
});
tap.test('deleteMany(): ' + dbEngine, async (t) => {
@ -485,8 +464,6 @@ tap.test('dbs', ({ end }) => {
t.same(ret3.data, []);
t.same(ret4.data, []);
t.end();
});
}
@ -518,9 +495,5 @@ tap.test('dbs', ({ end }) => {
} catch (err) {
t.ok(err, 'got expected error');
}
t.end();
});
end();
});

View File

@ -44,7 +44,7 @@ tap.test('directories.', async (t) => {
});
t.test('create()', async (t) => {
t.test('create a directory with all required params', async (t) => {
t.test('create a directory with all required params', async () => {
const { data: directory } = await directorySync.directories.create(directoryPayload);
tap.ok(directory);
@ -55,11 +55,9 @@ tap.test('directories.', async (t) => {
tap.strictSame(directory?.webhook.endpoint, directoryPayload.webhook_url);
tap.strictSame(directory?.webhook.secret, directoryPayload.webhook_secret);
tap.strictSame(directory?.log_webhook_events, false);
t.end();
});
t.test('generate a name using tenant and product if name is not provided', async (t) => {
t.test('generate a name using tenant and product if name is not provided', async () => {
const { data: directory } = await directorySync.directories.create({
...directoryPayload,
name: undefined,
@ -67,11 +65,9 @@ tap.test('directories.', async (t) => {
tap.ok(directory);
tap.strictSame(directory?.name, `scim-${tenant}-${product}`);
t.end();
});
t.test('use generic-scim-v2 type if type is not provided', async (t) => {
t.test('use generic-scim-v2 type if type is not provided', async () => {
const { data: directory } = await directorySync.directories.create({
...directoryPayload,
type: undefined,
@ -79,11 +75,9 @@ tap.test('directories.', async (t) => {
tap.ok(directory);
tap.strictSame(directory?.type, 'generic-scim-v2');
t.end();
});
t.test('should not be able to create a directory without tenant or product', async (t) => {
t.test('should not be able to create a directory without tenant or product', async () => {
const { data: directory, error } = await directorySync.directories.create({
...directoryPayload,
tenant: '',
@ -94,11 +88,9 @@ tap.test('directories.', async (t) => {
tap.ok(error);
tap.strictSame(error?.code, 400);
tap.strictSame(error?.message, 'Missing required parameters.');
t.end();
});
t.test('should not be able to create a directory with invalid type', async (t) => {
t.test('should not be able to create a directory with invalid type', async () => {
const { data: directory, error } = await directorySync.directories.create({
...directoryPayload,
type: 'invalid-type' as DirectoryType,
@ -108,11 +100,9 @@ tap.test('directories.', async (t) => {
tap.ok(error);
tap.strictSame(error?.code, 400);
tap.strictSame(error?.message, 'Invalid directory type.');
t.end();
});
t.test('create multiple directories for same tenant and product', async (t) => {
t.test('create multiple directories for same tenant and product', async () => {
const { data: directory1 } = await directorySync.directories.create({
...directoryPayload,
name: 'Directory 1',
@ -138,11 +128,7 @@ tap.test('directories.', async (t) => {
tap.ok(directoriesFetched);
tap.strictSame(directoriesFetched?.length, 2);
t.end();
});
t.end();
});
t.test('get()', async (t) => {
@ -165,8 +151,6 @@ tap.test('directories.', async (t) => {
t.ok(directoryFetched);
t.strictSame(directoryFetched, directory);
t.match(directoryFetched?.id, directory.id);
t.end();
});
t.test('should not be able to get a directory that does not exist', async (t) => {
@ -176,8 +160,6 @@ tap.test('directories.', async (t) => {
t.ok(error);
t.strictSame(error?.code, 404);
t.strictSame(error?.message, 'Directory configuration not found.');
t.end();
});
t.test('should not be able to get a directory without an id', async (t) => {
@ -187,11 +169,7 @@ tap.test('directories.', async (t) => {
t.ok(error);
t.strictSame(error?.code, 400);
t.strictSame(error?.message, 'Missing required parameters.');
t.end();
});
t.end();
});
t.test('getByTenantAndProduct()', async (t) => {
@ -217,8 +195,6 @@ tap.test('directories.', async (t) => {
t.ok(directoriesFetched);
t.strictSame(directoriesFetched, [directory]);
t.match(directoriesFetched?.length, 1);
t.end();
});
t.test('should not be able to get a directory that does not exist', async (t) => {
@ -230,11 +206,7 @@ tap.test('directories.', async (t) => {
t.ok(directoriesFetched);
t.notOk(error);
t.strictSame(directoriesFetched?.length, 0);
t.end();
});
t.end();
});
t.test('update()', async (t) => {
@ -284,8 +256,6 @@ tap.test('directories.', async (t) => {
t.same(directoryFetched?.type, toUpdate.type);
t.match(directoryFetched?.webhook.endpoint, toUpdate.webhook?.endpoint);
t.match(directoryFetched?.webhook.secret, toUpdate.webhook?.secret);
t.end();
});
t.test('must provide a directory id', async (t) => {
@ -296,11 +266,7 @@ tap.test('directories.', async (t) => {
t.ok(error);
t.same(error?.code, 400);
t.same(error?.message, 'Missing required parameters.');
t.end();
});
t.end();
});
t.test('delete()', async (t) => {
@ -323,11 +289,7 @@ tap.test('directories.', async (t) => {
const { data: directoryFetched } = await directorySync.directories.get(directory.id);
t.notOk(directoryFetched);
t.end();
});
t.end();
});
t.test('getAll()', async (t) => {
@ -370,9 +332,5 @@ tap.test('directories.', async (t) => {
t.match(directoryFetched2?.deactivated, false);
t.match(isConnectionActive(directoryFetched2!), true);
t.end();
});
t.end();
});

View File

@ -50,8 +50,6 @@ tap.test('Directory groups / ', async (t) => {
t.ok(createdGroup);
t.hasStrict(createdGroup, groups[0]);
t.ok('id' in createdGroup);
t.end();
});
t.test('Should be able to get the group by id', async (t) => {
@ -63,8 +61,6 @@ tap.test('Directory groups / ', async (t) => {
t.equal(status, 200);
t.hasStrict(data, createdGroup);
t.hasStrict(data, groups[0]);
t.end();
});
t.test('Should be able to get the group by displayName', async (t) => {
@ -77,8 +73,6 @@ tap.test('Directory groups / ', async (t) => {
t.hasStrict(data.Resources[0], createdGroup);
t.hasStrict(data.Resources[0], groups[0]);
t.equal(data.Resources.length, 1);
t.end();
});
t.test('Should be able to get all groups', async (t) => {
@ -92,8 +86,6 @@ tap.test('Directory groups / ', async (t) => {
t.hasStrict(data.Resources[0], groups[0]);
t.equal(data.totalResults, 1);
t.equal(data.Resources[0].members.length, 0);
t.end();
});
t.test('Should be able to update the group name', async (t) => {
@ -112,8 +104,6 @@ tap.test('Directory groups / ', async (t) => {
t.ok(data);
t.equal(status, 200);
t.equal(data.displayName, 'Developers Updated');
t.end();
});
t.test('Should be able to delete a group', async (t) => {
@ -135,9 +125,5 @@ tap.test('Directory groups / ', async (t) => {
t.equal(e.statusCode, 404);
t.equal(e.message, `Group with id ${createdGroup.id} not found.`);
}
t.end();
});
t.end();
});

View File

@ -157,6 +157,4 @@ tap.test('Directory groups membership / ', async (t) => {
t.match(await directorySync.groups.isUserInGroup(group.id, user1.id), false);
t.match(await directorySync.groups.isUserInGroup(group.id, user2.id), false);
t.end();
});

View File

@ -55,8 +55,6 @@ tap.test('Directory users / ', async (t) => {
t.equal(status, 200);
t.hasStrict(data.Resources[0], createdUser);
t.hasStrict(data.Resources[0], users[0]);
t.end();
});
t.test('Should be able to get the user by id', async (t) => {
@ -65,8 +63,6 @@ tap.test('Directory users / ', async (t) => {
t.ok(data);
t.equal(status, 200);
t.hasStrict(data, users[0]);
t.end();
});
t.test('Should be able to update the user using PUT request', async (t) => {
@ -94,8 +90,6 @@ tap.test('Directory users / ', async (t) => {
t.ok(user);
t.hasStrict(user, toUpdate);
t.match(user.city, toUpdate.city);
t.end();
});
t.test('Should be able to delete the user using PATCH request', async (t) => {
@ -111,8 +105,6 @@ tap.test('Directory users / ', async (t) => {
t.ok(data);
t.equal(status, 200);
t.hasStrict(data, toUpdate);
t.end();
});
t.test('should be able to update the user with multi-valued properties', async (t) => {
@ -125,8 +117,6 @@ tap.test('Directory users / ', async (t) => {
t.equal(data.active, false);
t.equal(data.name.givenName, 'David');
t.equal(data.name.familyName, 'Jones');
t.end();
});
t.test('Should be able to update the custom user attributes', async (t) => {
@ -138,8 +128,6 @@ tap.test('Directory users / ', async (t) => {
t.equal(status, 200);
t.equal(data.companyName, 'BoxyHQ');
t.equal(data.address.streetAddress, '123 Main St');
t.end();
});
t.test('Should be able to fetch all users', async (t) => {
@ -151,8 +139,6 @@ tap.test('Directory users / ', async (t) => {
t.equal(data.Resources.length, 1);
t.hasStrict(data.Resources[0], users[0]);
t.equal(data.totalResults, 1);
t.end();
});
t.test('Should be able to delete the user', async (t) => {
@ -171,8 +157,6 @@ tap.test('Directory users / ', async (t) => {
t.hasStrict(user.Resources, []);
t.hasStrict(user.totalResults, 0);
t.end();
});
t.test('Should be able to delete all users using deleteAll() method', async (t) => {
@ -184,9 +168,5 @@ tap.test('Directory users / ', async (t) => {
const { data: users } = await directorySync.users.getAll();
t.equal(users?.length, 0);
t.end();
});
t.end();
});

View File

@ -66,8 +66,6 @@ tap.test('Webhook Events / ', async (t) => {
t.test("Should be able to get the directory's webhook", async (t) => {
t.match(directory.webhook.endpoint, webhook.endpoint);
t.match(directory.webhook.secret, webhook.secret);
t.end();
});
t.test('Should not log events if the directory has no webhook', async (t) => {
@ -111,8 +109,6 @@ tap.test('Webhook Events / ', async (t) => {
await directorySync.directories.update(directory.id, {
log_webhook_events: true,
});
t.end();
});
t.test('Should be able to get an event by id', async (t) => {
@ -124,8 +120,6 @@ tap.test('Webhook Events / ', async (t) => {
const log = await directorySync.webhookLogs.get(logs[0].id);
t.equal(log.id, logs[0].id);
t.end();
});
t.test('Should send user related events', async (t) => {
@ -172,8 +166,6 @@ tap.test('Webhook Events / ', async (t) => {
t.hasStrict(logs[2].data.raw, createdUser);
await directorySync.users.deleteAll(directory.id);
t.end();
});
t.test('Should send group related events', async (t) => {
@ -218,8 +210,6 @@ tap.test('Webhook Events / ', async (t) => {
t.match(logs[2].event, 'group.created');
t.match(logs[2].directory_id, directory.id);
t.hasStrict(logs[2].data.raw, createdGroup);
t.end();
});
t.test('Should send group membership related events', async (t) => {
@ -274,8 +264,6 @@ tap.test('Webhook Events / ', async (t) => {
await directorySync.users.delete(createdUser.id);
await directorySync.groups.delete(createdGroup.id);
t.end();
});
t.test('createSignatureString()', async (t) => {
@ -305,9 +293,5 @@ tap.test('Webhook Events / ', async (t) => {
const emptySignatureString = createSignatureString('', event);
t.match(emptySignatureString, '');
t.end();
});
t.end();
});

View File

@ -36,7 +36,7 @@ const assertCalledWith = (spy: sinon.SinonSpy, args: any[]) => {
spy.restore();
};
tap.test('should send sso.created event', async (t) => {
tap.test('should send sso.created event', async () => {
const body = {
...saml_connection,
metadataUrl: 'https://mocksaml.com/api/saml/metadata',
@ -62,11 +62,9 @@ tap.test('should send sso.created event', async (t) => {
clientID: connection.clientID,
clientSecret: connection.clientSecret,
});
t.end();
});
tap.test('should send sso.deactivated event', async (t) => {
tap.test('should send sso.deactivated event', async () => {
const body = {
...saml_connection,
metadataUrl: 'https://mocksaml.com/api/saml/metadata',
@ -109,11 +107,9 @@ tap.test('should send sso.deactivated event', async (t) => {
clientID: connection.clientID,
clientSecret: connection.clientSecret,
});
t.end();
});
tap.test('should send sso.activated event', async (t) => {
tap.test('should send sso.activated event', async () => {
const body = {
...saml_connection,
metadataUrl: 'https://mocksaml.com/api/saml/metadata',
@ -156,11 +152,9 @@ tap.test('should send sso.activated event', async (t) => {
clientID: connection.clientID,
clientSecret: connection.clientSecret,
});
t.end();
});
tap.test('should send sso.deleted event', async (t) => {
tap.test('should send sso.deleted event', async () => {
const body = {
...saml_connection,
metadataUrl: 'https://mocksaml.com/api/saml/metadata',
@ -195,8 +189,6 @@ tap.test('should send sso.deleted event', async (t) => {
assertCalledWith(notifySpy, [eventType, connection]);
assertCalledWith(sendWebhookEventSpy, [jacksonOptions.webhook, payload]);
t.end();
});
tap.test('should send dsync.created event', async (t) => {
@ -223,8 +215,6 @@ tap.test('should send dsync.created event', async (t) => {
assertCalledWith(sendWebhookEventSpy, [jacksonOptions.webhook, payload]);
await directoryConnectionController.delete(connection.id);
t.end();
});
tap.test('should send dsync.deactivated event', async (t) => {
@ -256,8 +246,6 @@ tap.test('should send dsync.deactivated event', async (t) => {
assertCalledWith(sendWebhookEventSpy, [jacksonOptions.webhook, payload]);
await directoryConnectionController.delete(connection.id);
t.end();
});
tap.test('should send dsync.activated event', async (t) => {
@ -289,8 +277,6 @@ tap.test('should send dsync.activated event', async (t) => {
assertCalledWith(sendWebhookEventSpy, [jacksonOptions.webhook, payload]);
await directoryConnectionController.delete(connection.id);
t.end();
});
tap.test('should send dsync.deleted event', async (t) => {
@ -320,6 +306,4 @@ tap.test('should send dsync.deleted event', async (t) => {
assertCalledWith(sendWebhookEventSpy, [jacksonOptions.webhook, payload]);
await directoryConnectionController.delete(connection.id);
t.end();
});

View File

@ -12,7 +12,7 @@ tap.before(async () => {
samlFederatedController = jackson.samlFederatedController;
});
tap.test('Federated SAML App', async (t) => {
tap.test('Federated SAML App', async () => {
const app = await samlFederatedController.app.create({
name: 'Test App',
tenant,
@ -28,8 +28,6 @@ tap.test('Federated SAML App', async (t) => {
t.match(app.product, product);
t.match(app.entityId, serviceProvider.entityId);
t.match(app.acsUrl, serviceProvider.acsUrl);
t.end();
});
tap.test('Should be able to get the SAML Federation app by id', async (t) => {
@ -37,8 +35,6 @@ tap.test('Federated SAML App', async (t) => {
t.ok(response);
t.match(response.id, app.id);
t.end();
});
tap.test('Should be able to get the SAML Federation app by entity id', async (t) => {
@ -46,8 +42,6 @@ tap.test('Federated SAML App', async (t) => {
t.ok(response);
t.match(response.entityId, serviceProvider.entityId);
t.end();
});
tap.test('Should be able to update the SAML Federation app', async (t) => {
@ -65,8 +59,6 @@ tap.test('Federated SAML App', async (t) => {
t.ok(updatedApp);
t.match(updatedApp.name, 'Updated App Name');
t.match(updatedApp.acsUrl, 'https://twilio.com/saml/acsUrl/updated');
t.end();
});
tap.test('Should be able to update the app branding', async (t) => {
@ -87,8 +79,6 @@ tap.test('Federated SAML App', async (t) => {
t.match(updatedApp.logoUrl, 'https://company.com/logo.png');
t.match(updatedApp.faviconUrl, 'https://company.com/favicon.ico');
t.match(updatedApp.primaryColor, '#000000');
t.end();
});
tap.test('Should be able to get all SAML Federation apps', async (t) => {
@ -96,8 +86,6 @@ tap.test('Federated SAML App', async (t) => {
t.ok(response);
t.ok(response.data.length === 1);
t.end();
});
tap.test('Should be able to delete the SAML Federation app', async (t) => {
@ -106,11 +94,7 @@ tap.test('Federated SAML App', async (t) => {
const allApps = await samlFederatedController.app.getAll({});
t.ok(allApps.data.length === 0);
t.end();
});
t.end();
});
tap.teardown(async () => {

View File

@ -51,7 +51,7 @@ tap.before(async () => {
});
});
tap.test('Federated SAML flow', async (t) => {
tap.test('Federated SAML flow', async () => {
const relayStateFromSP = 'sp-saml-request-relay-state';
const requestXML = await fs.readFile(path.join(__dirname, '/data/request.xml'), 'utf8');
@ -78,8 +78,6 @@ tap.test('Federated SAML flow', async (t) => {
t.ok(response.redirectUrl, 'Should have a redirect URL');
t.ok(response.redirectUrl?.includes('SAMLRequest'), 'Should have a SAMLRequest in the redirect URL');
t.ok(response.redirectUrl?.includes('RelayState'), 'Should have a RelayState in the redirect URL');
t.end();
});
tap.test('Should be able to accept SAML Response from IdP and generate SAML Response for SP', async (t) => {
@ -113,11 +111,7 @@ tap.test('Federated SAML flow', async (t) => {
t.match(relayState, relayStateFromSP, 'Should have the same relay state as the one sent by SP');
stubValidate.restore();
t.end();
});
t.end();
});
tap.teardown(async () => {