test: add e2e for NodeJS agent (#6073)
This commit is contained in:
parent
e739ca2290
commit
d4175d84b1
|
|
@ -0,0 +1,53 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: E2E-NodeJS
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**'
|
||||
- '!**.md'
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
SKIP_TEST: true
|
||||
SW_AGENT_JDK_VERSION: 8
|
||||
|
||||
jobs:
|
||||
NodeJSAgent:
|
||||
name: NodeJSAgent
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Compile and Build
|
||||
run: make docker
|
||||
- name: Copy dist package
|
||||
run: cp -R dist test/e2e/
|
||||
- name: NodeJS Agent
|
||||
run: ./mvnw --batch-mode -f test/e2e/pom.xml -am -DfailIfNoTests=false verify -Dit.test=org.apache.skywalking.e2e.NodeJSE2E
|
||||
|
|
@ -55,7 +55,8 @@ public class TopoMatcher extends AbstractMatcher<Topology> {
|
|||
try {
|
||||
getNodes().get(i).verify(topology.getNodes().get(j));
|
||||
matched = true;
|
||||
} catch (Throwable ignored) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
|
|
@ -71,7 +72,8 @@ public class TopoMatcher extends AbstractMatcher<Topology> {
|
|||
try {
|
||||
getCalls().get(i).verify(topology.getCalls().get(j));
|
||||
matched = true;
|
||||
} catch (Throwable ignored) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM node:12
|
||||
|
||||
ENV COMMIT_HASH=55daa7e6385b6236987a5e26bb39242724730455
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
EXPOSE 5050 5051
|
||||
|
||||
RUN git clone https://github.com/apache/skywalking-nodejs.git $(pwd)
|
||||
|
||||
RUN git reset --hard ${COMMIT_HASH} && git submodule update --init
|
||||
|
||||
RUN npm install
|
||||
RUN npm run generate-source
|
||||
RUN npm install express axios
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*!
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import * as http from 'http';
|
||||
import agent from './src';
|
||||
import axios from 'axios';
|
||||
|
||||
agent.start({
|
||||
serviceName: 'consumer',
|
||||
maxBufferSize: 1000,
|
||||
});
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
axios
|
||||
.post(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, {}, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
.then((r) => res.end(JSON.stringify(r.data)))
|
||||
.catch(err => res.end(JSON.stringify(err.message)));
|
||||
});
|
||||
|
||||
server.listen(5001, () => console.info('Listening on port 5001...'));
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
version: '2.1'
|
||||
|
||||
services:
|
||||
oap:
|
||||
extends:
|
||||
file: ../base-compose.yml
|
||||
service: oap
|
||||
|
||||
ui:
|
||||
extends:
|
||||
file: ../base-compose.yml
|
||||
service: ui
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
|
||||
provider:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.nodejs
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- 5000
|
||||
environment:
|
||||
SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
|
||||
SW_AGENT_INSTANCE: provider-instance
|
||||
volumes:
|
||||
- ./provider.ts:/app/provider.ts
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5000" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
entrypoint: [ 'npx', 'ts-node', '/app/provider.ts' ]
|
||||
|
||||
medium:
|
||||
extends:
|
||||
file: ../base-compose.yml
|
||||
service: consumer
|
||||
environment:
|
||||
PROVIDER_URL: http://provider:5000
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
provider:
|
||||
condition: service_healthy
|
||||
|
||||
consumer:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.nodejs
|
||||
networks:
|
||||
- e2e
|
||||
expose:
|
||||
- 5001
|
||||
environment:
|
||||
SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
|
||||
SW_AGENT_INSTANCE: consumer-instance
|
||||
SERVER: medium:9092
|
||||
volumes:
|
||||
- ./consumer.ts:/app/consumer.ts
|
||||
depends_on:
|
||||
oap:
|
||||
condition: service_healthy
|
||||
medium:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5051" ]
|
||||
interval: 5s
|
||||
timeout: 60s
|
||||
retries: 120
|
||||
entrypoint: [ 'npx', 'ts-node', '/app/consumer.ts' ]
|
||||
|
||||
networks:
|
||||
e2e:
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*!
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import agent from './src';
|
||||
|
||||
import express from 'express';
|
||||
|
||||
agent.start({
|
||||
serviceName: 'provider',
|
||||
maxBufferSize: 1000,
|
||||
});
|
||||
const app = express();
|
||||
|
||||
const handle = (req, res) => setTimeout(() => res.send({'id': 1, 'name': 'ke'}), 200);
|
||||
|
||||
app.get('/users', handle);
|
||||
app.post('/users', handle);
|
||||
|
||||
app.listen(5000, () => console.info('Listening on port 5000...'));
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.e2e;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
|
||||
import org.apache.skywalking.e2e.annotation.DockerCompose;
|
||||
import org.apache.skywalking.e2e.base.SkyWalkingE2E;
|
||||
import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
|
||||
import org.apache.skywalking.e2e.common.HostAndPort;
|
||||
import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
|
||||
import org.apache.skywalking.e2e.metrics.Metrics;
|
||||
import org.apache.skywalking.e2e.metrics.MetricsQuery;
|
||||
import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
|
||||
import org.apache.skywalking.e2e.retryable.RetryableTest;
|
||||
import org.apache.skywalking.e2e.service.Service;
|
||||
import org.apache.skywalking.e2e.service.ServicesMatcher;
|
||||
import org.apache.skywalking.e2e.service.ServicesQuery;
|
||||
import org.apache.skywalking.e2e.service.endpoint.Endpoint;
|
||||
import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
|
||||
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
|
||||
import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
|
||||
import org.apache.skywalking.e2e.service.instance.Instance;
|
||||
import org.apache.skywalking.e2e.service.instance.Instances;
|
||||
import org.apache.skywalking.e2e.service.instance.InstancesMatcher;
|
||||
import org.apache.skywalking.e2e.service.instance.InstancesQuery;
|
||||
import org.apache.skywalking.e2e.topo.Call;
|
||||
import org.apache.skywalking.e2e.topo.ServiceInstanceTopology;
|
||||
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyMatcher;
|
||||
import org.apache.skywalking.e2e.topo.ServiceInstanceTopologyQuery;
|
||||
import org.apache.skywalking.e2e.topo.TopoMatcher;
|
||||
import org.apache.skywalking.e2e.topo.TopoQuery;
|
||||
import org.apache.skywalking.e2e.topo.Topology;
|
||||
import org.apache.skywalking.e2e.trace.Trace;
|
||||
import org.apache.skywalking.e2e.trace.TracesMatcher;
|
||||
import org.apache.skywalking.e2e.trace.TracesQuery;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.testcontainers.containers.DockerComposeContainer;
|
||||
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyPercentileMetrics;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_MULTIPLE_LINEAR_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_CLIENT_METRICS;
|
||||
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_RELATION_SERVER_METRICS;
|
||||
import static org.apache.skywalking.e2e.utils.Times.now;
|
||||
import static org.apache.skywalking.e2e.utils.Yamls.load;
|
||||
|
||||
@Slf4j
|
||||
@SkyWalkingE2E
|
||||
public class NodeJSE2E extends SkyWalkingTestAdapter {
|
||||
@SuppressWarnings("unused")
|
||||
@DockerCompose("docker/nodejs/docker-compose.yml")
|
||||
private DockerComposeContainer<?> justForSideEffects;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ContainerHostAndPort(name = "ui", port = 8080)
|
||||
private HostAndPort swWebappHostPort;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ContainerHostAndPort(name = "consumer", port = 5001)
|
||||
private HostAndPort nodejsHostPort;
|
||||
|
||||
@BeforeAll
|
||||
public void setUp() throws Exception {
|
||||
queryClient(swWebappHostPort);
|
||||
|
||||
trafficController(nodejsHostPort, "/users");
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public void tearDown() {
|
||||
trafficController.stop();
|
||||
}
|
||||
|
||||
@RetryableTest
|
||||
void services() throws Exception {
|
||||
List<Service> services = graphql.services(new ServicesQuery().start(startTime).end(now()));
|
||||
services = services.stream().filter(s -> !s.getLabel().equals("oap::oap-server")).collect(Collectors.toList());
|
||||
LOGGER.info("services: {}", services);
|
||||
|
||||
load("expected/nodejs/services.yml").as(ServicesMatcher.class).verify(services);
|
||||
|
||||
for (Service service : services) {
|
||||
if ("Your_ApplicationName".equals(service.getLabel())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGGER.info("verifying service instances: {}", service);
|
||||
|
||||
verifyServiceMetrics(service);
|
||||
|
||||
final Instances instances = verifyServiceInstances(service);
|
||||
|
||||
verifyInstancesMetrics(instances);
|
||||
|
||||
final Endpoints endpoints = verifyServiceEndpoints(service);
|
||||
|
||||
verifyEndpointsMetrics(endpoints);
|
||||
}
|
||||
}
|
||||
|
||||
@RetryableTest
|
||||
void traces() throws Exception {
|
||||
final List<Trace> traces = graphql.traces(new TracesQuery().start(startTime).end(now()).orderByStartTime());
|
||||
|
||||
LOGGER.info("traces: {}", traces);
|
||||
|
||||
load("expected/nodejs/traces.yml").as(TracesMatcher.class).verifyLoosely(traces);
|
||||
}
|
||||
|
||||
@RetryableTest
|
||||
void topology() throws Exception {
|
||||
final Topology topology = graphql.topo(new TopoQuery().stepByMinute().start(startTime.minusDays(1)).end(now()));
|
||||
|
||||
LOGGER.info("topology: {}", topology);
|
||||
|
||||
load("expected/nodejs/topo.yml").as(TopoMatcher.class).verify(topology);
|
||||
|
||||
verifyServiceRelationMetrics(topology.getCalls());
|
||||
}
|
||||
|
||||
@RetryableTest
|
||||
void serviceInstances() throws Exception {
|
||||
|
||||
final ServiceInstanceTopology topology = graphql.serviceInstanceTopo(
|
||||
new ServiceInstanceTopologyQuery().stepByMinute()
|
||||
.start(startTime.minusDays(1))
|
||||
.end(now())
|
||||
.clientServiceId("Y29uc3VtZXI=.1")
|
||||
.serverServiceId("WW91cl9BcHBsaWNhdGlvbk5hbWU=.1"));
|
||||
|
||||
LOGGER.info("topology: {}", topology);
|
||||
|
||||
load("expected/nodejs/consumer-instance-topo.yml").as(ServiceInstanceTopologyMatcher.class).verify(topology);
|
||||
|
||||
verifyServiceInstanceRelationMetrics(topology.getCalls());
|
||||
}
|
||||
|
||||
private Instances verifyServiceInstances(final Service service) throws Exception {
|
||||
final Instances instances = graphql.instances(
|
||||
new InstancesQuery().serviceId(service.getKey()).start(startTime).end(now())
|
||||
);
|
||||
|
||||
LOGGER.info("instances: {} {}", service.getLabel(), instances);
|
||||
|
||||
load(String.format("expected/nodejs/%s-instances.yml", service.getLabel()))
|
||||
.as(InstancesMatcher.class)
|
||||
.verify(instances);
|
||||
|
||||
return instances;
|
||||
}
|
||||
|
||||
private Endpoints verifyServiceEndpoints(final Service service) throws Exception {
|
||||
final Endpoints endpoints = graphql.endpoints(new EndpointQuery().serviceId(service.getKey()));
|
||||
|
||||
LOGGER.info("endpoints: {} {}", service.getLabel(), endpoints);
|
||||
|
||||
load(String.format("expected/nodejs/%s-endpoints.yml", service.getLabel()))
|
||||
.as(EndpointsMatcher.class)
|
||||
.verify(endpoints);
|
||||
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
private void verifyInstancesMetrics(Instances instances) throws Exception {
|
||||
for (Instance instance : instances.getInstances()) {
|
||||
for (String metricsName : ALL_INSTANCE_METRICS) {
|
||||
LOGGER.info("verifying service instance response time: {}", instance);
|
||||
final Metrics instanceMetrics = graphql.metrics(
|
||||
new MetricsQuery().stepByMinute().metricsName(metricsName).id(instance.getKey())
|
||||
);
|
||||
|
||||
LOGGER.info("instance metrics: {}", instanceMetrics);
|
||||
|
||||
final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
|
||||
final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
|
||||
greaterThanZero.setValue("gt 0");
|
||||
instanceRespTimeMatcher.setValue(greaterThanZero);
|
||||
instanceRespTimeMatcher.verify(instanceMetrics);
|
||||
LOGGER.info("{}: {}", metricsName, instanceMetrics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyEndpointsMetrics(Endpoints endpoints) throws Exception {
|
||||
for (Endpoint endpoint : endpoints.getEndpoints()) {
|
||||
for (final String metricName : ALL_ENDPOINT_METRICS) {
|
||||
LOGGER.info("verifying endpoint {}: {}", endpoint, metricName);
|
||||
|
||||
final Metrics metrics = graphql.metrics(
|
||||
new MetricsQuery().stepByMinute().metricsName(metricName).id(endpoint.getKey())
|
||||
);
|
||||
|
||||
LOGGER.info("metrics: {}", metrics);
|
||||
|
||||
final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
|
||||
final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
|
||||
greaterThanZero.setValue("gt 0");
|
||||
instanceRespTimeMatcher.setValue(greaterThanZero);
|
||||
instanceRespTimeMatcher.verify(metrics);
|
||||
|
||||
LOGGER.info("{}: {}", metricName, metrics);
|
||||
}
|
||||
for (String metricName : ALL_ENDPOINT_MULTIPLE_LINEAR_METRICS) {
|
||||
verifyPercentileMetrics(graphql, metricName, endpoint.getKey(), startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyServiceMetrics(final Service service) throws Exception {
|
||||
for (String metricName : ALL_SERVICE_METRICS) {
|
||||
LOGGER.info("verifying service {}, metrics: {}", service, metricName);
|
||||
final Metrics serviceMetrics = graphql.metrics(
|
||||
new MetricsQuery().stepByMinute().metricsName(metricName).id(service.getKey())
|
||||
);
|
||||
LOGGER.info("serviceMetrics: {}", serviceMetrics);
|
||||
final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
|
||||
final MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
|
||||
greaterThanZero.setValue("gt 0");
|
||||
instanceRespTimeMatcher.setValue(greaterThanZero);
|
||||
instanceRespTimeMatcher.verify(serviceMetrics);
|
||||
LOGGER.info("{}: {}", metricName, serviceMetrics);
|
||||
}
|
||||
|
||||
for (String metricName : ALL_SERVICE_MULTIPLE_LINEAR_METRICS) {
|
||||
verifyPercentileMetrics(graphql, metricName, service.getKey(), startTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyServiceInstanceRelationMetrics(final List<Call> calls) throws Exception {
|
||||
verifyRelationMetrics(
|
||||
calls, ALL_SERVICE_INSTANCE_RELATION_CLIENT_METRICS,
|
||||
ALL_SERVICE_INSTANCE_RELATION_SERVER_METRICS
|
||||
);
|
||||
}
|
||||
|
||||
private void verifyServiceRelationMetrics(final List<Call> calls) throws Exception {
|
||||
verifyRelationMetrics(calls, ALL_SERVICE_RELATION_CLIENT_METRICS, ALL_SERVICE_RELATION_SERVER_METRICS);
|
||||
}
|
||||
|
||||
private void verifyRelationMetrics(final List<Call> calls,
|
||||
final String[] relationClientMetrics,
|
||||
final String[] relationServerMetrics) throws Exception {
|
||||
for (Call call : calls) {
|
||||
for (String detectPoint : call.getDetectPoints()) {
|
||||
switch (detectPoint) {
|
||||
case "CLIENT": {
|
||||
for (String metricName : relationClientMetrics) {
|
||||
verifyMetrics(graphql, metricName, call.getId(), startTime);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SERVER": {
|
||||
for (String metricName : relationServerMetrics) {
|
||||
verifyMetrics(graphql, metricName, call.getId(), startTime);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
endpoints:
|
||||
- key: not null
|
||||
label: /users
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
nodes:
|
||||
- id: not null
|
||||
name: consumer-instance
|
||||
serviceId: not null
|
||||
serviceName: consumer
|
||||
isReal: true
|
||||
- id: not null
|
||||
name: not null
|
||||
serviceId: not null
|
||||
serviceName: Your_ApplicationName
|
||||
isReal: true
|
||||
calls:
|
||||
- id: not null
|
||||
source: Y29uc3VtZXI=.1_Y29uc3VtZXItaW5zdGFuY2U=
|
||||
detectPoints:
|
||||
- CLIENT
|
||||
- SERVER
|
||||
target: not null
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
instances:
|
||||
- key: not null
|
||||
label: not null
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
endpoints:
|
||||
- key: not null
|
||||
label: /users
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
instances:
|
||||
- key: not null
|
||||
label: not null
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
services:
|
||||
- key: not null
|
||||
label: provider
|
||||
- key: not null
|
||||
label: consumer
|
||||
- key: not null
|
||||
label: Your_ApplicationName
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
nodes:
|
||||
- id: not null
|
||||
name: User
|
||||
type: USER
|
||||
isReal: false
|
||||
- id: not null
|
||||
name: consumer
|
||||
type: http
|
||||
isReal: true
|
||||
- id: not null
|
||||
name: provider
|
||||
type: Express
|
||||
isReal: true
|
||||
- id: not null
|
||||
name: Your_ApplicationName
|
||||
type: Tomcat
|
||||
isReal: true
|
||||
calls:
|
||||
- id: not null
|
||||
source: ${User[0]}
|
||||
detectPoints:
|
||||
- SERVER
|
||||
target: ${consumer[0]}
|
||||
- id: not null
|
||||
source: ${consumer[0]}
|
||||
detectPoints:
|
||||
- CLIENT
|
||||
- SERVER
|
||||
target: ${Your_ApplicationName[0]}
|
||||
- id: not null
|
||||
source: ${Your_ApplicationName[0]}
|
||||
detectPoints:
|
||||
- CLIENT
|
||||
- SERVER
|
||||
target: ${provider[0]}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
traces:
|
||||
- key: not null
|
||||
endpointNames:
|
||||
- /users
|
||||
duration: ge 0
|
||||
start: gt 0
|
||||
isError: false
|
||||
traceIds:
|
||||
- not null
|
||||
Loading…
Reference in New Issue