-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Port @tsg's work on task manager. Remove 2nd var to track telemetry opt in. Add ES client to start querying index. Use query to get docs from a dummy index. Change how index is queried. Get diagnostic alerts to send to staging cluster. Record last timestamp. PoC on telemetry opt in via 2 processes. Revert to original solution * Update on agreed method. Fixes race condition. * Expand wildcards. * stage. * Add rule.ruleset collection. * Update telemetry sender with correct query for loading diag alerts. * Add similar task tests to endpont artifact work. * Fix broken import statement. * Create sender mocks. * Update test to check for func call. * Update unused reference. * record last run. * Update index. * fix import * Fix test. * test fix. * Pass unit to time diff calc. * Tests should pass now hopefully. * Add additional process fields to allowlist. Co-authored-by: Kibana Machine <[email protected]> Co-authored-by: Kibana Machine <[email protected]>
- Loading branch information
1 parent
2730154
commit 03523d7
Showing
5 changed files
with
383 additions
and
8 deletions.
There are no files selected for viewing
38 changes: 38 additions & 0 deletions
38
x-pack/plugins/security_solution/server/lib/telemetry/mocks.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* 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 { TelemetryEventsSender } from './sender'; | ||
import { TelemetryDiagTask } from './task'; | ||
|
||
/** | ||
* Creates a mocked Telemetry Events Sender | ||
*/ | ||
export const createMockTelemetryEventsSender = ( | ||
enableTelemtry: boolean | ||
): jest.Mocked<TelemetryEventsSender> => { | ||
return ({ | ||
setup: jest.fn(), | ||
start: jest.fn(), | ||
stop: jest.fn(), | ||
fetchDiagnosticAlerts: jest.fn(), | ||
queueTelemetryEvents: jest.fn(), | ||
processEvents: jest.fn(), | ||
isTelemetryOptedIn: jest.fn().mockReturnValue(enableTelemtry ?? jest.fn()), | ||
sendIfDue: jest.fn(), | ||
fetchClusterInfo: jest.fn(), | ||
fetchTelemetryUrl: jest.fn(), | ||
fetchLicenseInfo: jest.fn(), | ||
copyLicenseFields: jest.fn(), | ||
sendEvents: jest.fn(), | ||
} as unknown) as jest.Mocked<TelemetryEventsSender>; | ||
}; | ||
|
||
/** | ||
* Creates a mocked Telemetry Diagnostic Task | ||
*/ | ||
export class MockTelemetryDiagnosticTask extends TelemetryDiagTask { | ||
public runTask = jest.fn(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
x-pack/plugins/security_solution/server/lib/telemetry/task.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* 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 moment from 'moment'; | ||
import { loggingSystemMock } from 'src/core/server/mocks'; | ||
|
||
import { taskManagerMock } from '../../../../task_manager/server/mocks'; | ||
import { TaskStatus } from '../../../../task_manager/server'; | ||
|
||
import { TelemetryDiagTask, TelemetryDiagTaskConstants } from './task'; | ||
import { createMockTelemetryEventsSender, MockTelemetryDiagnosticTask } from './mocks'; | ||
|
||
describe('test', () => { | ||
let logger: ReturnType<typeof loggingSystemMock.createLogger>; | ||
|
||
beforeEach(() => { | ||
logger = loggingSystemMock.createLogger(); | ||
}); | ||
|
||
describe('basic diagnostic alert telemetry sanity checks', () => { | ||
test('task can register', () => { | ||
const telemetryDiagTask = new TelemetryDiagTask( | ||
logger, | ||
taskManagerMock.createSetup(), | ||
createMockTelemetryEventsSender(true) | ||
); | ||
|
||
expect(telemetryDiagTask).toBeInstanceOf(TelemetryDiagTask); | ||
}); | ||
}); | ||
|
||
test('diagnostic task should be registered', () => { | ||
const mockTaskManager = taskManagerMock.createSetup(); | ||
new TelemetryDiagTask(logger, mockTaskManager, createMockTelemetryEventsSender(true)); | ||
|
||
expect(mockTaskManager.registerTaskDefinitions).toHaveBeenCalled(); | ||
}); | ||
|
||
test('task should be scheduled', async () => { | ||
const mockTaskManagerSetup = taskManagerMock.createSetup(); | ||
const telemetryDiagTask = new TelemetryDiagTask( | ||
logger, | ||
mockTaskManagerSetup, | ||
createMockTelemetryEventsSender(true) | ||
); | ||
|
||
const mockTaskManagerStart = taskManagerMock.createStart(); | ||
await telemetryDiagTask.start(mockTaskManagerStart); | ||
expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); | ||
}); | ||
|
||
test('task should run', async () => { | ||
const mockContext = createMockTelemetryEventsSender(true); | ||
const mockTaskManager = taskManagerMock.createSetup(); | ||
const telemetryDiagTask = new MockTelemetryDiagnosticTask(logger, mockTaskManager, mockContext); | ||
|
||
const mockTaskInstance = { | ||
id: TelemetryDiagTaskConstants.TYPE, | ||
runAt: new Date(), | ||
attempts: 0, | ||
ownerId: '', | ||
status: TaskStatus.Running, | ||
startedAt: new Date(), | ||
scheduledAt: new Date(), | ||
retryAt: new Date(), | ||
params: {}, | ||
state: {}, | ||
taskType: TelemetryDiagTaskConstants.TYPE, | ||
}; | ||
const createTaskRunner = | ||
mockTaskManager.registerTaskDefinitions.mock.calls[0][0][TelemetryDiagTaskConstants.TYPE] | ||
.createTaskRunner; | ||
const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); | ||
await taskRunner.run(); | ||
expect(telemetryDiagTask.runTask).toHaveBeenCalled(); | ||
}); | ||
|
||
test('task should not query elastic if telemetry is not opted in', async () => { | ||
const mockSender = createMockTelemetryEventsSender(false); | ||
const mockTaskManager = taskManagerMock.createSetup(); | ||
new MockTelemetryDiagnosticTask(logger, mockTaskManager, mockSender); | ||
|
||
const mockTaskInstance = { | ||
id: TelemetryDiagTaskConstants.TYPE, | ||
runAt: new Date(), | ||
attempts: 0, | ||
ownerId: '', | ||
status: TaskStatus.Running, | ||
startedAt: new Date(), | ||
scheduledAt: new Date(), | ||
retryAt: new Date(), | ||
params: {}, | ||
state: {}, | ||
taskType: TelemetryDiagTaskConstants.TYPE, | ||
}; | ||
const createTaskRunner = | ||
mockTaskManager.registerTaskDefinitions.mock.calls[0][0][TelemetryDiagTaskConstants.TYPE] | ||
.createTaskRunner; | ||
const taskRunner = createTaskRunner({ taskInstance: mockTaskInstance }); | ||
await taskRunner.run(); | ||
expect(mockSender.fetchDiagnosticAlerts).not.toHaveBeenCalled(); | ||
}); | ||
|
||
test('test -5 mins is returned when there is no previous task run', async () => { | ||
const telemetryDiagTask = new TelemetryDiagTask( | ||
logger, | ||
taskManagerMock.createSetup(), | ||
createMockTelemetryEventsSender(true) | ||
); | ||
|
||
const executeTo = moment().utc().toISOString(); | ||
const executeFrom = undefined; | ||
const newExecuteFrom = telemetryDiagTask.getLastExecutionTimestamp(executeTo, executeFrom); | ||
|
||
expect(newExecuteFrom).toEqual(moment(executeTo).subtract(5, 'minutes').toISOString()); | ||
}); | ||
|
||
test('test -6 mins is returned when there was a previous task run', async () => { | ||
const telemetryDiagTask = new TelemetryDiagTask( | ||
logger, | ||
taskManagerMock.createSetup(), | ||
createMockTelemetryEventsSender(true) | ||
); | ||
|
||
const executeTo = moment().utc().toISOString(); | ||
const executeFrom = moment(executeTo).subtract(6, 'minutes').toISOString(); | ||
const newExecuteFrom = telemetryDiagTask.getLastExecutionTimestamp(executeTo, executeFrom); | ||
|
||
expect(newExecuteFrom).toEqual(executeFrom); | ||
}); | ||
|
||
// it's possible if Kibana is down for a prolonged period the stored lastRun would have drifted | ||
// if that is the case we will just roll it back to a 10 min search window | ||
test('test 10 mins is returned when previous task run took longer than 10 minutes', async () => { | ||
const telemetryDiagTask = new TelemetryDiagTask( | ||
logger, | ||
taskManagerMock.createSetup(), | ||
createMockTelemetryEventsSender(true) | ||
); | ||
|
||
const executeTo = moment().utc().toISOString(); | ||
const executeFrom = moment(executeTo).subtract(142, 'minutes').toISOString(); | ||
const newExecuteFrom = telemetryDiagTask.getLastExecutionTimestamp(executeTo, executeFrom); | ||
|
||
expect(newExecuteFrom).toEqual(moment(executeTo).subtract(10, 'minutes').toISOString()); | ||
}); | ||
}); |
Oops, something went wrong.