Skip to content

Commit

Permalink
Added mocks and logging (#24743)
Browse files Browse the repository at this point in the history
* Added mocks and logging
  * https://github.com/elastic/ingest-dev/issues/54
  * Added test mocks to GraphQL
  * Added logging
  * Added unit tests

* Removed dead variable causing the build to fail
  • Loading branch information
FrankHassanabad authored and XavierM committed Oct 29, 2018
1 parent ca73f36 commit 820d0c5
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 4 deletions.
48 changes: 48 additions & 0 deletions x-pack/plugins/secops/server/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,54 @@
*/

import { rootSchema } from '../../common/graphql/root/schema.gql';
import sourceMock from '../graphql/sources/source.mock';
import sourcesMock from '../graphql/sources/sources.mock';
import { Logger } from '../utils/logger';
import { sourcesSchema } from './sources/schema.gql';

export const schemas = [rootSchema, sourcesSchema];

// The types from graphql-tools/src/mock.ts 'any' based. I add slightly
// stricter types here, but these should go away when graphql-tools using something
// other than "any" in the future for its types.
// https://github.com/apollographql/graphql-tools/blob/master/src/mock.ts#L406
interface Context {
req: {
payload: {
operationName: string;
};
};
}

export const createMocks = (logger: Logger) => ({
Query: () => ({
allSources: (root: unknown, args: unknown, context: Context) => {
logger.info('Mock allSources');
const operationName = context.req.payload.operationName.toLowerCase();
switch (operationName) {
case 'test': {
logger.info(`Using mock for test ${sourceMock}`);
return sourcesMock;
}
default: {
logger.error(`Could not find a mock for: ${operationName}`);
return [];
}
}
},
source: (root: unknown, args: unknown, context: Context) => {
logger.info('Mock source');
const operationName = context.req.payload.operationName.toLowerCase();
switch (operationName) {
case 'test': {
logger.info(`Using mock for test ${sourceMock}`);
return sourceMock;
}
default: {
logger.error(`Could not find a mock for: ${operationName}`);
return {};
}
}
},
}),
});
17 changes: 17 additions & 0 deletions x-pack/plugins/secops/server/graphql/sources/source.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/* tslint:disable */

export default
{
"id": "default",
"configuration": {
"fields": {
"host": "beat.hostname"
}
}
}
24 changes: 24 additions & 0 deletions x-pack/plugins/secops/server/graphql/sources/sources.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

/* tslint:disable */

export default
[
{
"id": "default",
"configuration": {
"fields": {
"container": "docker.container.name",
"host": "beat.hostname",
"message": [
"message",
"@message"
]
}
}
}
]
17 changes: 15 additions & 2 deletions x-pack/plugins/secops/server/init_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,29 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { IResolvers, makeExecutableSchema } from 'graphql-tools';
import { addMockFunctionsToSchema, IResolvers, makeExecutableSchema } from 'graphql-tools';

import { schemas } from './graphql';
import { createMocks } from './graphql';
import { createSourcesResolvers } from './graphql/sources';
import { AppBackendLibs } from './lib/types';
import { Logger } from './utils/logger';

export interface Config {
mocking: boolean;
logger: Logger;
}

export const initServer = (libs: AppBackendLibs) => {
export const initServer = (libs: AppBackendLibs, config: Config) => {
const { logger, mocking } = config;
const schema = makeExecutableSchema({
resolvers: [createSourcesResolvers(libs) as IResolvers],
typeDefs: schemas,
});

if (mocking) {
const mocks = createMocks(logger);
addMockFunctionsToSchema({ mocks, schema });
}
libs.framework.registerGraphQLEndpoint('/api/secops/graphql', schema);
};
25 changes: 25 additions & 0 deletions x-pack/plugins/secops/server/kibana.index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { amMocking } from './kibana.index';

describe('kibana.index', () => {
describe('#amMocking', () => {
afterEach(() => delete process.env.INGEST_MOCKS);

test('should return true when process.ENV.mocking is set to a lower case string true', () => {
process.env.INGEST_MOCKS = 'true';
expect(amMocking()).toEqual(true);
});
test('should return false when process.ENV.mocking is not set', () => {
expect(amMocking()).toEqual(false);
});
test('should return false when process.ENV.mocking is not set to a lower case string (since I am picky)', () => {
process.env.INGEST_MOCKS = 'TRUE';
expect(amMocking()).toEqual(false);
});
});
});
22 changes: 20 additions & 2 deletions x-pack/plugins/secops/server/kibana.index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,34 @@

import { Server } from 'hapi';
import JoiNamespace from 'joi';

import { initServer } from './init_server';
import { compose } from './lib/compose/kibana';
import { createLogger } from './utils/logger';

const APP_ID = 'secops';

export interface KbnServer extends Server {
usage: any;
usage: unknown;
}

export const amMocking = (): boolean => process.env.INGEST_MOCKS === 'true';

export const initServerWithKibana = (kbnServer: KbnServer) => {
const logger = createLogger(kbnServer);
logger.info('Plugin initializing');

const mocking = amMocking();
if (mocking) {
logger.info(
`Mocks for ${APP_ID} is activated. No real ${APP_ID} data will be used, only mocks will be used.`
);
}

const libs = compose(kbnServer);
initServer(libs);
initServer(libs, { mocking, logger });

logger.info('Plugin done initializing');
};

export const getConfigSchema = (Joi: typeof JoiNamespace) => {
Expand Down
46 changes: 46 additions & 0 deletions x-pack/plugins/secops/server/utils/logger.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { createLogger } from './logger';

const APP_ID = 'secops';
const createMockServer = () => ({ log: jest.fn() });

describe('logger', () => {
describe('#createLogger', () => {
test('should log out debug', () => {
const kbnServer = createMockServer();
const logger = createLogger(kbnServer as any);
logger.debug('debug information');
expect(kbnServer.log.mock.calls[0][0]).toEqual(['debug', APP_ID]);
expect(kbnServer.log.mock.calls[0][1]).toEqual('debug information');
});

test('should log out info', () => {
const kbnServer = createMockServer();
const logger = createLogger(kbnServer as any);
logger.info('info information');
expect(kbnServer.log.mock.calls[0][0]).toEqual(['info', APP_ID]);
expect(kbnServer.log.mock.calls[0][1]).toEqual('info information');
});

test('should log out warn', () => {
const kbnServer = createMockServer();
const logger = createLogger(kbnServer as any);
logger.warn('warn information');
expect(kbnServer.log.mock.calls[0][0]).toEqual(['warning', APP_ID]);
expect(kbnServer.log.mock.calls[0][1]).toEqual('warn information');
});

test('should log out error', () => {
const kbnServer = createMockServer();
const logger = createLogger(kbnServer as any);
logger.error('error information');
expect(kbnServer.log.mock.calls[0][0]).toEqual(['error', APP_ID]);
expect(kbnServer.log.mock.calls[0][1]).toEqual('error information');
});
});
});
23 changes: 23 additions & 0 deletions x-pack/plugins/secops/server/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Server } from 'hapi';

const LOGGING_TAGS = ['secops'];

export interface Logger {
debug: (message: string) => void;
info: (message: string) => void;
warn: (message: string) => void;
error: (message: string) => void;
}

export const createLogger = (kbnServer: Readonly<Server>): Readonly<Logger> => ({
debug: (message: string) => kbnServer.log(['debug', ...LOGGING_TAGS], message),
info: (message: string) => kbnServer.log(['info', ...LOGGING_TAGS], message),
warn: (message: string) => kbnServer.log(['warning', ...LOGGING_TAGS], message),
error: (message: string) => kbnServer.log(['error', ...LOGGING_TAGS], message),
});

0 comments on commit 820d0c5

Please sign in to comment.