Skip to content

Commit 4dcf719

Browse files
Adding api test for transaction_groups /breakdown and /avg_duration_by_browser (#72623)
* adding api test for transaction_groups /breakdown and /avg_duration_by_browser * adding filter by transaction name * adding filter by transaction name * addressing pr comments * fixing TS issue Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent a41633d commit 4dcf719

File tree

10 files changed

+1855
-2
lines changed

10 files changed

+1855
-2
lines changed

x-pack/plugins/apm/server/lib/transactions/avg_duration_by_browser/fetcher.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
TRANSACTION_TYPE,
1313
USER_AGENT_NAME,
1414
TRANSACTION_DURATION,
15+
TRANSACTION_NAME,
1516
} from '../../../../common/elasticsearch_fieldnames';
1617
import { rangeFilter } from '../../../../common/utils/range_filter';
1718
import { getBucketSize } from '../../helpers/get_bucket_size';
@@ -23,15 +24,20 @@ export type ESResponse = PromiseReturnType<typeof fetcher>;
2324

2425
export function fetcher(options: Options) {
2526
const { end, client, indices, start, uiFiltersES } = options.setup;
26-
const { serviceName } = options;
27+
const { serviceName, transactionName } = options;
2728
const { intervalString } = getBucketSize(start, end, 'auto');
2829

30+
const transactionNameFilter = transactionName
31+
? [{ term: { [TRANSACTION_NAME]: transactionName } }]
32+
: [];
33+
2934
const filter: ESFilter[] = [
3035
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
3136
{ term: { [SERVICE_NAME]: serviceName } },
3237
{ term: { [TRANSACTION_TYPE]: TRANSACTION_PAGE_LOAD } },
3338
{ range: rangeFilter(start, end) },
3439
...uiFiltersES,
40+
...transactionNameFilter,
3541
];
3642

3743
const params = {

x-pack/plugins/apm/server/lib/transactions/avg_duration_by_browser/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { transformer } from './transformer';
1616
export interface Options {
1717
serviceName: string;
1818
setup: Setup & SetupTimeRange & SetupUIFilters;
19+
transactionName?: string;
1920
}
2021

2122
export type AvgDurationByBrowserAPIResponse = Array<{

x-pack/plugins/apm/server/routes/transaction_groups.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ export const transactionGroupsAvgDurationByBrowser = createRoute(() => ({
164164
}),
165165
query: t.intersection([
166166
t.partial({
167-
transactionType: t.string,
168167
transactionName: t.string,
169168
}),
170169
uiFiltersRt,
@@ -174,10 +173,12 @@ export const transactionGroupsAvgDurationByBrowser = createRoute(() => ({
174173
handler: async ({ context, request }) => {
175174
const setup = await setupRequest(context, request);
176175
const { serviceName } = context.params.path;
176+
const { transactionName } = context.params.query;
177177

178178
return getTransactionAvgDurationByBrowser({
179179
serviceName,
180180
setup,
181+
transactionName,
181182
});
182183
},
183184
}));

x-pack/test/apm_api_integration/basic/tests/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export default function apmApiIntegrationTests({ loadTestFile }: FtrProviderCont
3535
loadTestFile(require.resolve('./transaction_groups/top_transaction_groups'));
3636
loadTestFile(require.resolve('./transaction_groups/transaction_charts'));
3737
loadTestFile(require.resolve('./transaction_groups/error_rate'));
38+
loadTestFile(require.resolve('./transaction_groups/breakdown'));
39+
loadTestFile(require.resolve('./transaction_groups/avg_duration_by_browser'));
3840
});
3941

4042
describe('Observability overview', function () {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import expect from '@kbn/expect';
7+
import { FtrProviderContext } from '../../../common/ftr_provider_context';
8+
import expectedAvgDurationByBrowser from './expectation/avg_duration_by_browser.json';
9+
import expectedAvgDurationByBrowserWithTransactionName from './expectation/avg_duration_by_browser_transaction_name.json';
10+
11+
export default function ApiTest({ getService }: FtrProviderContext) {
12+
const supertest = getService('supertest');
13+
const esArchiver = getService('esArchiver');
14+
15+
const start = encodeURIComponent('2020-06-29T06:45:00.000Z');
16+
const end = encodeURIComponent('2020-06-29T06:49:00.000Z');
17+
const transactionName = '/products';
18+
const uiFilters = encodeURIComponent(JSON.stringify({}));
19+
20+
describe('Average duration by browser', () => {
21+
describe('when data is not loaded', () => {
22+
it('handles the empty state', async () => {
23+
const response = await supertest.get(
24+
`/api/apm/services/client/transaction_groups/avg_duration_by_browser?start=${start}&end=${end}&uiFilters=${uiFilters}`
25+
);
26+
expect(response.status).to.be(200);
27+
expect(response.body).to.eql([]);
28+
});
29+
});
30+
31+
describe('when data is loaded', () => {
32+
before(() => esArchiver.load('8.0.0'));
33+
after(() => esArchiver.unload('8.0.0'));
34+
35+
it('returns the average duration by browser', async () => {
36+
const response = await supertest.get(
37+
`/api/apm/services/client/transaction_groups/avg_duration_by_browser?start=${start}&end=${end}&uiFilters=${uiFilters}`
38+
);
39+
40+
expect(response.status).to.be(200);
41+
expect(response.body).to.eql(expectedAvgDurationByBrowser);
42+
});
43+
it('returns the average duration by browser filtering by transaction name', async () => {
44+
const response = await supertest.get(
45+
`/api/apm/services/client/transaction_groups/avg_duration_by_browser?start=${start}&end=${end}&uiFilters=${uiFilters}&transactionName=${transactionName}`
46+
);
47+
48+
expect(response.status).to.be(200);
49+
expect(response.body).to.eql(expectedAvgDurationByBrowserWithTransactionName);
50+
});
51+
});
52+
});
53+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import expect from '@kbn/expect';
7+
import { FtrProviderContext } from '../../../common/ftr_provider_context';
8+
import expectedBreakdown from './expectation/breakdown.json';
9+
import expectedBreakdownWithTransactionName from './expectation/breakdown_transaction_name.json';
10+
11+
export default function ApiTest({ getService }: FtrProviderContext) {
12+
const supertest = getService('supertest');
13+
const esArchiver = getService('esArchiver');
14+
15+
const start = encodeURIComponent('2020-06-29T06:45:00.000Z');
16+
const end = encodeURIComponent('2020-06-29T06:49:00.000Z');
17+
const transactionType = 'request';
18+
const transactionName = 'GET /api';
19+
const uiFilters = encodeURIComponent(JSON.stringify({}));
20+
21+
describe('Breakdown', () => {
22+
describe('when data is not loaded', () => {
23+
it('handles the empty state', async () => {
24+
const response = await supertest.get(
25+
`/api/apm/services/opbeans-node/transaction_groups/breakdown?start=${start}&end=${end}&uiFilters=${uiFilters}&transactionType=${transactionType}`
26+
);
27+
expect(response.status).to.be(200);
28+
expect(response.body).to.eql({ kpis: [], timeseries: [] });
29+
});
30+
});
31+
32+
describe('when data is loaded', () => {
33+
before(() => esArchiver.load('8.0.0'));
34+
after(() => esArchiver.unload('8.0.0'));
35+
36+
it('returns the transaction breakdown for a service', async () => {
37+
const response = await supertest.get(
38+
`/api/apm/services/opbeans-node/transaction_groups/breakdown?start=${start}&end=${end}&uiFilters=${uiFilters}&transactionType=${transactionType}`
39+
);
40+
41+
expect(response.status).to.be(200);
42+
expect(response.body).to.eql(expectedBreakdown);
43+
});
44+
it('returns the transaction breakdown for a transaction group', async () => {
45+
const response = await supertest.get(
46+
`/api/apm/services/opbeans-node/transaction_groups/breakdown?start=${start}&end=${end}&uiFilters=${uiFilters}&transactionType=${transactionType}&transactionName=${transactionName}`
47+
);
48+
49+
expect(response.status).to.be(200);
50+
expect(response.body).to.eql(expectedBreakdownWithTransactionName);
51+
});
52+
it('returns the top 4 by percentage and sorts them by name', async () => {
53+
const response = await supertest.get(
54+
`/api/apm/services/opbeans-node/transaction_groups/breakdown?start=${start}&end=${end}&uiFilters=${uiFilters}&transactionType=${transactionType}`
55+
);
56+
57+
expect(response.status).to.be(200);
58+
expect(response.body.kpis.map((kpi: { name: string }) => kpi.name)).to.eql([
59+
'app',
60+
'http',
61+
'postgresql',
62+
'redis',
63+
]);
64+
});
65+
});
66+
});
67+
}

0 commit comments

Comments
 (0)