diff --git a/x-pack/test/api_integration/apis/metrics_ui/helpers.ts b/x-pack/test/api_integration/apis/metrics_ui/helpers.ts index 0b97e91eba5fd..b5375b8d70cab 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/helpers.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/helpers.ts @@ -10,6 +10,7 @@ import { SuperTest, Test } from 'supertest'; export type KibanaSupertest = SuperTest; +// generates traces, metrics for services export function generateServicesData({ from, to, @@ -22,7 +23,6 @@ export function generateServicesData({ servicesPerHost?: number; }) { const range = timerange(from, to); - const services = Array(instanceCount) .fill(null) .flatMap((_, hostIdx) => @@ -51,3 +51,40 @@ export function generateServicesData({ ) ); } +// generates error logs only for services +export function generateServicesLogsOnlyData({ + from, + to, + instanceCount = 1, + servicesPerHost = 1, +}: { + from: string; + to: string; + instanceCount?: number; + servicesPerHost?: number; +}) { + const range = timerange(from, to); + const services = Array(instanceCount) + .fill(null) + .flatMap((_, hostIdx) => + Array(servicesPerHost) + .fill(null) + .map((__, serviceIdx) => + apm + .service({ + name: `service-${hostIdx}-${serviceIdx}`, + environment: 'production', + agentName: 'go', + }) + .instance(`host-${hostIdx}`) + ) + ); + return range + .interval('1m') + .rate(1) + .generator((timestamp, index) => + services.map((service) => + service.error({ message: 'error', type: 'My Type' }).timestamp(timestamp) + ) + ); +} diff --git a/x-pack/test/api_integration/apis/metrics_ui/services.ts b/x-pack/test/api_integration/apis/metrics_ui/services.ts index 5b4532e8e2655..c738ecfed673c 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/services.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/services.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { ServicesAPIResponseRT } from '@kbn/infra-plugin/common/http_api/host_details'; import { decodeOrThrow } from '@kbn/infra-plugin/common/runtime_types'; import { FtrProviderContext } from './types'; -import { generateServicesData } from './helpers'; +import { generateServicesData, generateServicesLogsOnlyData } from './helpers'; const SERVICES_ENDPOINT = '/api/infra/services'; @@ -17,70 +17,94 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const synthtrace = getService('apmSynthtraceEsClient'); describe('GET /infra/services', () => { - it('returns no services with no data', async () => { - const filters = JSON.stringify({ - 'host.name': 'some-host', + const from = new Date(Date.now() - 1000 * 60 * 2).toISOString(); + const to = new Date().toISOString(); + describe('with transactions', () => { + before(async () => { + await synthtrace.index( + generateServicesData({ from, to, instanceCount: 3, servicesPerHost: 3 }) + ); }); - const from = new Date(Date.now() - 1000 * 60 * 2).toISOString(); - const to = new Date().toISOString(); - const response = await supertest - .get(SERVICES_ENDPOINT) - .set({ - 'kbn-xsrf': 'some-xsrf-token', - }) - .query({ - filters, - from, - to, - }) - .expect(200); + after(() => synthtrace.clean()); + it('returns no services with no data', async () => { + const filters = JSON.stringify({ + 'host.name': 'some-host', + }); - const { services } = decodeOrThrow(ServicesAPIResponseRT)(response.body); - expect(services.length).to.be(0); - }); - it('should return correct number of services running on specified host', async () => { - const from = new Date(Date.now() - 1000 * 60 * 2).toISOString(); - const to = new Date().toISOString(); - await synthtrace.index( - generateServicesData({ from, to, instanceCount: 3, servicesPerHost: 3 }) - ); - const filters = JSON.stringify({ - 'host.name': 'host-0', + const response = await supertest + .get(SERVICES_ENDPOINT) + .set({ + 'kbn-xsrf': 'some-xsrf-token', + }) + .query({ + filters, + from, + to, + }) + .expect(200); + + const { services } = decodeOrThrow(ServicesAPIResponseRT)(response.body); + expect(services.length).to.be(0); + }); + it('should return correct number of services running on specified host', async () => { + const filters = JSON.stringify({ + 'host.name': 'host-0', + }); + const response = await supertest + .get(SERVICES_ENDPOINT) + .set({ + 'kbn-xsrf': 'some-xsrf-token', + }) + .query({ + filters, + from, + to, + }) + .expect(200); + expect(response.body.services.length).to.equal(3); + }); + it('should return bad request if unallowed filter', async () => { + const filters = JSON.stringify({ + 'host.name': 'host-0', + 'agent.name': 'nodejs', + }); + await supertest + .get(SERVICES_ENDPOINT) + .set({ + 'kbn-xsrf': 'some-xsrf-token', + }) + .query({ + filters, + from, + to, + }) + .expect(400); }); - const response = await supertest - .get(SERVICES_ENDPOINT) - .set({ - 'kbn-xsrf': 'some-xsrf-token', - }) - .query({ - filters, - from, - to, - }) - .expect(200); - expect(response.body.services.length).to.equal(3); }); - it('should return bad request if unallowed filter', async () => { - const from = new Date(Date.now() - 1000 * 60 * 2).toISOString(); - const to = new Date().toISOString(); - await synthtrace.index( - generateServicesData({ from, to, instanceCount: 3, servicesPerHost: 3 }) - ); - const filters = JSON.stringify({ - 'host.name': 'host-0', - 'agent.name': 'nodejs', + describe('with logs only', () => { + before(async () => { + await synthtrace.index( + generateServicesLogsOnlyData({ from, to, instanceCount: 1, servicesPerHost: 2 }) + ); + }); + after(() => synthtrace.clean()); + it('should return services with logs only data', async () => { + const filters = JSON.stringify({ + 'host.name': 'host-0', + }); + const response = await supertest + .get(SERVICES_ENDPOINT) + .set({ + 'kbn-xsrf': 'some-xsrf-token', + }) + .query({ + filters, + from, + to, + }) + .expect(200); + expect(response.body.services.length).to.equal(2); }); - const response = await supertest - .get(SERVICES_ENDPOINT) - .set({ - 'kbn-xsrf': 'some-xsrf-token', - }) - .query({ - filters, - from, - to, - }) - .expect(400); }); }); }