Skip to content

Commit

Permalink
Update async / await for jest according docs
Browse files Browse the repository at this point in the history
- Update async tests according to  https://jestjs.io/docs/tutorial-async and align several tests
- Add dependency for sorting imports
- Add rules for sorting to prettier
- Update prefered VSCode plugins
- Add exceeption for sonar lint
  • Loading branch information
npalm committed Jan 12, 2022
1 parent 9b63aac commit 6bd3f4c
Show file tree
Hide file tree
Showing 20 changed files with 1,235 additions and 1,143 deletions.
5 changes: 3 additions & 2 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
"editorconfig.editorconfig",
"yzhang.markdown-all-in-one",
"mauve.terraform"
"sonarsource.sonarlint-vscode",
"hashicorp.terraform"
]
}
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"sonarlint.rules": {
"javascript:S4123": {
"level": "off"
}
}
}
8 changes: 7 additions & 1 deletion modules/runners/lambdas/runners/.prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@
"singleQuote": true,
"trailingComma": "all",
"semi": true,
}
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"importOrder": [
"<THIRD_PARTY_MODULES>",
"^[./]"
]
}
2 changes: 2 additions & 0 deletions modules/runners/lambdas/runners/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"all": "yarn build && yarn format && yarn lint && yarn test"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^3.1.1",
"@types/aws-lambda": "^8.10.89",
"@types/express": "^4.17.11",
"@types/jest": "^27.4.0",
Expand All @@ -25,6 +26,7 @@
"eslint": "^7.32.0",
"eslint-plugin-prettier": "4.0.0",
"jest": "27.4.5",
"jest-mock": "^27.4.6",
"jest-mock-extended": "^2.0.1",
"moment-timezone": "^0.5.34",
"nock": "^13.2.1",
Expand Down
3 changes: 2 additions & 1 deletion modules/runners/lambdas/runners/src/aws/runners.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EC2 } from 'aws-sdk';
import { listEC2Runners, createRunner, terminateRunner, RunnerInfo, RunnerInputParameters } from './runners';

import ScaleError from './../scale-runners/ScaleError';
import { RunnerInfo, RunnerInputParameters, createRunner, listEC2Runners, terminateRunner } from './runners';

const mockEC2 = { describeInstances: jest.fn(), createFleet: jest.fn(), terminateInstances: jest.fn() };
const mockSSM = { putParameter: jest.fn() };
Expand Down
3 changes: 2 additions & 1 deletion modules/runners/lambdas/runners/src/aws/runners.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EC2, SSM } from 'aws-sdk';
import { logger as rootLogger, LogFields } from '../logger';

import { LogFields, logger as rootLogger } from '../logger';
import ScaleError from './../scale-runners/ScaleError';

const logger = rootLogger.getChildLogger({ name: 'runners' });
Expand Down
3 changes: 2 additions & 1 deletion modules/runners/lambdas/runners/src/aws/ssm.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GetParameterCommandOutput, SSM } from '@aws-sdk/client-ssm';
import nock from 'nock';

import { getParameterValue } from './ssm';
import { SSM, GetParameterCommandOutput } from '@aws-sdk/client-ssm';

jest.mock('@aws-sdk/client-ssm');

Expand Down
15 changes: 7 additions & 8 deletions modules/runners/lambdas/runners/src/gh-auth/gh-auth.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { createOctoClient, createGithubAppAuth } from './gh-auth';
import nock from 'nock';
import { createAppAuth } from '@octokit/auth-app';

import { StrategyOptions } from '@octokit/auth-app/dist-types/types';
import { getParameterValue } from './../aws/ssm';

import { RequestInterface } from '@octokit/types';
import { mock, MockProxy } from 'jest-mock-extended';
import { request } from '@octokit/request';
import { mocked } from 'ts-jest/utils';
import { RequestInterface } from '@octokit/types';
import { mocked } from 'jest-mock';
import { MockProxy, mock } from 'jest-mock-extended';
import nock from 'nock';

import { getParameterValue } from './../aws/ssm';
import { createGithubAppAuth, createOctoClient } from './gh-auth';

jest.mock('./../aws/ssm');
jest.mock('@octokit/auth-app');
Expand Down
15 changes: 8 additions & 7 deletions modules/runners/lambdas/runners/src/gh-auth/gh-auth.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { Octokit } from '@octokit/rest';
import { request } from '@octokit/request';
import { createAppAuth } from '@octokit/auth-app';
import {
StrategyOptions,
AppAuthentication,
AppAuthOptions,
InstallationAuthOptions,
InstallationAccessTokenAuthentication,
AppAuthentication,
AuthInterface,
InstallationAccessTokenAuthentication,
InstallationAuthOptions,
StrategyOptions,
} from '@octokit/auth-app/dist-types/types';
import { OctokitOptions } from '@octokit/core/dist-types/types';
import { request } from '@octokit/request';
import { Octokit } from '@octokit/rest';

import { getParameterValue } from '../aws/ssm';
import { logger as rootLogger, LogFields } from '../logger';
import { LogFields, logger as rootLogger } from '../logger';

const logger = rootLogger.getChildLogger({ name: 'gh-auth' });

Expand Down
33 changes: 17 additions & 16 deletions modules/runners/lambdas/runners/src/lambda.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Context, SQSEvent, SQSRecord } from 'aws-lambda';
import { mocked } from 'ts-jest/utils';
import { mocked } from 'jest-mock';

import { adjustPool, scaleDownHandler, scaleUpHandler } from './lambda';
import { ActionRequestMessage, scaleUp } from './scale-runners/scale-up';
import ScaleError from './scale-runners/ScaleError';
import { logger } from './logger';
import { scaleDown } from './scale-runners/scale-down';
import { adjust } from './pool/pool';
import ScaleError from './scale-runners/ScaleError';
import { scaleDown } from './scale-runners/scale-down';
import { ActionRequestMessage, scaleUp } from './scale-runners/scale-up';

const body: ActionRequestMessage = {
eventType: 'workflow_job',
Expand Down Expand Up @@ -62,6 +63,7 @@ jest.mock('./scale-runners/scale-down');
jest.mock('./pool/pool');
jest.mock('./logger');

// Docs for testing async with jest: https://jestjs.io/docs/tutorial-async
describe('Test scale up lambda wrapper.', () => {
it('Do not handle multiple record sets.', async () => {
await testInvalidRecords([sqsRecord, sqsRecord]);
Expand All @@ -82,18 +84,17 @@ describe('Test scale up lambda wrapper.', () => {
});

it('Non scale should resolve.', async () => {
const error = new Error('some error');
const error = new Error('Non scale should resolve.');
const mock = mocked(scaleUp);
mock.mockRejectedValue(error);
expect(await scaleUpHandler(sqsEvent, context)).resolves;
await expect(scaleUpHandler(sqsEvent, context)).resolves;
});

it('Scale should be rejected', async () => {
const error = new ScaleError('some scale error');
const error = new ScaleError('Scale should be rejected');
const mock = mocked(scaleUp);

mock.mockRejectedValue(error);
expect(scaleUpHandler(sqsEvent, context)).rejects.toThrow(error);
await expect(scaleUpHandler(sqsEvent, context)).rejects.toThrow(error);
});
});

Expand All @@ -109,7 +110,7 @@ async function testInvalidRecords(sqsRecords: SQSRecord[]) {
Records: sqsRecords,
};

expect(await scaleUpHandler(sqsEventMultipleRecords, context)).resolves;
await expect(scaleUpHandler(sqsEventMultipleRecords, context)).resolves;

expect(logWarnSpy).toHaveBeenCalledWith(
'Event ignored, only one record at the time can be handled, ensure the lambda batch size is set to 1.',
Expand All @@ -125,14 +126,14 @@ describe('Test scale down lambda wrapper.', () => {
resolve();
});
});
expect(await scaleDownHandler(context)).resolves;
await expect(scaleDownHandler(context)).resolves;
});

it('Scaling down with error.', async () => {
const error = new Error('some error');
const error = new Error('Scaling down with error.');
const mock = mocked(scaleDown);
mock.mockRejectedValue(error);
expect(await scaleDownHandler(context)).resolves;
await expect(await scaleDownHandler(context)).resolves;
});
});

Expand All @@ -144,15 +145,15 @@ describe('Adjust pool.', () => {
resolve();
});
});
expect(await adjustPool({ poolSize: 2 }, context)).resolves;
await expect(adjustPool({ poolSize: 2 }, context)).resolves;
});

it('Handle error for adjusting pool.', async () => {
const mock = mocked(adjust);
const error = new Error('errorXYX');
const error = new Error('Handle error for adjusting pool.');
mock.mockRejectedValue(error);
const logSpy = jest.spyOn(logger, 'error');
expect(await adjustPool({ poolSize: 0 }, context)).resolves;
await adjustPool({ poolSize: 0 }, context);
expect(logSpy).lastCalledWith(error);
});
});
11 changes: 6 additions & 5 deletions modules/runners/lambdas/runners/src/lambda.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { scaleUp } from './scale-runners/scale-up';
import { scaleDown } from './scale-runners/scale-down';
import { SQSEvent, Context } from 'aws-lambda';
import { Context, SQSEvent } from 'aws-lambda';
import 'source-map-support/register';

import { LogFields, logger } from './logger';
import { PoolEvent, adjust } from './pool/pool';
import ScaleError from './scale-runners/ScaleError';
import 'source-map-support/register';
import { adjust, PoolEvent } from './pool/pool';
import { scaleDown } from './scale-runners/scale-down';
import { scaleUp } from './scale-runners/scale-up';

export async function scaleUpHandler(event: SQSEvent, context: Context): Promise<void> {
logger.setSettings({ requestId: context.awsRequestId });
Expand Down
2 changes: 1 addition & 1 deletion modules/runners/lambdas/runners/src/local.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { logger } from './logger';
import { scaleUp, ActionRequestMessage } from './scale-runners/scale-up';
import { ActionRequestMessage, scaleUp } from './scale-runners/scale-up';

const sqsEvent = {
Records: [
Expand Down
17 changes: 9 additions & 8 deletions modules/runners/lambdas/runners/src/pool/pool.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { mocked } from 'ts-jest/utils';
import { adjust } from './pool';
import * as ghAuth from '../gh-auth/gh-auth';
import * as scale from '../scale-runners/scale-up';
import nock from 'nock';
import { Octokit } from '@octokit/rest';
import { mocked } from 'jest-mock';
import nock from 'nock';

import { listEC2Runners } from '../aws/runners';
import * as ghAuth from '../gh-auth/gh-auth';
import * as scale from '../scale-runners/scale-up';
import { adjust } from './pool';

const mockOctokit = {
paginate: jest.fn(),
Expand Down Expand Up @@ -153,13 +154,13 @@ describe('Test simple pool.', () => {
describe('With GitHub Cloud', () => {
it('Top up pool with pool size 2.', async () => {
const spy = jest.spyOn(scale, 'createRunners');
expect(await adjust({ poolSize: 2 })).resolves;
await expect(adjust({ poolSize: 2 })).resolves;
expect(spy).toBeCalled;
});

it('Should not top up if pool size is reached.', async () => {
const spy = jest.spyOn(scale, 'createRunners');
expect(await adjust({ poolSize: 1 })).resolves;
await expect(adjust({ poolSize: 1 })).resolves;
expect(spy).not.toHaveBeenCalled;
});
});
Expand All @@ -171,7 +172,7 @@ describe('Test simple pool.', () => {

it('Top up if the pool size is set to 5', async () => {
const spy = jest.spyOn(scale, 'createRunners');
expect(await adjust({ poolSize: 5 })).resolves;
await expect(adjust({ poolSize: 5 })).resolves;
expect(spy).toBeCalled;
});
});
Expand Down
5 changes: 3 additions & 2 deletions modules/runners/lambdas/runners/src/pool/pool.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import yn from 'yn';

import { listEC2Runners } from '../aws/runners';
import { createGithubAppAuth, createGithubInstallationAuth, createOctoClient } from '../gh-auth/gh-auth';
import { logger as rootLogger } from '../logger';
import { createRunners } from '../scale-runners/scale-up';
import { createGithubAppAuth, createGithubInstallationAuth, createOctoClient } from '../gh-auth/gh-auth';
import { listEC2Runners } from '../aws/runners';

const logger = rootLogger.getChildLogger({ name: 'pool' });

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import moment from 'moment-timezone';
import { getIdleRunnerCount, ScalingDownConfigList } from './scale-down-config';

import { ScalingDownConfigList, getIdleRunnerCount } from './scale-down-config';

const DEFAULT_TIMEZONE = 'America/Los_Angeles';
const DEFAULT_IDLE_COUNT = 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Octokit } from '@octokit/rest';
import { mocked } from 'jest-mock';
import moment from 'moment';
import { mocked } from 'ts-jest/utils';
import { listEC2Runners, terminateRunner, RunnerInfo, RunnerList } from './../aws/runners';
import { scaleDown } from './scale-down';
import * as ghAuth from '../gh-auth/gh-auth';
import nock from 'nock';
import { Octokit } from '@octokit/rest';

import * as ghAuth from '../gh-auth/gh-auth';
import { RunnerInfo, RunnerList, listEC2Runners, terminateRunner } from './../aws/runners';
import { githubCache } from './cache';
import { scaleDown } from './scale-down';

const mockOctokit = {
apps: {
Expand Down Expand Up @@ -350,7 +351,7 @@ describe('scaleDown', () => {
}
});

it('Terminates 0 runners owned by repos', async () => {
it('Terminates 0 runners owned by org', async () => {
mockListRunners.mockResolvedValue(RUNNERS_REPO_WITH_AUTO_SCALING_CONFIG);
process.env.ENABLE_ORGANIZATION_RUNNERS = 'false';
await scaleDown();
Expand All @@ -364,6 +365,22 @@ describe('scaleDown', () => {
});
});

it('No instances terminates when delete runner in github results in a non 204 status.', async () => {
mockListRunners.mockResolvedValue(DEFAULT_RUNNERS);
mockOctokit.actions.deleteSelfHostedRunnerFromOrg.mockImplementation(() => {
return { status: 500 };
});

await scaleDown();

expect(listEC2Runners).toBeCalledWith({
environment: environment,
});

expect(mockOctokit.apps.getOrgInstallation).toBeCalled();
expect(terminateRunner).not.toBeCalled;
});

it('Terminates 6 runners amongst all owners and all orphaned', async () => {
mockListRunners.mockResolvedValue(DEFAULT_RUNNERS);
await scaleDown();
Expand Down
11 changes: 6 additions & 5 deletions modules/runners/lambdas/runners/src/scale-runners/scale-down.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Octokit } from '@octokit/rest';
import moment from 'moment';
import { listEC2Runners, RunnerInfo, RunnerList, terminateRunner } from './../aws/runners';
import { getIdleRunnerCount, ScalingDownConfig } from './scale-down-config';
import { createOctoClient, createGithubAppAuth, createGithubInstallationAuth } from '../gh-auth/gh-auth';
import { githubCache, GhRunners } from './cache';
import { logger as rootLogger, LogFields } from '../logger';

import { createGithubAppAuth, createGithubInstallationAuth, createOctoClient } from '../gh-auth/gh-auth';
import { LogFields, logger as rootLogger } from '../logger';
import { RunnerInfo, RunnerList, listEC2Runners, terminateRunner } from './../aws/runners';
import { GhRunners, githubCache } from './cache';
import { ScalingDownConfig, getIdleRunnerCount } from './scale-down-config';

const logger = rootLogger.getChildLogger({ name: 'scale-down' });

Expand Down
Loading

0 comments on commit 6bd3f4c

Please sign in to comment.