Skip to content

Commit

Permalink
feat: support tags/match filtering in push (#913)
Browse files Browse the repository at this point in the history
* feat: support tags/match filtering in push

* fix options test

* rename to grep options and add more tests
  • Loading branch information
vigneshshanmugam committed Apr 5, 2024
1 parent 7c75279 commit 13813d4
Show file tree
Hide file tree
Showing 12 changed files with 277 additions and 102 deletions.
64 changes: 58 additions & 6 deletions __tests__/core/runner.test.ts
Expand Up @@ -338,7 +338,7 @@ describe('runner', () => {
expect(
await runner.run({
...defaultRunOptions,
match: 'j2',
grepOpts: { match: 'j2' },
})
).toMatchObject({
j2: { status: 'succeeded' },
Expand All @@ -351,7 +351,7 @@ describe('runner', () => {
expect(
await runner.run({
...defaultRunOptions,
match: 'j*',
grepOpts: { match: 'j*' },
})
).toMatchObject({
j1: { status: 'succeeded' },
Expand All @@ -368,8 +368,7 @@ describe('runner', () => {
expect(
await runner.run({
...defaultRunOptions,
tags: ['foo*'],
match: 'j*',
grepOpts: { tags: ['foo*'], match: 'j*' },
})
).toMatchObject({
j1: { status: 'succeeded' },
Expand All @@ -385,7 +384,7 @@ describe('runner', () => {
expect(
await runner.run({
...defaultRunOptions,
tags: ['hello:b*'],
grepOpts: { tags: ['hello:b*'] },
})
).toMatchObject({
j2: { status: 'succeeded' },
Expand All @@ -400,7 +399,7 @@ describe('runner', () => {
expect(
await runner.run({
...defaultRunOptions,
tags: ['!hello:b*'],
grepOpts: { tags: ['!hello:b*'] },
})
).toMatchObject({
j1: { status: 'succeeded' },
Expand Down Expand Up @@ -750,6 +749,7 @@ describe('runner', () => {
throttling: { latency: 1000 },
schedule: 1,
alert: { status: { enabled: false } },
tags: [],
});
});

Expand Down Expand Up @@ -810,6 +810,58 @@ describe('runner', () => {
alert: { tls: { enabled: true } },
});
});

it('runner - build monitors filtered via "match"', async () => {
const j1 = new Journey({ name: 'j1' }, noop);
const j2 = new Journey({ name: 'j2' }, noop);
runner.addJourney(j1);
runner.addJourney(j2);

const monitors = runner.buildMonitors({
...options,
grepOpts: { match: 'j1' },
schedule: 1,
});
expect(monitors.length).toBe(1);
expect(monitors[0].config.name).toBe('j1');
});

it('runner - build monitors with via "tags"', async () => {
const j1 = new Journey({ name: 'j1', tags: ['first'] }, noop);
const j2 = new Journey({ name: 'j2', tags: ['second'] }, noop);
const j3 = new Journey({ name: 'j3' }, noop);
runner.addJourney(j1);
runner.addJourney(j2);
runner.addJourney(j3);

const monitors = runner.buildMonitors({
...options,
grepOpts: { tags: ['first'] },
schedule: 1,
});
expect(monitors.length).toBe(1);
expect(monitors[0].config.name).toBe('j1');
});

it('runner - build monitors with config and filter via "tags"', async () => {
const j1 = new Journey({ name: 'j1', tags: ['first'] }, noop);
const j2 = new Journey({ name: 'j2', tags: ['second'] }, noop);
const j3 = new Journey({ name: 'j3' }, noop);
runner.addJourney(j1);
runner.addJourney(j2);
runner.addJourney(j3);
// using monitor.use
j2.updateMonitor({ tags: ['newtag'] });

const monitors = runner.buildMonitors({
...options,
tags: ['newtag'],
grepOpts: { tags: ['newtag'] },
schedule: 1,
});
expect(monitors.length).toBe(2);
expect(monitors.map(m => m.config.name)).toEqual(['j2', 'j3']);
});
});

describe('journey and step annotations', () => {
Expand Down
1 change: 1 addition & 0 deletions __tests__/fixtures/synthetics.config.ts
Expand Up @@ -38,6 +38,7 @@ module.exports = env => {
screenshot: 'off',
schedule: 10,
locations: ['us_east'],
tags: ['foo', 'bar'],
privateLocations: ['test-location'],
alert: {
status: {
Expand Down
3 changes: 2 additions & 1 deletion __tests__/options.test.ts
Expand Up @@ -51,7 +51,7 @@ describe('options', () => {
expect(await normalizeOptions(cliArgs)).toMatchObject({
dryRun: true,
environment: 'test',
match: 'check*',
grepOpts: { match: 'check*' },
params: {
foo: 'bar',
url: 'non-dev',
Expand Down Expand Up @@ -108,6 +108,7 @@ describe('options', () => {
screenshots: 'only-on-failure',
schedule: 3,
privateLocations: ['test'],
tags: ['foo', 'bar'],
locations: ['australia_east'],
alert: {
status: {
Expand Down
7 changes: 0 additions & 7 deletions __tests__/push/__snapshots__/index.test.ts.snap
@@ -1,12 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Push abort on tags and match 1`] = `
"Aborted. Invalid CLI flags.
Tags and Match are not supported in push command.
"
`;

exports[`Push error on empty project id 1`] = `
"Aborted. Invalid synthetics project settings.
Expand Down
6 changes: 0 additions & 6 deletions __tests__/push/index.test.ts
Expand Up @@ -123,12 +123,6 @@ describe('Push', () => {
expect(output).toContain('Push command Aborted');
});

it('abort on tags and match', async () => {
await fakeProjectSetup({}, {});
const output = await runPush([...DEFAULT_ARGS, '--tags', 'foo:*']);
expect(output).toMatchSnapshot();
});

it('error on invalid schedule in monitor DSL', async () => {
await fakeProjectSetup(
{ id: 'test-project', space: 'dummy', url: 'http://localhost:8080' },
Expand Down
69 changes: 68 additions & 1 deletion __tests__/push/monitor.test.ts
Expand Up @@ -207,7 +207,7 @@ heartbeat.monitors:
`);
const monitors = await createLightweightMonitors(PROJECT_DIR, {
...opts,
pattern: '.yaml$',
grepOpts: { pattern: '.yaml$' },
});
expect(monitors.length).toBe(0);
});
Expand Down Expand Up @@ -236,6 +236,73 @@ heartbeat.monitors:
expect(monitors.length).toBe(1);
});

it('push - match filter', async () => {
await writeHBFile(`
heartbeat.monitors:
- type: http
name: "m1"
id: "mon1"
tags: "tag1"
- type: http
name: "m2"
id: "mon2"
tags: "tag2"
`);
const monitors = await createLightweightMonitors(PROJECT_DIR, {
...opts,
grepOpts: { match: 'm1' },
});
expect(monitors.length).toBe(1);
expect(monitors[0].config.name).toEqual('m1');
});

it('push - tags filter', async () => {
await writeHBFile(`
heartbeat.monitors:
- type: http
name: "m1"
id: "mon1"
tags: ["foo", "bar"]
- type: http
name: "m2"
id: "mon2"
tags: ["bar", "baz"]
- type: http
name: "m3"
id: "mon3"
tags: ["baz", "boom"]
`);
const monitors = await createLightweightMonitors(PROJECT_DIR, {
...opts,
grepOpts: { tags: ['bar'] },
});
expect(monitors.length).toBe(2);
expect(monitors.map(m => m.config.name)).toEqual(['m1', 'm2']);
});

it('push - apply tags config and also filter', async () => {
await writeHBFile(`
heartbeat.monitors:
- type: http
name: "m1"
id: "mon1"
tags: ["foo"]
- type: http
name: "m2"
id: "mon2"
- type: http
name: "m3"
id: "mon3"
`);
const monitors = await createLightweightMonitors(PROJECT_DIR, {
...opts,
tags: ['ltag'],
grepOpts: { tags: ['ltag'] },
});
expect(monitors.length).toBe(2);
expect(monitors.map(m => m.config.name)).toEqual(['m2', 'm3']);
});

it('prefer local monitor config', async () => {
await writeHBFile(`
heartbeat.monitors:
Expand Down
26 changes: 17 additions & 9 deletions src/cli.ts
Expand Up @@ -56,20 +56,25 @@ import { installTransform } from './core/transform';
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
const { name, version } = require('../package.json');

const { params, pattern, playwrightOpts, auth, authMandatory, configOpt } =
getCommonCommandOpts();
const {
params,
pattern,
playwrightOpts,
auth,
authMandatory,
configOpt,
tags,
match,
} = getCommonCommandOpts();

program
.name(`npx ${name}`)
.usage('[options] [dir] [files] file')
.addOption(configOpt)
.addOption(pattern)
.addOption(tags)
.addOption(match)
.addOption(params)
.option('--tags <name...>', 'run tests with a tag that matches the glob')
.option(
'--match <name>',
'run tests with a name or tags that matches the glob'
)
.addOption(
new Option('--reporter <value>', `output reporter format`).choices(
Object.keys(reporters)
Expand Down Expand Up @@ -157,6 +162,7 @@ program
.description(
'Push all journeys in the current directory to create monitors within the Kibana monitor management UI'
)
.addOption(authMandatory)
.option(
'--schedule <time-in-minutes>',
"schedule in minutes for the pushed monitors. Setting `10`, for example, configures monitors which don't have an interval defined to run every 10 minutes.",
Expand All @@ -172,7 +178,7 @@ program
'--private-locations <locations...>',
'default list of private locations from which your monitors will run.'
)
.option('--url <url>', 'Kibana URL to upload the monitors')
.option('--url <url>', 'Kibana URL to upload the project monitors')
.option(
'--id <id>',
'project id that will be used for logically grouping monitors'
Expand All @@ -182,8 +188,10 @@ program
'the target Kibana spaces for the pushed monitors — spaces help you organise pushed monitors.'
)
.option('-y, --yes', 'skip all questions and run non-interactively')
.addOption(authMandatory)

.addOption(pattern)
.addOption(tags)
.addOption(match)
.addOption(params)
.addOption(playwrightOpts)
.addOption(configOpt)
Expand Down
16 changes: 13 additions & 3 deletions src/common_types.ts
Expand Up @@ -200,14 +200,18 @@ export type ThrottlingOptions = {
latency?: number;
};

type GrepOptions = {
pattern?: string;
tags?: Array<string>;
match?: string;
};

type BaseArgs = {
params?: Params;
screenshots?: ScreenshotOptions;
dryRun?: boolean;
config?: string;
pattern?: string;
match?: string;
tags?: Array<string>;
auth?: string;
outfd?: number;
wsEndpoint?: string;
pauseOnError?: boolean;
Expand All @@ -220,6 +224,9 @@ type BaseArgs = {
};

export type CliArgs = BaseArgs & {
pattern?: string;
match?: string;
tags?: Array<string>;
reporter?: BuiltInReporterName;
inline?: boolean;
require?: Array<string>;
Expand All @@ -239,16 +246,19 @@ export type RunOptions = BaseArgs & {
environment?: string;
networkConditions?: NetworkConditions;
reporter?: BuiltInReporterName | ReporterInstance;
grepOpts?: GrepOptions;
};

export type PushOptions = Partial<ProjectSettings> &
Partial<BaseArgs> & {
auth: string;
kibanaVersion?: string;
yes?: boolean;
tags?: Array<string>;
alert?: AlertConfig;
retestOnFailure?: MonitorConfig['retestOnFailure'];
enabled?: boolean;
grepOpts?: GrepOptions;
};

export type ProjectSettings = {
Expand Down

0 comments on commit 13813d4

Please sign in to comment.