Skip to content
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

Artifact creation and validation #2540

Merged
merged 37 commits into from
Sep 9, 2024
Merged
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0311ab2
WIP: Creating and validating artifact
Aug 29, 2024
68085ff
WIP: Cleanup
Aug 29, 2024
d1a7f25
feat: Update schema validation
Sep 3, 2024
bcc7ab4
fix: Properly get all datasource definitions
Sep 3, 2024
1e6e183
feat: First pass at error output
Sep 3, 2024
1de35c9
feat: Add community dataSourceIds
Sep 3, 2024
0cabd35
refactor: Rename datasource to dataSource
Sep 3, 2024
0b0ad40
feat: Additional error output formatting
Sep 3, 2024
1be1bd8
WIP: Creating and validating artifact
Aug 29, 2024
c5107b6
WIP: Cleanup
Aug 29, 2024
556b9cd
fix: Properly get all datasource definitions
Sep 3, 2024
76d9594
feat: First pass at error output
Sep 3, 2024
e9ef407
feat: Add community dataSourceIds
Sep 3, 2024
b1c5eb6
refactor: Rename datasource to dataSource
Sep 3, 2024
3a4ddf7
feat: Additional error output formatting
Sep 3, 2024
82ccc25
chore: Resolving merge conflicts
zstix Sep 5, 2024
5343088
refactor: Broke up large script to smaller, composable, functions
zstix Sep 5, 2024
5338b6b
feat: Fix configs for validation
mickeyryan42 Sep 5, 2024
ec3ceb6
feat: Fix config issues for validation
mickeyryan42 Sep 5, 2024
3e48902
feat: Remove extra filter
Sep 5, 2024
0ee8e1f
refactor: Minor cleanup with error parsing
Sep 5, 2024
0c3e0e6
fix: Correctly fetch all alerts
Sep 6, 2024
84cfe43
chore: Move comment to the right place
Sep 6, 2024
9fbe659
fix: Correct mongo operator
Sep 6, 2024
a54677a
feat: Update alerts schema
Sep 6, 2024
912a627
chore: Remove debug log
Sep 6, 2024
162893d
Merge branch 'campfire/NR-268461-config-fixes' of https://github.com/…
mickeyryan42 Sep 6, 2024
6c44419
refactor: Add a type guard function to remove the need for `as`
zstix Sep 6, 2024
8bb1b46
chore: Reverted flexibility with install directives
zstix Sep 6, 2024
ebb74da
chore: Show a success message when script encounters no errors
zstix Sep 6, 2024
533e844
refactor: Pull in lodash/get to make access to nested object easier
zstix Sep 6, 2024
9c39df9
chore: Remove unecessary whitespace
zstix Sep 6, 2024
2669874
chore: Slightly less permissive types
zstix Sep 6, 2024
ba9fc77
refactor: Separated error formatting from printing
zstix Sep 6, 2024
c10fc26
test: Ensure logic is correct for building and validating artifact
zstix Sep 6, 2024
1823bef
Merge branch 'campfire/NR-268461-build-validate-artifact' of https://…
mickeyryan42 Sep 9, 2024
a8d98bf
test: Add alert and dashboard to tests
mickeyryan42 Sep 9, 2024
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
Prev Previous commit
Next Next commit
test: Ensure logic is correct for building and validating artifact
zstix committed Sep 6, 2024

Verified

This commit was signed with the committer’s verified signature.
zstix Zack Stickles
commit c10fc26b834082d2b44739b647b37edc6a49b14a
163 changes: 163 additions & 0 deletions utils/__tests__/build-validate-quickstart-artifact.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import * as fs from 'fs';
import Quickstart from '../lib/Quickstart';
import DataSource from '../lib/DataSource';
import Alert from '../lib/Alert';
import Dashboard from '../lib/Dashboard';

import {
getArtifactComponents,
getDataSourceIds,
validateArtifact,
} from '../build-validate-quickstart-artifact';

jest.mock('../lib/Quickstart');
jest.mock('../lib/DataSource');
jest.mock('../lib/Alert');
jest.mock('../lib/Dashboard');
jest.mock('fs');

describe('built-validate-quickstart-artifact', () => {
beforeEach(() => {
// disable normal logging used as feedback while script runs
jest.spyOn(console, 'log').mockImplementation(() => {});
});

describe('build', () => {
it('should find all of the components', () => {
Quickstart.getAll = jest
.fn()
.mockReturnValueOnce([
{ config: 'test-quickstart-1' },
{ config: 'test-quickstart-2' },
]);

DataSource.getAll = jest
.fn()
.mockReturnValueOnce([{ config: 'test-dataSource-1' }]);

Alert.getAll = jest.fn().mockReturnValueOnce([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to test each of these with non-empty values here since we had problems with the getAll returning nothing before!

Dashboard.getAll = jest.fn().mockReturnValueOnce([]);

const actual = getArtifactComponents();

expect(actual.quickstarts).toHaveLength(2);
expect(actual.quickstarts[0]).toEqual('test-quickstart-1');
expect(actual.quickstarts[1]).toEqual('test-quickstart-2');
expect(actual.dataSources).toHaveLength(1);
expect(actual.dataSources[0]).toEqual('test-dataSource-1');
expect(actual.alerts).toHaveLength(0);
expect(actual.dashboards).toHaveLength(0);
});

it('should produce a complete list of dataSource IDs', () => {
Quickstart.getAll = jest.fn().mockReturnValueOnce([]);
Alert.getAll = jest.fn().mockReturnValueOnce([]);
Dashboard.getAll = jest.fn().mockReturnValueOnce([]);
DataSource.getAll = jest
.fn()
.mockReturnValueOnce([
{ config: { id: 'community-1' } },
{ config: { id: 'community-2' } },
{ config: { id: 'community-3' } },
]);

const { dataSources } = getArtifactComponents();
fs.readFileSync.mockReturnValueOnce(JSON.stringify(['core-1', 'core-2']));

const actual = getDataSourceIds('dummy-file.json', dataSources);

expect(actual).toHaveLength(5);
expect(actual).toContain('community-1');
expect(actual).toContain('community-2');
expect(actual).toContain('community-3');
expect(actual).toContain('core-1');
expect(actual).toContain('core-2');
});
});

describe('validate', () => {
const TEST_SCHEMA = {
type: 'object',
properties: {
quickstarts: { type: 'array' },
alerts: { type: 'array' },
dashboards: { type: 'array' },
dataSources: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string' },
title: { type: 'string' },
},
},
},
getDataSourceIds: { type: 'array', items: { type: 'string' } },
},
};

it('should correctly build and validate valid artifacts with no errors', () => {
Quickstart.getAll = jest.fn().mockReturnValueOnce([]);
Alert.getAll = jest.fn().mockReturnValueOnce([]);
Dashboard.getAll = jest.fn().mockReturnValueOnce([]);
DataSource.getAll = jest
.fn()
.mockReturnValueOnce([
{ config: { id: 'community-1', title: 'DataSource 1' } },
{ config: { id: 'community-2', title: 'DataSource 2' } },
{ config: { id: 'community-3', title: 'DataSource 3' } },
]);

const components = getArtifactComponents();

fs.readFileSync.mockReturnValueOnce(JSON.stringify(['core-1', 'core-2']));
const dataSourceIds = getDataSourceIds(
'dummy-file.json',
components.dataSources
);

const artifact = { ...components, dataSourceIds };

const actual = validateArtifact(TEST_SCHEMA, artifact);

expect(actual).toHaveLength(0);
});

it('should correctly return errors for an invalid artifact', () => {
Quickstart.getAll = jest.fn().mockReturnValueOnce([]);
Alert.getAll = jest.fn().mockReturnValueOnce([]);
Dashboard.getAll = jest.fn().mockReturnValueOnce([]);
DataSource.getAll = jest
.fn()
.mockReturnValueOnce([
{ config: { id: 'community-1', title: 'DataSource 1' } },
{ config: { id: false, title: 'DataSource 2' } },
{ config: { id: 'community-3', title: 3 } },
]);

const components = getArtifactComponents();

fs.readFileSync.mockReturnValueOnce(JSON.stringify(['core-1', 'core-2']));
const dataSourceIds = getDataSourceIds(
'dummy-file.json',
components.dataSources
);

const artifact = { ...components, dataSourceIds };

const actual = validateArtifact(TEST_SCHEMA, artifact);

expect(actual).toHaveLength(2);
expect(actual).toEqual(
expect.arrayContaining([
expect.objectContaining({
instancePath: '/dataSources/1/id',
}),
expect.objectContaining({
instancePath: '/dataSources/2/title',
}),
])
);
});
});
});
6 changes: 3 additions & 3 deletions utils/build-validate-quickstart-artifact.ts
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ const getSchema = (filepath: string): ArtifactSchema => {
};

// NOTE: we could run these in parallel to speed up the script
const getArtifactComponents = (): ArtifactComponents => {
export const getArtifactComponents = (): ArtifactComponents => {
const quickstarts = Quickstart.getAll().map((quickstart) => quickstart.config);
console.log(`[*] Found ${quickstarts.length} quickstarts`);

@@ -57,7 +57,7 @@ const getArtifactComponents = (): ArtifactComponents => {
}
};

const getDataSourceIds = (filepath: string, communityDataSources: DataSourceConfig[]): string[] => {
export const getDataSourceIds = (filepath: string, communityDataSources: DataSourceConfig[]): string[] => {
const coreDataSourceIds = yaml.load(
fs.readFileSync(filepath).toString('utf8')
) as string[];
@@ -67,7 +67,7 @@ const getDataSourceIds = (filepath: string, communityDataSources: DataSourceConf
return [...coreDataSourceIds, ...communityDataSourceIds];
}

const validateArtifact = (schema: ArtifactSchema, artifact: Artifact): ErrorObject[] => {
export const validateArtifact = (schema: ArtifactSchema, artifact: Artifact): ErrorObject[] => {
const ajv = new Ajv({ allErrors: true });
ajv.validate(schema, artifact);