Skip to content

Commit

Permalink
Improve mobile API tests (#156578)
Browse files Browse the repository at this point in the history
There were some comments regarding the api test done for the mobile
transactions main and detailed statistics as part of this
[PR](#153044)

### Summary
- add value specific test not just check if the response is empty
(detailed statistics timeseries test)
- calculate values based on the inputs for generating data, instead of
like snapshot testing (throughput)

This PR also contains the fixes for the following failing skipped tests 
- #156207
- #156218
  • Loading branch information
MiriamAparicio authored May 16, 2023
1 parent 927743a commit b35265b
Show file tree
Hide file tree
Showing 5 changed files with 552 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ export default function ApiTest({ getService }: FtrProviderContext) {
environment: 'production',
field: 'service.version',
});
expect(isEmpty(response.currentPeriod)).to.be.equal(false);

expect(Object.keys(response.currentPeriod)).to.be.eql(['2.3', '1.1', '1.2']);
expect(isEmpty(response.previousPeriod)).to.be.equal(true);
});
});
Expand All @@ -110,8 +111,12 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});
it('returns some data for both periods', async () => {
expect(isEmpty(mobiledetailedStatisticResponse.currentPeriod)).to.be.equal(false);
expect(isEmpty(mobiledetailedStatisticResponse.previousPeriod)).to.be.equal(false);
expect(Object.keys(mobiledetailedStatisticResponse.currentPeriod).sort()).to.be.eql(
SERVICE_VERSIONS.sort()
);
expect(Object.keys(mobiledetailedStatisticResponse.previousPeriod).sort()).to.be.eql(
SERVICE_VERSIONS.sort()
);
});

it('returns same number of buckets for both periods', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,173 @@
*/

import expect from '@kbn/expect';
import { apm, timerange } from '@kbn/apm-synthtrace-client';
import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace';
import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api';
import { ENVIRONMENT_ALL } from '@kbn/apm-plugin/common/environment_filter_values';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { generateMobileData } from './generate_mobile_data';

type MobileLocationStats =
APIReturnType<'GET /internal/apm/mobile-services/{serviceName}/location/stats'>;

// we generate 3 transactions per each mobile device
// timerange 15min, interval 5m, rate 1
// generate 3 http spans for galaxy10 device

async function generateData({
start,
end,
synthtraceEsClient,
}: {
start: number;
end: number;
synthtraceEsClient: ApmSynthtraceEsClient;
}) {
const galaxy10 = apm
.mobileApp({
name: 'synth-android',
environment: 'production',
agentName: 'android/java',
})
.mobileDevice({ serviceVersion: '1.1' })
.deviceInfo({
manufacturer: 'Samsung',
modelIdentifier: 'SM-G973F',
modelName: 'Galaxy S10',
})
.osInfo({
osType: 'android',
osVersion: '10',
osFull: 'Android 10, API level 29, BUILD A022MUBU2AUD1',
runtimeVersion: '2.1.0',
})
.setGeoInfo({
clientIp: '223.72.43.22',
cityName: 'Beijing',
continentName: 'Asia',
countryIsoCode: 'CN',
countryName: 'China',
regionIsoCode: 'CN-BJ',
regionName: 'Beijing',
location: { coordinates: [116.3861, 39.9143], type: 'Point' },
})
.setNetworkConnection({ type: 'wifi' });

const galaxy7 = apm
.mobileApp({
name: 'synth-android',
environment: 'production',
agentName: 'android/java',
})
.mobileDevice({ serviceVersion: '1.2' })
.deviceInfo({
manufacturer: 'Samsung',
modelIdentifier: 'SM-G930F',
modelName: 'Galaxy S7',
})
.osInfo({
osType: 'android',
osVersion: '10',
osFull: 'Android 10, API level 29, BUILD A022MUBU2AUD1',
runtimeVersion: '2.1.0',
})
.setGeoInfo({
clientIp: '223.72.43.22',
cityName: 'Beijing',
continentName: 'Asia',
countryIsoCode: 'CN',
countryName: 'China',
regionIsoCode: 'CN-BJ',
regionName: 'Beijing',
location: { coordinates: [116.3861, 39.9143], type: 'Point' },
})
.setNetworkConnection({
type: 'cell',
subType: 'edge',
carrierName: 'M1 Limited',
carrierMNC: '03',
carrierICC: 'SG',
carrierMCC: '525',
});

const huaweiP2 = apm
.mobileApp({
name: 'synth-android',
environment: 'production',
agentName: 'android/java',
})
.mobileDevice({ serviceVersion: '2.3' })
.deviceInfo({
manufacturer: 'Huawei',
modelIdentifier: 'HUAWEI P2-0000',
modelName: 'HuaweiP2',
})
.osInfo({
osType: 'android',
osVersion: '11',
osFull: 'Android 10, API level 29, BUILD A022MUBU2AUD1',
runtimeVersion: '2.1.0',
})
.setGeoInfo({
clientIp: '20.24.184.101',
cityName: 'Singapore',
continentName: 'Asia',
countryIsoCode: 'SG',
countryName: 'Singapore',
location: { coordinates: [103.8554, 1.3036], type: 'Point' },
})
.setNetworkConnection({
type: 'cell',
subType: 'edge',
carrierName: 'Osaka Gas Business Create Co., Ltd.',
carrierMNC: '17',
carrierICC: 'JP',
carrierMCC: '440',
});

return await synthtraceEsClient.index([
timerange(start, end)
.interval('5m')
.rate(1)
.generator((timestamp) => {
galaxy10.startNewSession();
galaxy7.startNewSession();
huaweiP2.startNewSession();
return [
galaxy10
.transaction('Start View - View Appearing', 'Android Activity')
.errors(galaxy10.crash({ message: 'error' }).timestamp(timestamp))
.timestamp(timestamp)
.duration(500)
.success()
.children(
galaxy10
.httpSpan({
spanName: 'GET backend:1234',
httpMethod: 'GET',
httpUrl: 'https://backend:1234/api/start',
})
.duration(800)
.success()
.timestamp(timestamp + 400)
),
galaxy7
.transaction('Start View - View Appearing', 'Android Activity')
.errors(galaxy7.crash({ message: 'error' }).timestamp(timestamp))
.timestamp(timestamp)
.duration(20)
.success(),
huaweiP2
.transaction('Start View - View Appearing', 'huaweiP2 Activity')
.errors(huaweiP2.crash({ message: 'error' }).timestamp(timestamp))
.timestamp(timestamp)
.duration(20)
.success(),
];
}),
]);
}

export default function ApiTest({ getService }: FtrProviderContext) {
const apmApiClient = getService('apmApiClient');
const registry = getService('registry');
Expand Down Expand Up @@ -66,7 +225,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {

registry.when('Location stats', { config: 'basic', archives: [] }, () => {
before(async () => {
await generateMobileData({
await generateData({
synthtraceEsClient,
start,
end,
Expand Down Expand Up @@ -96,9 +255,8 @@ export default function ApiTest({ getService }: FtrProviderContext) {
});
});

// FAILING: https://github.com/elastic/kibana/issues/156207
describe.skip('when filters are applied', () => {
it('returns empty state for filters', async () => {
describe('when filters are applied', () => {
it('returns empty state for filters with no results', async () => {
const response = await getMobileLocationStats({
serviceName: 'synth-android',
environment: 'production',
Expand All @@ -120,21 +278,21 @@ export default function ApiTest({ getService }: FtrProviderContext) {
const response = await getMobileLocationStats({
serviceName: 'synth-android',
environment: 'production',
kuery: `service.version:"2.3"`,
kuery: `service.version:"1.1"`,
});

expect(response.currentPeriod.mostSessions.value).to.eql(12);
expect(response.currentPeriod.mostRequests.value).to.eql(0);
expect(response.currentPeriod.mostSessions.value).to.eql(3);
expect(response.currentPeriod.mostRequests.value).to.eql(3);
});

it('returns the correct values when multiple filters are applied', async () => {
const response = await getMobileLocationStats({
serviceName: 'synth-android',
kuery: `service.version:"2.3" and service.environment: "production"`,
kuery: `service.version:"1.1" and service.environment: "production"`,
});

expect(response.currentPeriod.mostSessions.value).to.eql(12);
expect(response.currentPeriod.mostRequests.value).to.eql(0);
expect(response.currentPeriod.mostSessions.value).to.eql(3);
expect(response.currentPeriod.mostRequests.value).to.eql(3);
});
});
});
Expand Down
Loading

0 comments on commit b35265b

Please sign in to comment.