Skip to content

Commit

Permalink
Merge branch 'master' into 57813-table
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Jul 13, 2020
2 parents ac4727f + 79df8e0 commit dec24cb
Show file tree
Hide file tree
Showing 23 changed files with 533 additions and 231 deletions.
32 changes: 20 additions & 12 deletions test/functional/apps/discover/_doc_navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }) {
const retry = getService('retry');

// Flaky: https://github.com/elastic/kibana/issues/71216
describe.skip('doc link in discover', function contextSize() {
describe('doc link in discover', function contextSize() {
beforeEach(async function () {
log.debug('load kibana index with default index pattern');
await esArchiver.loadIfNeeded('discover');
Expand Down Expand Up @@ -63,20 +63,28 @@ export default function ({ getService, getPageObjects }) {
await filterBar.addFilter('agent', 'is', 'Missing/Fields');
await PageObjects.discover.waitUntilSearchingHasFinished();

// navigate to the doc view
await docTable.clickRowToggle({ rowIndex: 0 });
await retry.try(async () => {
// navigate to the doc view
await docTable.clickRowToggle({ rowIndex: 0 });

const details = await docTable.getDetailsRow();
await docTable.addInclusiveFilter(details, 'referer');
await PageObjects.discover.waitUntilSearchingHasFinished();
const details = await docTable.getDetailsRow();
await docTable.addInclusiveFilter(details, 'referer');
await PageObjects.discover.waitUntilSearchingHasFinished();

const hasInclusiveFilter = await filterBar.hasFilter('referer', 'exists', true, false, true);
expect(hasInclusiveFilter).to.be(true);
const hasInclusiveFilter = await filterBar.hasFilter(
'referer',
'exists',
true,
false,
true
);
expect(hasInclusiveFilter).to.be(true);

await docTable.removeInclusiveFilter(details, 'referer');
await PageObjects.discover.waitUntilSearchingHasFinished();
const hasExcludeFilter = await filterBar.hasFilter('referer', 'exists', true, false, false);
expect(hasExcludeFilter).to.be(true);
await docTable.removeInclusiveFilter(details, 'referer');
await PageObjects.discover.waitUntilSearchingHasFinished();
const hasExcludeFilter = await filterBar.hasFilter('referer', 'exists', true, false, false);
expect(hasExcludeFilter).to.be(true);
});
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface Aggregation {
buckets: Array<{
aggregatedValue: { value: number; values?: Array<{ key: number; value: number }> };
doc_count: number;
key_as_string: string;
}>;
};
}
Expand Down Expand Up @@ -57,17 +58,18 @@ export const evaluateAlert = (
);
const { threshold, comparator } = criterion;
const comparisonFunction = comparatorMap[comparator];
return mapValues(currentValues, (values: number | number[] | null) => {
if (isTooManyBucketsPreviewException(values)) throw values;
return mapValues(currentValues, (points: any[] | typeof NaN | null) => {
if (isTooManyBucketsPreviewException(points)) throw points;
return {
...criterion,
metric: criterion.metric ?? DOCUMENT_COUNT_I18N,
currentValue: Array.isArray(values) ? last(values) : NaN,
shouldFire: Array.isArray(values)
? values.map((value) => comparisonFunction(value, threshold))
currentValue: Array.isArray(points) ? last(points)?.value : NaN,
timestamp: Array.isArray(points) ? last(points)?.key : NaN,
shouldFire: Array.isArray(points)
? points.map((point) => comparisonFunction(point.value, threshold))
: [false],
isNoData: values === null,
isError: isNaN(values),
isNoData: points === null,
isError: isNaN(points),
};
});
})
Expand Down Expand Up @@ -157,17 +159,20 @@ const getValuesFromAggregations = (
const { buckets } = aggregations.aggregatedIntervals;
if (!buckets.length) return null; // No Data state
if (aggType === Aggregators.COUNT) {
return buckets.map((bucket) => bucket.doc_count);
return buckets.map((bucket) => ({ key: bucket.key_as_string, value: bucket.doc_count }));
}
if (aggType === Aggregators.P95 || aggType === Aggregators.P99) {
return buckets.map((bucket) => {
const values = bucket.aggregatedValue?.values || [];
const firstValue = first(values);
if (!firstValue) return null;
return firstValue.value;
return { key: bucket.key_as_string, value: firstValue.value };
});
}
return buckets.map((bucket) => bucket.aggregatedValue.value);
return buckets.map((bucket) => ({
key: bucket.key_as_string,
value: bucket.aggregatedValue.value,
}));
} catch (e) {
return NaN; // Error state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,26 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => {
);
});
});

describe('handles time', () => {
const end = new Date('2020-07-08T22:07:27.235Z').valueOf();
const timerange = {
end,
start: end - 5 * 60 * 1000,
};
const searchBody = getElasticsearchMetricQuery(
expressionParams,
timefield,
undefined,
undefined,
timerange
);
test('by rounding timestamps to the nearest timeUnit', () => {
const rangeFilter = searchBody.query.bool.filter.find((filter) =>
filter.hasOwnProperty('range')
)?.range[timefield];
expect(rangeFilter?.lte).toBe(1594246020000);
expect(rangeFilter?.gte).toBe(1594245720000);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { networkTraffic } from '../../../../../common/inventory_models/shared/metrics/snapshot/network_traffic';
import { MetricExpressionParams, Aggregators } from '../types';
import { getIntervalInSeconds } from '../../../../utils/get_interval_in_seconds';
import { roundTimestamp } from '../../../../utils/round_timestamp';
import { getDateHistogramOffset } from '../../../snapshot/query_helpers';
import { createPercentileAggregation } from './create_percentile_aggregation';

Expand Down Expand Up @@ -34,12 +36,15 @@ export const getElasticsearchMetricQuery = (
const interval = `${timeSize}${timeUnit}`;
const intervalAsSeconds = getIntervalInSeconds(interval);

const to = timeframe ? timeframe.end : Date.now();
const to = roundTimestamp(timeframe ? timeframe.end : Date.now(), timeUnit);
// We need enough data for 5 buckets worth of data. We also need
// to convert the intervalAsSeconds to milliseconds.
const minimumFrom = to - intervalAsSeconds * 1000 * MINIMUM_BUCKETS;

const from = timeframe && timeframe.start <= minimumFrom ? timeframe.start : minimumFrom;
const from = roundTimestamp(
timeframe && timeframe.start <= minimumFrom ? timeframe.start : minimumFrom,
timeUnit
);

const offset = getDateHistogramOffset(from, interval);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,14 @@ describe('The metric threshold alert type', () => {
expect(getState(instanceID).alertState).toBe(AlertStates.OK);
});
test('reports expected values to the action context', async () => {
const now = 1577858400000;
await execute(Comparator.GT, [0.75]);
const { action } = mostRecentAction(instanceID);
expect(action.group).toBe('*');
expect(action.reason).toContain('current value is 1');
expect(action.reason).toContain('threshold of 0.75');
expect(action.reason).toContain('test.metric.1');
expect(action.timestamp).toBe(new Date(now).toISOString());
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs, alertId: s
}
}
if (reason) {
const firstResult = first(alertResults);
const timestamp = (firstResult && firstResult[group].timestamp) ?? moment().toISOString();
alertInstance.scheduleActions(FIRED_ACTIONS.id, {
group,
alertState: stateToAlertMessage[nextState],
reason,
timestamp: moment().toISOString(),
timestamp,
value: mapToConditionsLookup(alertResults, (result) => result[group].currentValue),
threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
metric: mapToConditionsLookup(criteria, (c) => c.metric),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const bucketsA = [
{
doc_count: 3,
aggregatedValue: { value: 1.0, values: [{ key: 95.0, value: 1.0 }] },
key_as_string: new Date(1577858400000).toISOString(),
},
];

Expand Down
15 changes: 15 additions & 0 deletions x-pack/plugins/infra/server/utils/round_timestamp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 { Unit } from '@elastic/datemath';
import moment from 'moment';

export const roundTimestamp = (timestamp: number, unit: Unit) => {
const floor = moment(timestamp).startOf(unit).valueOf();
const ceil = moment(timestamp).add(1, unit).startOf(unit).valueOf();
if (Math.abs(timestamp - floor) <= Math.abs(timestamp - ceil)) return floor;
return ceil;
};
43 changes: 43 additions & 0 deletions x-pack/plugins/ingest_manager/common/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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 { NewPackageConfig, PackageConfig } from './types/models/package_config';

export const createNewPackageConfigMock = () => {
return {
name: 'endpoint-1',
description: '',
namespace: 'default',
enabled: true,
config_id: '93c46720-c217-11ea-9906-b5b8a21b268e',
output_id: '',
package: {
name: 'endpoint',
title: 'Elastic Endpoint',
version: '0.9.0',
},
inputs: [],
} as NewPackageConfig;
};

export const createPackageConfigMock = () => {
const newPackageConfig = createNewPackageConfigMock();
return {
...newPackageConfig,
id: 'c6d16e42-c32d-4dce-8a88-113cfe276ad1',
version: 'abcd',
revision: 1,
updated_at: '2020-06-25T16:03:38.159292',
updated_by: 'kibana',
created_at: '2020-06-25T16:03:38.159292',
created_by: 'kibana',
inputs: [
{
config: {},
},
],
} as PackageConfig;
};
5 changes: 3 additions & 2 deletions x-pack/plugins/security_solution/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"embeddable",
"features",
"home",
"ingestManager",
"taskManager",
"inspector",
"licensing",
Expand All @@ -21,6 +20,7 @@
],
"optionalPlugins": [
"encryptedSavedObjects",
"ingestManager",
"ml",
"newsfeed",
"security",
Expand All @@ -33,6 +33,7 @@
"requiredBundles": [
"kibanaUtils",
"esUiShared",
"kibanaReact"
"kibanaReact",
"ingestManager"
]
}
10 changes: 6 additions & 4 deletions x-pack/plugins/security_solution/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,12 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S

public start(core: CoreStart, plugins: StartPlugins) {
KibanaServices.init({ ...core, ...plugins, kibanaVersion: this.kibanaVersion });
plugins.ingestManager.registerPackageConfigComponent(
'endpoint',
ConfigureEndpointPackageConfig
);
if (plugins.ingestManager) {
plugins.ingestManager.registerPackageConfigComponent(
'endpoint',
ConfigureEndpointPackageConfig
);
}

return {};
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/security_solution/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface StartPlugins {
data: DataPublicPluginStart;
embeddable: EmbeddableStart;
inspector: InspectorStart;
ingestManager: IngestManagerStart;
ingestManager?: IngestManagerStart;
newsfeed?: NewsfeedStart;
triggers_actions_ui: TriggersActionsStart;
uiActions: UiActionsStart;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { httpServerMock } from '../../../../../src/core/server/mocks';
import { EndpointAppContextService } from './endpoint_app_context_services';

describe('test endpoint app context services', () => {
// it('should return undefined on getAgentService if dependencies are not enabled', async () => {
// const endpointAppContextService = new EndpointAppContextService();
// expect(endpointAppContextService.getAgentService()).toEqual(undefined);
// });
// it('should return undefined on getManifestManager if dependencies are not enabled', async () => {
// const endpointAppContextService = new EndpointAppContextService();
// expect(endpointAppContextService.getManifestManager()).toEqual(undefined);
// });
it('should return undefined on getAgentService if dependencies are not enabled', async () => {
const endpointAppContextService = new EndpointAppContextService();
expect(endpointAppContextService.getAgentService()).toEqual(undefined);
});
it('should return undefined on getManifestManager if dependencies are not enabled', async () => {
const endpointAppContextService = new EndpointAppContextService();
expect(endpointAppContextService.getManifestManager()).toEqual(undefined);
});
it('should throw error on getScopedSavedObjectsClient if start is not called', async () => {
const endpointAppContextService = new EndpointAppContextService();
expect(() =>
Expand Down
Loading

0 comments on commit dec24cb

Please sign in to comment.