diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx index e17a8046b5c6a..6c5b539fcecfa 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx @@ -119,7 +119,7 @@ export function PageLoadDistChart({ xScaleType={ScaleType.Linear} yScaleType={ScaleType.Linear} data={data?.pageLoadDistribution ?? []} - curve={CurveType.CURVE_NATURAL} + curve={CurveType.CURVE_CATMULL_ROM} /> {breakdowns.map(({ name, type }) => ( ): LineAnnotationDatum[] { return Object.entries(values ?? {}).map((value) => ({ - dataValue: Math.round(value[1] / 1000), + dataValue: value[1], details: `${(+value[0]).toFixed(0)}`, })); } diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx index 7d48cee49b104..81503e16f7bcf 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx @@ -68,7 +68,7 @@ export const PageLoadDistribution = () => { ); const onPercentileChange = (min: number, max: number) => { - setPercentileRange({ min: min * 1000, max: max * 1000 }); + setPercentileRange({ min, max }); }; return ( diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx index 3ddaa66b8de5e..3380a81c7bfab 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx @@ -46,7 +46,7 @@ export function RumOverview() { (callApmApi) => { if (start && end) { return callApmApi({ - pathname: '/api/apm/services', + pathname: '/api/apm/rum-client/services', params: { query: { start, @@ -68,11 +68,7 @@ export function RumOverview() { {!isRumServiceRoute && ( <> - service.serviceName) ?? [] - } - /> + {' '} diff --git a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap index c006d01637483..602eb88ba8940 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap @@ -70,6 +70,9 @@ Object { "durPercentiles": Object { "percentiles": Object { "field": "transaction.duration.us", + "hdr": Object { + "number_of_significant_value_digits": 3, + }, "percents": Array [ 50, 75, @@ -179,3 +182,55 @@ Object { "index": "myIndex", } `; + +exports[`rum client dashboard queries fetches rum services 1`] = ` +Object { + "body": Object { + "aggs": Object { + "services": Object { + "terms": Object { + "field": "service.name", + "size": 1000, + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "range": Object { + "@timestamp": Object { + "format": "epoch_millis", + "gte": 1528113600000, + "lte": 1528977600000, + }, + }, + }, + Object { + "term": Object { + "processor.event": "transaction", + }, + }, + Object { + "term": Object { + "transaction.type": "page-load", + }, + }, + Object { + "exists": Object { + "field": "transaction.marks.navigationTiming.fetchStart", + }, + }, + Object { + "term": Object { + "my.custom.ui.filter": "foo-bar", + }, + }, + ], + }, + }, + "size": 0, + }, + "index": "myIndex", +} +`; diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts index 43af18999547d..e847a87264759 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts @@ -12,6 +12,12 @@ import { SetupUIFilters, } from '../helpers/setup_request'; +export const MICRO_TO_SEC = 1000000; + +export function microToSec(val: number) { + return Math.round((val / MICRO_TO_SEC + Number.EPSILON) * 100) / 100; +} + export async function getPageLoadDistribution({ setup, minPercentile, @@ -42,6 +48,9 @@ export async function getPageLoadDistribution({ percentiles: { field: 'transaction.duration.us', percents: [50, 75, 90, 95, 99], + hdr: { + number_of_significant_value_digits: 3, + }, }, }, }, @@ -59,20 +68,29 @@ export async function getPageLoadDistribution({ return null; } - const minDuration = aggregations?.minDuration.value ?? 0; + const { durPercentiles, minDuration } = aggregations ?? {}; - const minPerc = minPercentile ? +minPercentile : minDuration; + const minPerc = minPercentile + ? +minPercentile * MICRO_TO_SEC + : minDuration?.value ?? 0; - const maxPercQuery = aggregations?.durPercentiles.values['99.0'] ?? 10000; + const maxPercQuery = durPercentiles?.values['99.0'] ?? 10000; - const maxPerc = maxPercentile ? +maxPercentile : maxPercQuery; + const maxPerc = maxPercentile ? +maxPercentile * MICRO_TO_SEC : maxPercQuery; const pageDist = await getPercentilesDistribution(setup, minPerc, maxPerc); + + Object.entries(durPercentiles?.values ?? {}).forEach(([key, val]) => { + if (durPercentiles?.values?.[key]) { + durPercentiles.values[key] = microToSec(val as number); + } + }); + return { pageLoadDistribution: pageDist, - percentiles: aggregations?.durPercentiles.values, - minDuration: minPerc, - maxDuration: maxPerc, + percentiles: durPercentiles?.values, + minDuration: microToSec(minPerc), + maxDuration: microToSec(maxPerc), }; } @@ -81,9 +99,9 @@ const getPercentilesDistribution = async ( minDuration: number, maxDuration: number ) => { - const stepValue = (maxDuration - minDuration) / 50; + const stepValue = (maxDuration - minDuration) / 100; const stepValues = []; - for (let i = 1; i < 51; i++) { + for (let i = 1; i < 101; i++) { stepValues.push((stepValue * i + minDuration).toFixed(2)); } @@ -103,6 +121,9 @@ const getPercentilesDistribution = async ( field: 'transaction.duration.us', values: stepValues, keyed: false, + hdr: { + number_of_significant_value_digits: 3, + }, }, }, }, @@ -117,7 +138,7 @@ const getPercentilesDistribution = async ( return pageDist.map(({ key, value }, index: number, arr) => { return { - x: Math.round(key / 1000), + x: microToSec(key), y: index === 0 ? value : value - arr[index - 1].value, }; }); diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts b/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts index 5ae6bd1540f7c..ea9d701e64c3d 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts @@ -17,6 +17,7 @@ import { USER_AGENT_NAME, USER_AGENT_OS, } from '../../../common/elasticsearch_fieldnames'; +import { MICRO_TO_SEC, microToSec } from './get_page_load_distribution'; export const getBreakdownField = (breakdown: string) => { switch (breakdown) { @@ -38,7 +39,9 @@ export const getPageLoadDistBreakdown = async ( maxDuration: number, breakdown: string ) => { - const stepValue = (maxDuration - minDuration) / 50; + // convert secs to micros + const stepValue = + (maxDuration * MICRO_TO_SEC - minDuration * MICRO_TO_SEC) / 50; const stepValues = []; for (let i = 1; i < 51; i++) { @@ -67,6 +70,9 @@ export const getPageLoadDistBreakdown = async ( field: 'transaction.duration.us', values: stepValues, keyed: false, + hdr: { + number_of_significant_value_digits: 3, + }, }, }, }, @@ -86,7 +92,7 @@ export const getPageLoadDistBreakdown = async ( name: String(key), data: pageDist.values?.map(({ key: pKey, value }, index: number, arr) => { return { - x: Math.round(pKey / 1000), + x: microToSec(pKey), y: index === 0 ? value : value - arr[index - 1].value, }; }), diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts b/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts new file mode 100644 index 0000000000000..5957a25239307 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts @@ -0,0 +1,48 @@ +/* + * 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 { getRumOverviewProjection } from '../../../common/projections/rum_overview'; +import { mergeProjection } from '../../../common/projections/util/merge_projection'; +import { + Setup, + SetupTimeRange, + SetupUIFilters, +} from '../helpers/setup_request'; + +export async function getRumServices({ + setup, +}: { + setup: Setup & SetupTimeRange & SetupUIFilters; +}) { + const projection = getRumOverviewProjection({ + setup, + }); + + const params = mergeProjection(projection, { + body: { + size: 0, + query: { + bool: projection.body.query.bool, + }, + aggs: { + services: { + terms: { + field: 'service.name', + size: 1000, + }, + }, + }, + }, + }); + + const { client } = setup; + + const response = await client.search(params); + + const result = response.aggregations?.services.buckets ?? []; + + return result.map(({ key }) => key as string); +} diff --git a/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts b/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts index 5f5a48eced746..37432672c5d89 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/queries.test.ts @@ -11,6 +11,7 @@ import { import { getClientMetrics } from './get_client_metrics'; import { getPageViewTrends } from './get_page_view_trends'; import { getPageLoadDistribution } from './get_page_load_distribution'; +import { getRumServices } from './get_rum_services'; describe('rum client dashboard queries', () => { let mock: SearchParamsMock; @@ -49,4 +50,13 @@ describe('rum client dashboard queries', () => { ); expect(mock.params).toMatchSnapshot(); }); + + it('fetches rum services', async () => { + mock = await inspectSearchParams((setup) => + getRumServices({ + setup, + }) + ); + expect(mock.params).toMatchSnapshot(); + }); }); diff --git a/x-pack/plugins/apm/server/routes/create_apm_api.ts b/x-pack/plugins/apm/server/routes/create_apm_api.ts index c314debcd8049..513c44904683e 100644 --- a/x-pack/plugins/apm/server/routes/create_apm_api.ts +++ b/x-pack/plugins/apm/server/routes/create_apm_api.ts @@ -76,6 +76,7 @@ import { rumPageViewsTrendRoute, rumPageLoadDistributionRoute, rumPageLoadDistBreakdownRoute, + rumServicesRoute, } from './rum_client'; import { observabilityDashboardHasDataRoute, @@ -172,6 +173,7 @@ const createApmApi = () => { .add(rumPageLoadDistributionRoute) .add(rumPageLoadDistBreakdownRoute) .add(rumClientMetricsRoute) + .add(rumServicesRoute) // Observability dashboard .add(observabilityDashboardHasDataRoute) diff --git a/x-pack/plugins/apm/server/routes/rum_client.ts b/x-pack/plugins/apm/server/routes/rum_client.ts index 75651f646a50d..01e549632a0bc 100644 --- a/x-pack/plugins/apm/server/routes/rum_client.ts +++ b/x-pack/plugins/apm/server/routes/rum_client.ts @@ -12,6 +12,7 @@ import { rangeRt, uiFiltersRt } from './default_api_types'; import { getPageViewTrends } from '../lib/rum_client/get_page_view_trends'; import { getPageLoadDistribution } from '../lib/rum_client/get_page_load_distribution'; import { getPageLoadDistBreakdown } from '../lib/rum_client/get_pl_dist_breakdown'; +import { getRumServices } from '../lib/rum_client/get_rum_services'; export const percentileRangeRt = t.partial({ minPercentile: t.string, @@ -91,3 +92,15 @@ export const rumPageViewsTrendRoute = createRoute(() => ({ return getPageViewTrends({ setup, breakdowns }); }, })); + +export const rumServicesRoute = createRoute(() => ({ + path: '/api/apm/rum-client/services', + params: { + query: t.intersection([uiFiltersRt, rangeRt]), + }, + handler: async ({ context, request }) => { + const setup = await setupRequest(context, request); + + return getRumServices({ setup }); + }, +})); diff --git a/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts b/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts index a340aa24aebfb..ac7499c23e926 100644 --- a/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts +++ b/x-pack/plugins/apm/typings/elasticsearch/aggregations.ts @@ -150,6 +150,7 @@ export interface AggregationOptionsByType { field: string; values: string[]; keyed?: boolean; + hdr?: { number_of_significant_value_digits: number }; }; } diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/data.json.gz b/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/data.json.gz new file mode 100644 index 0000000000000..ad3f2351ed30a Binary files /dev/null and b/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/data.json.gz differ diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/mappings.json b/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/mappings.json new file mode 100644 index 0000000000000..48ac74d97dfa7 --- /dev/null +++ b/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/mappings.json @@ -0,0 +1,600 @@ +{ + "type": "index", + "value": { + "aliases": { + }, + "index": "apm-8.0.0-transaction-005", + "mappings": { + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "properties": { + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "version": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "client": { + "properties": { + "geo": { + "properties": { + "continent_name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "country_iso_code": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "location": { + "properties": { + "lat": { + "type": "float" + }, + "lon": { + "type": "float" + } + } + } + } + }, + "ip": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "ecs": { + "properties": { + "version": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "event": { + "properties": { + "ingested": { + "type": "date" + } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "referrer": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "response": { + "properties": { + "decoded_body_size": { + "type": "long" + }, + "encoded_body_size": { + "type": "long" + }, + "transfer_size": { + "type": "long" + } + } + } + } + }, + "observer": { + "properties": { + "ephemeral_id": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "hostname": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "id": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "type": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "version": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "version_major": { + "type": "long" + } + } + }, + "processor": { + "properties": { + "event": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "service": { + "properties": { + "language": { + "properties": { + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "version": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "source": { + "properties": { + "ip": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "trace": { + "properties": { + "id": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "transaction": { + "properties": { + "custom": { + "properties": { + "userConfig": { + "properties": { + "featureFlags": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "showDashboard": { + "type": "boolean" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "marks": { + "properties": { + "agent": { + "properties": { + "domComplete": { + "type": "long" + }, + "domInteractive": { + "type": "long" + }, + "firstContentfulPaint": { + "type": "float" + }, + "largestContentfulPaint": { + "type": "float" + }, + "timeToFirstByte": { + "type": "long" + } + } + }, + "navigationTiming": { + "properties": { + "connectEnd": { + "type": "long" + }, + "connectStart": { + "type": "long" + }, + "domComplete": { + "type": "long" + }, + "domContentLoadedEventEnd": { + "type": "long" + }, + "domContentLoadedEventStart": { + "type": "long" + }, + "domInteractive": { + "type": "long" + }, + "domLoading": { + "type": "long" + }, + "domainLookupEnd": { + "type": "long" + }, + "domainLookupStart": { + "type": "long" + }, + "fetchStart": { + "type": "long" + }, + "loadEventEnd": { + "type": "long" + }, + "loadEventStart": { + "type": "long" + }, + "requestStart": { + "type": "long" + }, + "responseEnd": { + "type": "long" + }, + "responseStart": { + "type": "long" + } + } + } + } + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "page": { + "properties": { + "referer": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "url": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "sampled": { + "type": "boolean" + }, + "span_count": { + "properties": { + "started": { + "type": "long" + } + } + }, + "type": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "url": { + "properties": { + "domain": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "full": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "original": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "path": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "port": { + "type": "long" + }, + "scheme": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "user": { + "properties": { + "email": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "id": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "user_agent": { + "properties": { + "device": { + "properties": { + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "original": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "os": { + "properties": { + "full": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "version": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "version": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + } + } + }, + "settings": { + "index": { + "number_of_replicas": "1", + "number_of_shards": "1" + } + } + } +} diff --git a/x-pack/test/apm_api_integration/trial/tests/index.ts b/x-pack/test/apm_api_integration/trial/tests/index.ts index 1a00f7e2df9e8..37328badcb794 100644 --- a/x-pack/test/apm_api_integration/trial/tests/index.ts +++ b/x-pack/test/apm_api_integration/trial/tests/index.ts @@ -11,5 +11,6 @@ export default function observabilityApiIntegrationTests({ loadTestFile }: FtrPr this.tags('ciGroup1'); loadTestFile(require.resolve('./annotations')); loadTestFile(require.resolve('./service_maps')); + loadTestFile(require.resolve('./rum_services')); }); } diff --git a/x-pack/test/apm_api_integration/trial/tests/rum_services.ts b/x-pack/test/apm_api_integration/trial/tests/rum_services.ts new file mode 100644 index 0000000000000..5505387de54a7 --- /dev/null +++ b/x-pack/test/apm_api_integration/trial/tests/rum_services.ts @@ -0,0 +1,47 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +export default function rumServicesApiTests({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + describe('RUM Services', () => { + describe('when there is no data', () => { + it('returns empty list', async () => { + const response = await supertest.get( + '/api/apm/rum-client/services?start=2020-06-28T10%3A24%3A46.055Z&end=2020-07-29T10%3A24%3A46.055Z&uiFilters=%7B%22agentName%22%3A%5B%22js-base%22%2C%22rum-js%22%5D%7D' + ); + + expect(response.status).to.be(200); + expect(response.body).to.eql([]); + }); + }); + + describe('when there is data', () => { + before(async () => { + await esArchiver.load('8.0.0'); + await esArchiver.load('rum_8.0.0'); + }); + after(async () => { + await esArchiver.unload('8.0.0'); + await esArchiver.unload('rum_8.0.0'); + }); + + it('returns rum services list', async () => { + const response = await supertest.get( + '/api/apm/rum-client/services?start=2020-06-28T10%3A24%3A46.055Z&end=2020-07-29T10%3A24%3A46.055Z&uiFilters=%7B%22agentName%22%3A%5B%22js-base%22%2C%22rum-js%22%5D%7D' + ); + + expect(response.status).to.be(200); + + expect(response.body).to.eql(['client', 'opbean-client-rum']); + }); + }); + }); +}