import { apm , timerange } from '@elastic/apm-synthtrace' ; import expect from '@kbn/expect' ; import { meanBy , sumBy } from 'lodash' ; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types' ; import { FtrProviderContext } from '../../common/ftr_provider_context' ; import { roundNumber } from '../../utils' ; export default function ApiTest ( { getService } ) { const registry = getService ( 'registry' ) ; const apmApiClient = getService ( 'apmApiClient' ) ; const synthtraceEsClient = getService ( 'synthtraceEsClient' ) ; const serviceName = 'synth-go' ; const start = new Date ( '2021-01-01T00:00:00.000Z' ) . getTime ( ) ; const end = new Date ( '2021-01-01T00:15:00.000Z' ) . getTime ( ) - 1 ; async function getThroughputValues ( processorEvent ) { const commonQuery = { start : new Date ( start ) . toISOString ( ) , end : new Date ( end ) . toISOString ( ) , environment : 'ENVIRONMENT_ALL' , } ; const [ serviceInventoryAPIResponse , serviceThroughputAPIResponse , transactionsGroupDetailsAPIResponse , serviceInstancesAPIResponse , ] = await Promise . all ( [ apmApiClient . readUser ( { endpoint : 'GET /internal/apm/services' , params : { query : { ... commonQuery , kuery : `service.name : "${ serviceName }" and processor.event : "${ processorEvent }"` , } , } , } ) , apmApiClient . readUser ( { endpoint : 'GET /internal/apm/services/{serviceName}/throughput' , params : { path : { serviceName } , query : { ... commonQuery , kuery : `processor.event : "${ processorEvent }"` , transactionType : 'request' , } , } , } ) , apmApiClient . readUser ( { endpoint : `GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics` , params : { path : { serviceName } , query : { ... commonQuery , kuery : `processor.event : "${ processorEvent }"` , transactionType : 'request' , latencyAggregationType : 'avg' as LatencyAggregationType , } , } , } ) , apmApiClient . readUser ( { endpoint : `GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics` , params : { path : { serviceName } , query : { ... commonQuery , kuery : `processor.event : "${ processorEvent }"` , transactionType : 'request' , latencyAggregationType : 'avg' as LatencyAggregationType , } , } , } ) , ] ) ; const serviceInventoryThroughput = serviceInventoryAPIResponse . body . items [ 0 ] . throughput ; const throughputChartApiMean = meanBy ( serviceThroughputAPIResponse . body . currentPeriod , 'y' ) ; const transactionsGroupThroughputSum = sumBy ( transactionsGroupDetailsAPIResponse . body . transactionGroups , 'throughput' ) ; const serviceInstancesThroughputSum = sumBy ( serviceInstancesAPIResponse . body . currentPeriod , 'throughput' ) ; return { serviceInventoryThroughput , throughputChartApiMean , transactionsGroupThroughputSum , serviceInstancesThroughputSum , } ; } let throughputMetricValues ; let throughputTransactionValues ; registry . when ( 'Services APIs' , { config : 'basic' , archives : [ 'apm_mappings_only_8.0.0' ] } , ( ) => { describe ( 'when data is loaded ' , ( ) => { const GO_PROD_RATE = 80 ; const GO_DEV_RATE = 20 ; before ( async ( ) => { const serviceGoProdInstance = apm . service ( serviceName , 'production' , 'go' ) . instance ( 'instance-a' ) ; const serviceGoDevInstance = apm . service ( serviceName , 'development' , 'go' ) . instance ( 'instance-b' ) ; await synthtraceEsClient . index ( [ ... timerange ( start , end ) . interval ( '1m' ) . rate ( GO_PROD_RATE ) . flatMap ( ( timestamp ) => serviceGoProdInstance . transaction ( 'GET /api/product/list' ) . duration ( 1000 ) . timestamp ( timestamp ) . serialize ( ) ) , ... timerange ( start , end ) . interval ( '1m' ) . rate ( GO_DEV_RATE ) . flatMap ( ( timestamp ) => serviceGoDevInstance . transaction ( 'GET /api/product/:id' ) . duration ( 1000 ) . timestamp ( timestamp ) . serialize ( ) ) , ] ) ; } ) ; after ( ( ) => synthtraceEsClient . clean ( ) ) ; describe ( 'compare throughput value between service inventory, throughput chart, service inventory and transactions apis' , ( ) => { before ( async ( ) => { [ throughputTransactionValues , throughputMetricValues ] = await Promise . all ( [ getThroughputValues ( 'transaction' ) , getThroughputValues ( 'metric' ) , ] ) ; } ) ; it ( 'returns same throughput value for Transaction-based and Metric-based data' , ( ) => { [ ... Object . values ( throughputTransactionValues ) , ... Object . values ( throughputMetricValues ) , ] . forEach ( ( value ) => expect ( roundNumber ( value ) ) . to . be . equal ( roundNumber ( GO_PROD_RATE + GO_DEV_RATE ) ) ) ; } ) ; } ) ; } ) ; } ) ; }