[Uptime] Do not drop edge buckets (#48157)

* Checkpoint first uptime bucket

* Add code to specify interval for histogram chart, delete obsolete formatting code.

* Revert file to master version.

* Update usages of modified helper function.

* Delete obslete snapshot.

* Modify outdated tests and refresh snapshots.

* Update API test fixtures and several tests to avoid flakiness.

* Remove unneeded size field.

* Rename a type.

* Split concerns to two separate functions.

* Update chart formatting label stops and casing to fit latest charts.

* Remove addition of interval to x domain.

* Update tests to accommodate new changes.
This commit is contained in:
Justin Kambic 2019-10-25 18:42:31 -04:00 committed by GitHub
parent dba5481181
commit e7d82f29d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 849 additions and 838 deletions

View file

@ -4,8 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
const MINUTE = 1000 * 60;
const HOUR = MINUTE * 60;
const DAY = 24 * 60 * 60 * 1000;
const WEEK = DAY * 7;
const MONTH = WEEK * 4;
/**
* These contsants are used by the charting code to determine
@ -14,9 +17,10 @@ const WEEK = DAY * 7;
*/
export const CHART_FORMAT_LIMITS = {
DAY,
FIFTEEN_DAYS: 1000 * 60 * 60 * 24 * 15,
EIGHT_MINUTES: 1000 * 60 * 8,
EIGHT_MINUTES: MINUTE * 8,
FOUR_YEARS: 4 * 12 * 4 * WEEK,
THIRTY_SIX_HOURS: 1000 * 60 * 60 * 36,
THIRTY_SIX_HOURS: HOUR * 36,
THREE_WEEKS: WEEK * 3,
SIX_MONTHS: MONTH * 7,
NINE_DAYS: DAY * 9,
};

View file

@ -4,7 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { HistogramDataPoint } from '../graphql/types';
export interface UMGqlRange {
dateRangeStart: string;
dateRangeEnd: string;
}
export interface HistogramResult {
histogram: HistogramDataPoint[];
interval: number;
}

View file

@ -20,13 +20,13 @@ import React, { useContext } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import moment from 'moment';
import styled from 'styled-components';
import { HistogramDataPoint } from '../../../../common/graphql/types';
import { getColorsMap } from './get_colors_map';
import { getChartDateLabel } from '../../../lib/helper';
import { withUptimeGraphQL, UptimeGraphQLQueryProps } from '../../higher_order';
import { snapshotHistogramQuery } from '../../../queries/snapshot_histogram_query';
import { ChartWrapper } from './chart_wrapper';
import { UptimeSettingsContext } from '../../../contexts';
import { HistogramResult } from '../../../../common/domain_types';
const SnapshotHistogramWrapper = styled.div`
margin-left: 120px;
@ -56,7 +56,7 @@ export interface SnapshotHistogramProps {
}
interface SnapshotHistogramQueryResult {
histogram?: HistogramDataPoint[];
queryResult?: HistogramResult;
}
type Props = UptimeGraphQLQueryProps<SnapshotHistogramQueryResult> & SnapshotHistogramProps;
@ -68,7 +68,7 @@ export const SnapshotHistogramComponent = ({
loading = false,
height,
}: Props) => {
if (!data || !data.histogram)
if (!data || !data.queryResult)
/**
* TODO: the Fragment, EuiTitle, and EuiPanel should be extracted to a dumb component
* that we can reuse in the subsequent return statement at the bottom of this function.
@ -107,7 +107,9 @@ export const SnapshotHistogramComponent = ({
</EuiPanel>
</>
);
const { histogram } = data;
const {
queryResult: { histogram, interval },
} = data;
const {
colors: { danger, gray },
@ -145,7 +147,14 @@ export const SnapshotHistogramComponent = ({
})}
>
<Chart>
<Settings xDomain={{ min: absoluteStartDate, max: absoluteEndDate }} showLegend={false} />
<Settings
xDomain={{
minInterval: interval,
min: absoluteStartDate,
max: absoluteEndDate,
}}
showLegend={false}
/>
<Axis
id={getAxisId(
i18n.translate('xpack.uptime.snapshotHistogram.xAxisId', {

View file

@ -24,7 +24,7 @@ describe('getChartLabelFormatter', () => {
it('creates a label with month/day and hour/minute for time between 36 hours and 4 days', () => {
// Sun, 15 Jul 2001 17:53:10 GMT -> Thu, 19 Jul 2001 17:52:59 GMT
expect(getChartDateLabel(995219590000, 995565179000)).toBe('MM-dd HH:mm');
expect(getChartDateLabel(995219590000, 995565179000)).toBe('MM-DD HH:mm');
});
it('creates a format without day/month string for delta within same day local time', () => {
@ -34,17 +34,25 @@ describe('getChartLabelFormatter', () => {
it('creates a format with date/month string for delta crossing dates', () => {
// Wed, 18 Jul 2001 11:06:19 GMT -> Thu, 19 Jul 2001 17:52:59 GMT
expect(getChartDateLabel(995454379000, 995565179000)).toBe('MM-dd HH:mm');
expect(getChartDateLabel(995454379000, 995565179000)).toBe('MM-DD HH:mm');
});
it('creates a format with only month/day for delta between to eight days and two weeks', () => {
// Sun, 01 Jul 2001 23:28:15 GMT -> Thu, 19 Jul 2001 17:52:59 GMT
expect(getChartDateLabel(994030095000, 995565179000)).toBe('MM-dd');
expect(getChartDateLabel(994030095000, 995565179000)).toBe('MM-DD');
});
it('creates a format with the year/month for range exceeding a week', () => {
it('creates a format with the date and hour/min for 36h < range < 9d', () => {
expect(getChartDateLabel(1003752000000, 1004270400000)).toBe('MM-DD HH:mm');
});
it('creates a format with month/day for range between nine days and three weeks', () => {
expect(getChartDateLabel(1003752000000, 1004875200000)).toBe('MM-DD');
});
it('creates a format with the year/month/day for range exceeding three weeks', () => {
// Sun, 15 Jul 2001 12:27:59 GMT -> Fri, 28 Dec 2001 18:46:19 GMT
expect(getChartDateLabel(995200079000, 1009565179000)).toBe('yyyy-MM');
expect(getChartDateLabel(995200079000, 1009565179000)).toBe('YYYY-MM-DD');
});
it('creates a format of only year for timespan > 4 years', () => {

View file

@ -34,7 +34,7 @@ export const getChartDateLabel = (dateRangeStart: number, dateRangeEnd: number)
delta < CHART_FORMAT_LIMITS.THIRTY_SIX_HOURS &&
!isWithinCurrentDate(dateRangeStart, dateRangeEnd)
) {
formatString = 'MM-dd ';
formatString = 'MM-DD ';
}
return formatString + getLabelFormat(delta);
};

View file

@ -7,11 +7,12 @@
import { CHART_FORMAT_LIMITS } from '../../../../common/constants';
const {
FIFTEEN_DAYS,
EIGHT_MINUTES,
FOUR_YEARS,
THIRTY_SIX_HOURS,
THREE_WEEKS,
SIX_MONTHS,
NINE_DAYS,
} = CHART_FORMAT_LIMITS;
/**
@ -30,16 +31,20 @@ const dateStops: Array<{ key: number; value: string }> = [
value: 'HH:mm',
},
{
key: FIFTEEN_DAYS,
value: 'MM-dd HH:mm',
key: NINE_DAYS,
value: 'MM-DD HH:mm',
},
{
key: THREE_WEEKS,
value: 'MM-dd',
value: 'MM-DD',
},
{
key: SIX_MONTHS,
value: 'YYYY-MM-DD',
},
{
key: FOUR_YEARS,
value: 'yyyy-MM',
value: 'YYYY-MM',
},
];

View file

@ -14,18 +14,21 @@ export const snapshotHistogramQueryString = `
$monitorId: String
$statusFilter: String
) {
histogram: getSnapshotHistogram(
queryResult: getSnapshotHistogram(
dateRangeStart: $dateRangeStart
dateRangeEnd: $dateRangeEnd
filters: $filters
statusFilter: $statusFilter
monitorId: $monitorId
) {
histogram {
upCount
downCount
x
x0
y
}
interval
}
}
`;

View file

@ -17,11 +17,11 @@ import {
MonitorPageTitle,
Ping,
Snapshot,
HistogramDataPoint,
GetSnapshotHistogramQueryArgs,
} from '../../../common/graphql/types';
import { UMServerLibs } from '../../lib/lib';
import { CreateUMGraphQLResolvers, UMContext } from '../types';
import { HistogramResult } from '../../../common/domain_types';
export type UMSnapshotResolver = UMResolver<
Snapshot | Promise<Snapshot>,
@ -61,7 +61,7 @@ export type UMGetMontiorPageTitleResolver = UMResolver<
>;
export type UMGetSnapshotHistogram = UMResolver<
HistogramDataPoint[] | Promise<HistogramDataPoint[]>,
HistogramResult | Promise<HistogramResult>,
any,
GetSnapshotHistogramQueryArgs,
UMContext
@ -101,7 +101,7 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = (
resolver,
{ dateRangeStart, dateRangeEnd, filters, monitorId, statusFilter },
{ req }
): Promise<HistogramDataPoint[]> {
): Promise<HistogramResult> {
return await libs.pings.getPingHistogram(
req,
dateRangeStart,

View file

@ -120,6 +120,11 @@ export const monitorsSchema = gql`
monitors: [LatestMonitor!]
}
type HistogramResult {
histogram: [HistogramDataPoint]!
interval: UnsignedInteger!
}
type MonitorPageTitle {
id: String!
url: String
@ -147,7 +152,7 @@ export const monitorsSchema = gql`
filters: String
statusFilter: String
monitorId: String
): [HistogramDataPoint!]!
): HistogramResult
getMonitorChartsData(
monitorId: String!

View file

@ -6,7 +6,7 @@
import { get, sortBy } from 'lodash';
import { QueryContext } from '../elasticsearch_monitor_states_adapter';
import { getHistogramInterval } from '../../../helper';
import { getHistogramIntervalFormatted } from '../../../helper';
import { INDEX_NAMES, STATES } from '../../../../../common/constants';
import {
MonitorSummary,
@ -324,7 +324,7 @@ const getHistogramForMonitors = async (
histogram: {
date_histogram: {
field: '@timestamp',
fixed_interval: getHistogramInterval(
fixed_interval: getHistogramIntervalFormatted(
queryContext.dateRangeStart,
queryContext.dateRangeEnd
),

View file

@ -221,6 +221,10 @@ Object {
"x": 1568412432000,
"y": 1972483.25,
},
Object {
"x": 1568412468000,
"y": 1020490,
},
],
"name": "us-east-2",
},
@ -302,6 +306,10 @@ Object {
"x": 1568412432000,
"y": 1543307.5,
},
Object {
"x": 1568412468000,
"y": null,
},
],
"name": "us-west-4",
},
@ -421,6 +429,12 @@ Object {
"up": null,
"x": 1568412432000,
},
Object {
"down": null,
"total": 1,
"up": null,
"x": 1568412468000,
},
],
"statusMaxCount": 0,
}

View file

@ -13,12 +13,7 @@ import {
Ping,
LocationDurationLine,
} from '../../../../common/graphql/types';
import {
dropLatestBucket,
getFilterClause,
getHistogramInterval,
parseFilterQuery,
} from '../../helper';
import { getFilterClause, parseFilterQuery, getHistogramIntervalFormatted } from '../../helper';
import { DatabaseAdapter } from '../database';
import { UMMonitorsAdapter } from './adapter_types';
@ -80,7 +75,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
timeseries: {
date_histogram: {
field: '@timestamp',
fixed_interval: getHistogramInterval(dateRangeStart, dateRangeEnd),
fixed_interval: getHistogramIntervalFormatted(dateRangeStart, dateRangeEnd),
min_doc_count: 0,
},
aggs: {
@ -102,10 +97,7 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter {
const result = await this.database.search(request, params);
const dateHistogramBuckets = dropLatestBucket(
get(result, 'aggregations.timeseries.buckets', [])
);
const dateHistogramBuckets = get<any[]>(result, 'aggregations.timeseries.buckets', []);
/**
* The code below is responsible for formatting the aggregation data we fetched above in a way
* that the chart components used by the client understands.

View file

@ -1,82 +1,127 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ElasticsearchPingsAdapter class getPingHistogram handles simple_text_query without issues 1`] = `
Array [
Object {
"downCount": 1,
"key": 1,
"upCount": 2,
"x": 2,
"x0": 1,
"y": 1,
},
Object {
"downCount": 2,
"key": 2,
"upCount": 1,
"x": 3,
"x0": 2,
"y": 1,
},
]
Object {
"histogram": Array [
Object {
"downCount": 1,
"upCount": 2,
"x": 1,
"y": 1,
},
Object {
"downCount": 2,
"upCount": 1,
"x": 2,
"y": 1,
},
Object {
"downCount": 1,
"upCount": 3,
"x": 3,
"y": 1,
},
],
"interval": 36000,
}
`;
exports[`ElasticsearchPingsAdapter class getPingHistogram handles status + additional user queries 1`] = `
Array [
Object {
"downCount": 1,
"key": 1,
"upCount": 0,
"x": 2,
"x0": 1,
"y": 1,
},
Object {
"downCount": 2,
"key": 2,
"upCount": 0,
"x": 3,
"x0": 2,
"y": 1,
},
]
Object {
"histogram": Array [
Object {
"downCount": 1,
"upCount": 0,
"x": 1,
"y": 1,
},
Object {
"downCount": 2,
"upCount": 0,
"x": 2,
"y": 1,
},
Object {
"downCount": 1,
"upCount": 0,
"x": 3,
"y": 1,
},
],
"interval": 5609564928000,
}
`;
exports[`ElasticsearchPingsAdapter class getPingHistogram returns a down-filtered array for when filtered by down status 1`] = `
Array [
Object {
"downCount": 1,
"key": 1,
"upCount": 0,
"x": 2,
"x0": 1,
"y": 1,
},
]
Object {
"histogram": Array [
Object {
"downCount": 1,
"upCount": 0,
"x": 1,
"y": 1,
},
Object {
"downCount": undefined,
"upCount": 0,
"x": 2,
"y": 1,
},
],
"interval": 5609564928000,
}
`;
exports[`ElasticsearchPingsAdapter class getPingHistogram returns a down-filtered array for when filtered by up status 1`] = `
Array [
Object {
"downCount": 0,
"key": 1,
"upCount": 2,
"x": 2,
"x0": 1,
"y": 1,
},
]
Object {
"histogram": Array [
Object {
"downCount": 0,
"upCount": 2,
"x": 1,
"y": 1,
},
Object {
"downCount": 0,
"upCount": 2,
"x": 2,
"y": 1,
},
],
"interval": 5609564928000,
}
`;
exports[`ElasticsearchPingsAdapter class getPingHistogram returns a single bucket if array has 1 1`] = `
Object {
"histogram": Array [
Object {
"downCount": 1,
"upCount": 2,
"x": 1,
"y": 1,
},
],
"interval": 36000,
}
`;
exports[`ElasticsearchPingsAdapter class getPingHistogram returns expected result for no status filter 1`] = `
Array [
Object {
"downCount": 1,
"key": 1,
"upCount": 2,
"x": 2,
"x0": 1,
"y": 1,
},
]
Object {
"histogram": Array [
Object {
"downCount": 1,
"upCount": 2,
"x": 1,
"y": 1,
},
Object {
"downCount": undefined,
"upCount": 2,
"x": 2,
"y": 1,
},
],
"interval": 36000,
}
`;

View file

@ -88,7 +88,7 @@ describe('ElasticsearchPingsAdapter class', () => {
});
describe('getPingHistogram', () => {
it('returns an empty array for <= 1 bucket', async () => {
it('returns a single bucket if array has 1', async () => {
expect.assertions(2);
const search = jest.fn();
search.mockReturnValue({
@ -116,7 +116,7 @@ describe('ElasticsearchPingsAdapter class', () => {
const pingAdapter = new ElasticsearchPingsAdapter(pingDatabase);
const result = await pingAdapter.getPingHistogram(serverRequest, 'now-15m', 'now', null);
expect(pingDatabase.search).toHaveBeenCalledTimes(1);
expect(result).toEqual([]);
expect(result).toMatchSnapshot();
});
it('returns expected result for no status filter', async () => {

View file

@ -4,7 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { DocCount, HistogramDataPoint, Ping, PingResults } from '../../../../common/graphql/types';
import { DocCount, Ping, PingResults } from '../../../../common/graphql/types';
import { HistogramResult } from '../../../../common/domain_types';
export interface UMPingsAdapter {
getAll(
@ -33,7 +34,7 @@ export interface UMPingsAdapter {
filters?: string | null,
monitorId?: string | null,
statusFilter?: string | null
): Promise<HistogramDataPoint[]>;
): Promise<HistogramResult>;
getDocCount(request: any): Promise<DocCount>;
}

View file

@ -6,17 +6,12 @@
import { get } from 'lodash';
import { INDEX_NAMES } from '../../../../common/constants';
import {
DocCount,
HistogramDataPoint,
HttpBody,
Ping,
PingResults,
} from '../../../../common/graphql/types';
import { formatEsBucketsForHistogram, parseFilterQuery, getFilterClause } from '../../helper';
import { DocCount, HttpBody, Ping, PingResults } from '../../../../common/graphql/types';
import { parseFilterQuery, getFilterClause, getHistogramIntervalFormatted } from '../../helper';
import { DatabaseAdapter, HistogramQueryResult } from '../database';
import { UMPingsAdapter } from './adapter_types';
import { getHistogramInterval } from '../../helper/get_histogram_interval';
import { HistogramResult } from '../../../../common/domain_types';
export class ElasticsearchPingsAdapter implements UMPingsAdapter {
private database: DatabaseAdapter;
@ -195,7 +190,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
filters?: string | null,
monitorId?: string | null,
statusFilter?: string | null
): Promise<HistogramDataPoint[]> {
): Promise<HistogramResult> {
const boolFilters = parseFilterQuery(filters);
const additionaFilters = [];
if (monitorId) {
@ -205,6 +200,8 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
additionaFilters.push(boolFilters);
}
const filter = getFilterClause(dateRangeStart, dateRangeEnd, additionaFilters);
const interval = getHistogramInterval(dateRangeStart, dateRangeEnd);
const intervalFormatted = getHistogramIntervalFormatted(dateRangeStart, dateRangeEnd);
const params = {
index: INDEX_NAMES.HEARTBEAT,
@ -219,7 +216,7 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
timeseries: {
date_histogram: {
field: '@timestamp',
fixed_interval: getHistogramInterval(dateRangeStart, dateRangeEnd),
fixed_interval: intervalFormatted,
},
aggs: {
down: {
@ -244,19 +241,21 @@ export class ElasticsearchPingsAdapter implements UMPingsAdapter {
const result = await this.database.search(request, params);
const buckets: HistogramQueryResult[] = get(result, 'aggregations.timeseries.buckets', []);
const mappedBuckets = buckets.map(bucket => {
const key: number = get(bucket, 'key');
const histogram = buckets.map(bucket => {
const x: number = get(bucket, 'key');
const downCount: number = get(bucket, 'down.doc_count');
const upCount: number = get(bucket, 'up.doc_count');
return {
key,
x,
downCount: statusFilter && statusFilter !== 'down' ? 0 : downCount,
upCount: statusFilter && statusFilter !== 'up' ? 0 : upCount,
y: 1,
};
});
return formatEsBucketsForHistogram(mappedBuckets);
return {
histogram,
interval,
};
}
/**

View file

@ -1,9 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`dropLatestBucket drops the last of a list with greater length than 1 1`] = `
Array [
Object {
"prop": "val",
},
]
`;

View file

@ -1,42 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`formatEsBucketsForHistogram returns properly formatted buckets 1`] = `
Array [
Object {
"key": 1000,
"x": 2000,
"x0": 1000,
},
Object {
"key": 2000,
"x": 3000,
"x0": 2000,
},
Object {
"key": 3000,
"x": 4000,
"x0": 3000,
},
]
`;
exports[`formatEsBucketsForHistogram returns properly formatted object for generic call 1`] = `
Array [
Object {
"key": 1000,
"name": "something",
"value": 150,
"x": 2000,
"x0": 1000,
},
Object {
"key": 2000,
"name": "something",
"value": 120,
"x": 3000,
"x0": 2000,
},
]
`;
exports[`formatEsBucketsForHistogram returns the provided buckets if length is below min threshold 1`] = `Array []`;

View file

@ -1,25 +0,0 @@
/*
* 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 { dropLatestBucket } from '../drop_latest_bucket';
describe('dropLatestBucket', () => {
it('drops the last of a list with greater length than 1', () => {
const testData = [{ prop: 'val' }, { prop: 'val' }];
const result = dropLatestBucket(testData);
expect(result).toMatchSnapshot();
});
it('returns an empty list when length === 1', () => {
const testData = [{ prop: 'val' }];
const result = dropLatestBucket(testData);
expect(result).toEqual([]);
});
it('returns an empty list when length === 0', () => {
const testData: any[] = [];
const result = dropLatestBucket(testData);
expect(result).toEqual([]);
});
});

View file

@ -1,29 +0,0 @@
/*
* 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 { formatEsBucketsForHistogram } from '../format_es_buckets_for_histogram';
describe('formatEsBucketsForHistogram', () => {
it('returns the provided buckets if length is below min threshold', () => {
const buckets = [{ key: 1000 }];
const result = formatEsBucketsForHistogram(buckets);
expect(result).toMatchSnapshot();
});
it('returns properly formatted buckets', () => {
const buckets = [{ key: 1000 }, { key: 2000 }, { key: 3000 }, { key: 4000 }];
const result = formatEsBucketsForHistogram(buckets);
expect(result).toMatchSnapshot();
});
it('returns properly formatted object for generic call', () => {
const buckets = [
{ key: 1000, name: 'something', value: 150 },
{ key: 2000, name: 'something', value: 120 },
{ key: 3000, name: 'something', value: 180 },
];
const result = formatEsBucketsForHistogram(buckets);
expect(result).toMatchSnapshot();
});
});

View file

@ -5,29 +5,16 @@
*/
import { getHistogramInterval } from '../get_histogram_interval';
import { assertCloseTo } from '../assert_close_to';
describe('getHistogramInterval', () => {
it('specifies the interval necessary to divide a given timespan into equal buckets, rounded to the nearest integer, expressed in ms', () => {
const result = getHistogramInterval('now-15m', 'now', 10);
/**
* These assertions were verbatim comparisons but that introduced
* some flakiness at the ms resolution, sometimes values like "9001ms"
* are returned.
*/
expect(result.startsWith('9000')).toBeTruthy();
expect(result.endsWith('ms')).toBeTruthy();
expect(result).toHaveLength(7);
const interval = getHistogramInterval('now-15m', 'now', 10);
assertCloseTo(interval, 90000, 10);
});
it('will supply a default constant value for bucketCount when none is provided', () => {
const result = getHistogramInterval('now-15m', 'now');
/**
* These assertions were verbatim comparisons but that introduced
* some flakiness at the ms resolution, sometimes values like "9001ms"
* are returned.
*/
expect(result.startsWith('3600')).toBeTruthy();
expect(result.endsWith('ms')).toBeTruthy();
expect(result).toHaveLength(7);
const interval = getHistogramInterval('now-15m', 'now');
assertCloseTo(interval, 36000, 10);
});
});

View file

@ -0,0 +1,35 @@
/*
* 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 { getHistogramIntervalFormatted } from '../get_histogram_interval_formatted';
describe('getHistogramIntervalFormatted', () => {
it('specifies the interval necessary to divide a given timespan into equal buckets, rounded to the nearest integer, expressed in ms', () => {
const intervalFormatted = getHistogramIntervalFormatted('now-15m', 'now', 10);
/**
* Expected result is 90000.
* These assertions were verbatim comparisons but that introduced
* some flakiness at the ms resolution, sometimes values like "9001ms"
* are returned.
*/
expect(intervalFormatted.startsWith('9000')).toBeTruthy();
expect(intervalFormatted.endsWith('ms')).toBeTruthy();
expect(intervalFormatted).toHaveLength(7);
});
it('will supply a default constant value for bucketCount when none is provided', () => {
const intervalFormatted = getHistogramIntervalFormatted('now-15m', 'now');
/**
* Expected result is 36000.
* These assertions were verbatim comparisons but that introduced
* some flakiness at the ms resolution, sometimes values like "9001ms"
* are returned.
*/
expect(intervalFormatted.startsWith('3600')).toBeTruthy();
expect(intervalFormatted.endsWith('ms')).toBeTruthy();
expect(intervalFormatted).toHaveLength(7);
});
});

View file

@ -1,14 +0,0 @@
/*
* 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.
*/
/**
* We've had numerous requests to not display semi-full buckets (i.e. it is 13:01 and the
* bounds of our bucket are 13:00-13:05). If the first bucket isn't done filling, we'll
* start out with nothing returned, otherwise we drop the most recent bucket.
* @param buckets The bucket list
*/
export const dropLatestBucket = (buckets: any[]) =>
buckets.length > 1 ? buckets.slice(0, buckets.length - 1) : [];

View file

@ -1,42 +0,0 @@
/*
* 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 { UMESBucket, UMESHistogramBucket } from '../adapters/database';
import { dropLatestBucket } from './drop_latest_bucket';
/**
* The charting library we're currently using requires histogram data points have an
* x and an x0 property, where x0 is the beginning of a data point and x provides
* the size of the point from the start. This function attempts to generalize the
* concept so any bucket that has a numeric value as its key can be put into this format.
*
* Additionally, histograms that stack horizontally instead of vertically need to have
* a y and a y0 value. We're not doing this currently but with some minor modification
* this function could provide formatting for those buckets as well.
* @param buckets The ES data to format.
*/
export function formatEsBucketsForHistogram<T extends UMESBucket>(
buckets: T[]
): Array<T & UMESHistogramBucket> {
// wait for first bucket to fill up
if (buckets.length < 2) {
return [];
}
const TERMINAL_INDEX = buckets.length - 1;
const { key: terminalBucketTime } = buckets[TERMINAL_INDEX];
// drop the most recent bucket to avoid returning incomplete bucket
return dropLatestBucket(buckets).map((item, index, array) => {
const { key } = item;
const nextItem = array[index + 1];
const bucketSize = nextItem ? Math.abs(nextItem.key - key) : Math.abs(terminalBucketTime - key);
return {
x: key + bucketSize,
x0: key,
...item,
};
});
}

View file

@ -11,7 +11,7 @@ export const getHistogramInterval = (
dateRangeStart: string,
dateRangeEnd: string,
bucketCount?: number
): string => {
): number => {
const from = DateMath.parse(dateRangeStart);
const to = DateMath.parse(dateRangeEnd);
if (from === undefined) {
@ -20,7 +20,5 @@ export const getHistogramInterval = (
if (to === undefined) {
throw Error('Invalid dateRangeEnd value');
}
return `${Math.round(
(to.valueOf() - from.valueOf()) / (bucketCount || QUERY.DEFAULT_BUCKET_COUNT)
)}ms`;
return Math.round((to.valueOf() - from.valueOf()) / (bucketCount || QUERY.DEFAULT_BUCKET_COUNT));
};

View file

@ -0,0 +1,13 @@
/*
* 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 { getHistogramInterval } from './get_histogram_interval';
export const getHistogramIntervalFormatted = (
dateRangeStart: string,
dateRangeEnd: string,
bucketCount?: number
): string => `${getHistogramInterval(dateRangeStart, dateRangeEnd, bucketCount)}ms`;

View file

@ -4,9 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { dropLatestBucket } from './drop_latest_bucket';
export { formatEsBucketsForHistogram } from './format_es_buckets_for_histogram';
export { getFilterClause } from './get_filter_clause';
export { getHistogramInterval } from './get_histogram_interval';
export { getHistogramIntervalFormatted } from './get_histogram_interval_formatted';
export { parseFilterQuery } from './parse_filter_query';
export { assertCloseTo } from './assert_close_to';

View file

@ -103,6 +103,10 @@
{
"x": 1568173204510,
"y": null
},
{
"x": 1568173227311,
"y": 24627
}
]
}
@ -257,6 +261,12 @@
"up": null,
"down": null,
"total": 0
},
{
"x": 1568173227311,
"up": null,
"down": null,
"total": 1
}
],
"statusMaxCount": 0,

View file

@ -1,179 +1,188 @@
{
"histogram": [
{
"upCount": 93,
"downCount": 7,
"x": 1568172680087,
"x0": 1568172657286,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172702888,
"x0": 1568172680087,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172725689,
"x0": 1568172702888,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172748490,
"x0": 1568172725689,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172771291,
"x0": 1568172748490,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172794092,
"x0": 1568172771291,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172816893,
"x0": 1568172794092,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172839694,
"x0": 1568172816893,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172862495,
"x0": 1568172839694,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172885296,
"x0": 1568172862495,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172908097,
"x0": 1568172885296,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172930898,
"x0": 1568172908097,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172953699,
"x0": 1568172930898,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172976500,
"x0": 1568172953699,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172999301,
"x0": 1568172976500,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173022102,
"x0": 1568172999301,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173044903,
"x0": 1568173022102,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173067704,
"x0": 1568173044903,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173090505,
"x0": 1568173067704,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173113306,
"x0": 1568173090505,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173136107,
"x0": 1568173113306,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173158908,
"x0": 1568173136107,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568173181709,
"x0": 1568173158908,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173204510,
"x0": 1568173181709,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173227311,
"x0": 1568173204510,
"y": 1
}
]
"queryResult": {
"histogram": [
{
"upCount": 93,
"downCount": 7,
"x": 1568172657286,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172680087,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172702888,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172725689,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172748490,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172771291,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172794092,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172816893,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172839694,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172862495,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172885296,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172908097,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172930898,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172953699,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172976500,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172999301,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173022102,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173044903,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173067704,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173090505,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173113306,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173136107,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568173158908,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173181709,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173204510,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173227311,
"x0": null,
"y": 1
}
]
}
}

View file

@ -1,179 +1,188 @@
{
"histogram": [
{
"upCount": 93,
"downCount": 0,
"x": 1568172680087,
"x0": 1568172657286,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172702888,
"x0": 1568172680087,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172725689,
"x0": 1568172702888,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172748490,
"x0": 1568172725689,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172771291,
"x0": 1568172748490,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172794092,
"x0": 1568172771291,
"y": 1
},
{
"upCount": 92,
"downCount": 0,
"x": 1568172816893,
"x0": 1568172794092,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172839694,
"x0": 1568172816893,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172862495,
"x0": 1568172839694,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172885296,
"x0": 1568172862495,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172908097,
"x0": 1568172885296,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172930898,
"x0": 1568172908097,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172953699,
"x0": 1568172930898,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172976500,
"x0": 1568172953699,
"y": 1
},
{
"upCount": 92,
"downCount": 0,
"x": 1568172999301,
"x0": 1568172976500,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173022102,
"x0": 1568172999301,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173044903,
"x0": 1568173022102,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173067704,
"x0": 1568173044903,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173090505,
"x0": 1568173067704,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173113306,
"x0": 1568173090505,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173136107,
"x0": 1568173113306,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173158908,
"x0": 1568173136107,
"y": 1
},
{
"upCount": 92,
"downCount": 0,
"x": 1568173181709,
"x0": 1568173158908,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173204510,
"x0": 1568173181709,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173227311,
"x0": 1568173204510,
"y": 1
}
]
"queryResult": {
"histogram": [
{
"upCount": 93,
"downCount": 0,
"x": 1568172657286,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172680087,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172702888,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172725689,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172748490,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172771291,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 0,
"x": 1568172794092,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172816893,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172839694,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172862495,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172885296,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172908097,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172930898,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568172953699,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 0,
"x": 1568172976500,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172999301,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173022102,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173044903,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173067704,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173090505,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173113306,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173136107,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 0,
"x": 1568173158908,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173181709,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173204510,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 0,
"x": 1568173227311,
"x0": null,
"y": 1
}
]
}
}

View file

@ -1,179 +1,188 @@
{
"histogram": [
{
"upCount": 93,
"downCount": 7,
"x": 1568172680087,
"x0": 1568172657286,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172702888,
"x0": 1568172680087,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172725689,
"x0": 1568172702888,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172748490,
"x0": 1568172725689,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172771291,
"x0": 1568172748490,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172794092,
"x0": 1568172771291,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172816893,
"x0": 1568172794092,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172839694,
"x0": 1568172816893,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172862495,
"x0": 1568172839694,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172885296,
"x0": 1568172862495,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172908097,
"x0": 1568172885296,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172930898,
"x0": 1568172908097,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172953699,
"x0": 1568172930898,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172976500,
"x0": 1568172953699,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172999301,
"x0": 1568172976500,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173022102,
"x0": 1568172999301,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173044903,
"x0": 1568173022102,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173067704,
"x0": 1568173044903,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173090505,
"x0": 1568173067704,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173113306,
"x0": 1568173090505,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173136107,
"x0": 1568173113306,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173158908,
"x0": 1568173136107,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568173181709,
"x0": 1568173158908,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173204510,
"x0": 1568173181709,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173227311,
"x0": 1568173204510,
"y": 1
}
]
"queryResult": {
"histogram": [
{
"upCount": 93,
"downCount": 7,
"x": 1568172657286,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172680087,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172702888,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172725689,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172748490,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172771291,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172794092,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172816893,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172839694,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172862495,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172885296,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172908097,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172930898,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568172953699,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568172976500,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568172999301,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173022102,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173044903,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173067704,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173090505,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173113306,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173136107,
"x0": null,
"y": 1
},
{
"upCount": 92,
"downCount": 8,
"x": 1568173158908,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173181709,
"x0": null,
"y": 1
},
{
"upCount": 0,
"downCount": 0,
"x": 1568173204510,
"x0": null,
"y": 1
},
{
"upCount": 93,
"downCount": 7,
"x": 1568173227311,
"x0": null,
"y": 1
}
]
}
}

View file

@ -7,6 +7,7 @@
import { snapshotHistogramQueryString } from '../../../../../legacy/plugins/uptime/public/queries/snapshot_histogram_query';
import { expectFixtureEql } from './helpers/expect_fixture_eql';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { assertCloseTo } from '../../../../../legacy/plugins/uptime/server/lib/helper';
export default function({ getService }: FtrProviderContext) {
describe('snapshotHistogram', () => {
@ -31,6 +32,10 @@ export default function({ getService }: FtrProviderContext) {
.post('/api/uptime/graphql')
.set('kbn-xsrf', 'foo')
.send({ ...getSnapshotHistogramQuery });
// manually testing this value and then removing it to avoid flakiness
const { interval } = data.queryResult;
assertCloseTo(interval, 22801, 100);
delete data.queryResult.interval;
expectFixtureEql(data, 'snapshot_histogram');
});
@ -50,6 +55,9 @@ export default function({ getService }: FtrProviderContext) {
.post('/api/uptime/graphql')
.set('kbn-xsrf', 'foo')
.send({ ...getSnapshotHistogramQuery });
const { interval } = data.queryResult;
assertCloseTo(interval, 22801, 100);
delete data.queryResult.interval;
expectFixtureEql(data, 'snapshot_histogram_by_id');
});
@ -71,6 +79,9 @@ export default function({ getService }: FtrProviderContext) {
.post('/api/uptime/graphql')
.set('kbn-xsrf', 'foo')
.send({ ...getSnapshotHistogramQuery });
const { interval } = data.queryResult;
assertCloseTo(interval, 22801, 100);
delete data.queryResult.interval;
expectFixtureEql(data, 'snapshot_histogram_by_filter');
});
});