提交 d1a521b7 编写于 作者: K kezhenxu94 提交者: wu-sheng

Add end to end tests (#2935)

e2e test setup. cc @hanahmily @peng-yongsheng @IanCao @zhaoyuguang @JaredTan95 

# e2e test case
One single standalone Spring service, accessing H2 database. This service has been installed the agent. 
OAP runs in single mode with H2 storage too.

The e2e test will verify the results through GraphQL query
1. Traces exist.
2. Service/Service Instance/Endpoint exist and have expected metrics.
3. Topology exists and match expected.
上级 7f3ff150
/*
* 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.
*
*/
pipeline {
agent {
label 'xenial'
}
tools {
jdk 'JDK 1.8 (latest)'
}
stages {
stage('Checkout Source Code') {
steps {
deleteDir()
checkout scm
sh 'git submodule update --init'
}
}
stage('Prepare Distribution Package') {
steps {
sh './mvnw -DskipTests clean package'
sh 'tar -zxf dist/apache-skywalking-apm-bin.tar.gz -C dist'
}
}
stage('Run End-to-End Tests') {
steps {
sh './mvnw -Dbuild.id=${BUILD_ID} -f test/e2e/pom.xml clean verify'
}
}
}
post {
always {
// "Abort old build on update" will interrupt the job completely,
// we need to clean up when there are containers started by the e2e tests
sh 'docker ps'
sh 'docker ps | grep -e "skywalking-e2e-container-${BUILD_ID}" | awk \'{print $1}\' | xargs --no-run-if-empty docker stop'
deleteDir()
}
}
}
......@@ -20,10 +20,10 @@ PRG="$0"
PRGDIR=`dirname "$PRG"`
[ -z "$OAP_HOME" ] && OAP_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
OAP_LOG_DIR="${OAP_HOME}/logs"
OAP_LOG_DIR="${OAP_LOG_DIR:-${OAP_HOME}/logs}"
JAVA_OPTS=" -Xms256M -Xmx512M"
if [ ! -d "${OAP_HOME}/logs" ]; then
if [ ! -d "${OAP_LOG_DIR}" ]; then
mkdir -p "${OAP_LOG_DIR}"
fi
......
......@@ -20,11 +20,11 @@ PRG="$0"
PRGDIR=`dirname "$PRG"`
[ -z "$WEBAPP_HOME" ] && WEBAPP_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
WEBAPP_LOG_DIR="${WEBAPP_HOME}/logs"
WEBAPP_LOG_DIR="${WEBAPP_LOG_DIR:-${WEBAPP_HOME}/logs}"
JAVA_OPTS=" -Xms256M -Xmx512M"
JAR_PATH="${WEBAPP_HOME}/webapp"
if [ ! -d "${WEBAPP_HOME}/logs" ]; then
if [ ! -d "${WEBAPP_LOG_DIR}" ]; then
mkdir -p "${WEBAPP_LOG_DIR}"
fi
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apache-skywalking-e2e</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>e2e-base</artifactId>
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snake.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</project>
/*
* 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.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
/**
* @author kezhenxu94
*/
public abstract class AbstractQuery<T extends AbstractQuery<?>> {
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmmss");
private static final DateTimeFormatter MINUTE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmm");
private String start;
private String end;
private String step = "SECOND";
public String start() {
if (start != null) {
return start;
}
return "SECOND".equals(step())
? LocalDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(TIME_FORMATTER)
: LocalDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(MINUTE_TIME_FORMATTER);
}
public T start(String start) {
this.start = start;
return (T) this;
}
public T start(LocalDateTime start) {
if ("MINUTE".equals(step())) {
this.start = start.format(MINUTE_TIME_FORMATTER);
} else if ("SECOND".equals(step())) {
this.start = start.format(TIME_FORMATTER);
}
return (T) this;
}
public String end() {
if (end != null) {
return end;
}
return "SECOND".equals(step())
? LocalDateTime.now(ZoneOffset.UTC).format(TIME_FORMATTER)
: LocalDateTime.now(ZoneOffset.UTC).format(MINUTE_TIME_FORMATTER);
}
public AbstractQuery end(String end) {
this.end = end;
return this;
}
public T end(LocalDateTime end) {
if ("MINUTE".equals(step())) {
this.end = end.format(MINUTE_TIME_FORMATTER);
} else if ("SECOND".equals(step())) {
this.end = end.format(TIME_FORMATTER);
}
return (T) this;
}
public String step() {
return step;
}
public T step(String step) {
this.step = step;
return (T) this;
}
}
/*
* 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;
/**
* GraphQL response for easily test
*
* @author kezhenxu94
*/
public class GQLResponse<T> {
private T data;
public T getData() {
return data;
}
public void setData(final T data) {
this.data = data;
}
@Override
public String toString() {
return "GQLResponse{" +
"data=" + data +
'}';
}
}
/*
* 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 com.google.common.io.Resources;
import org.apache.skywalking.e2e.metrics.Metrics;
import org.apache.skywalking.e2e.metrics.MetricsData;
import org.apache.skywalking.e2e.metrics.MetricsQuery;
import org.apache.skywalking.e2e.service.Service;
import org.apache.skywalking.e2e.service.ServicesData;
import org.apache.skywalking.e2e.service.ServicesQuery;
import org.apache.skywalking.e2e.service.endpoint.EndpointQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
import org.apache.skywalking.e2e.service.instance.Instances;
import org.apache.skywalking.e2e.service.instance.InstancesQuery;
import org.apache.skywalking.e2e.topo.TopoData;
import org.apache.skywalking.e2e.topo.TopoQuery;
import org.apache.skywalking.e2e.topo.TopoResponse;
import org.apache.skywalking.e2e.trace.Trace;
import org.apache.skywalking.e2e.trace.TracesData;
import org.apache.skywalking.e2e.trace.TracesQuery;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author kezhenxu94
*/
public class SimpleQueryClient {
private final RestTemplate restTemplate = new RestTemplate();
private final String endpointUrl;
public SimpleQueryClient(String endpointUrl) {
this.endpointUrl = endpointUrl;
}
public List<Trace> traces(final TracesQuery query) throws Exception {
final URL queryFileUrl = Resources.getResource("traces.gql");
final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8"))
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{start}", query.start())
.replace("{end}", query.end())
.replace("{step}", query.step())
.replace("{traceState}", query.traceState())
.replace("{pageNum}", query.pageNum())
.replace("{pageSize}", query.pageSize())
.replace("{needTotal}", query.needTotal())
.replace("{queryOrder}", query.queryOrder());
final ResponseEntity<GQLResponse<TracesData>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<TracesData>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getTraces().getData();
}
public List<Service> services(final ServicesQuery query) throws Exception {
final URL queryFileUrl = Resources.getResource("services.gql");
final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8"))
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{start}", query.start())
.replace("{end}", query.end())
.replace("{step}", query.step());
final ResponseEntity<GQLResponse<ServicesData>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<ServicesData>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getServices();
}
public Instances instances(final InstancesQuery query) throws Exception {
final URL queryFileUrl = Resources.getResource("instances.gql");
final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8"))
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{serviceId}", query.serviceId())
.replace("{start}", query.start())
.replace("{end}", query.end())
.replace("{step}", query.step());
final ResponseEntity<GQLResponse<Instances>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<Instances>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData();
}
public Endpoints endpoints(final EndpointQuery query) throws Exception {
final URL queryFileUrl = Resources.getResource("endpoints.gql");
final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8"))
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{serviceId}", query.serviceId());
final ResponseEntity<GQLResponse<Endpoints>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<Endpoints>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData();
}
public TopoData topo(final TopoQuery query) throws Exception {
final URL queryFileUrl = Resources.getResource("topo.gql");
final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8"))
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{step}", query.step())
.replace("{start}", query.start())
.replace("{end}", query.end());
final ResponseEntity<GQLResponse<TopoResponse>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<TopoResponse>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getTopo();
}
public Metrics metrics(final MetricsQuery query) throws Exception {
final URL queryFileUrl = Resources.getResource("metrics.gql");
final String queryString = Resources.readLines(queryFileUrl, Charset.forName("UTF8"))
.stream()
.filter(it -> !it.startsWith("#"))
.collect(Collectors.joining())
.replace("{step}", query.step())
.replace("{start}", query.start())
.replace("{end}", query.end())
.replace("{metricsName}", query.metricsName())
.replace("{id}", query.id());
final ResponseEntity<GQLResponse<MetricsData>> responseEntity = restTemplate.exchange(
new RequestEntity<>(queryString, HttpMethod.POST, URI.create(endpointUrl)),
new ParameterizedTypeReference<GQLResponse<MetricsData>>() {
}
);
if (responseEntity.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException("Response status != 200, actual: " + responseEntity.getStatusCode());
}
return Objects.requireNonNull(responseEntity.getBody()).getData().getMetrics();
}
}
/*
* 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.metrics;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import org.assertj.core.api.Condition;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
public class AtLeastOneOfMetricsMatcher extends AbstractMatcher<Metrics> {
private MetricsValueMatcher value;
@Override
public void verify(Metrics metrics) {
assertThat(metrics.getValues()).isNotEmpty();
assertThat(metrics.getValues()).areAtLeastOne(new Condition<MetricsValue>(){
@Override
public boolean matches(MetricsValue value) {
try {
AtLeastOneOfMetricsMatcher.this.getValue().verify(value);
return true;
} catch (Throwable t) {
return false;
}
}
});
}
public MetricsValueMatcher getValue() {
return value;
}
public void setValue(MetricsValueMatcher value) {
this.value = value;
}
@Override
public String toString() {
return "OneOfMetricsMatcher{" +
"value=" + value +
'}';
}
}
/*
* 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.metrics;
import java.util.ArrayList;
import java.util.List;
/**
* @author kezhenxu94
*/
public class Metrics {
private List<MetricsValue> values = new ArrayList<>();
public List<MetricsValue> getValues() {
return values;
}
public void setValues(List<MetricsValue> values) {
this.values = values;
}
@Override
public String toString() {
return "Metrics{" +
"values=" + values +
'}';
}
}
/*
* 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.metrics;
/**
* @author kezhenxu94
*/
public class MetricsData {
private Metrics metrics;
public Metrics getMetrics() {
return metrics;
}
public void setMetrics(Metrics metrics) {
this.metrics = metrics;
}
@Override
public String toString() {
return "MetricsData{" +
"metrics=" + metrics +
'}';
}
}
/*
* 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.metrics;
import org.apache.skywalking.e2e.AbstractQuery;
/**
* @author kezhenxu94
*/
public class MetricsQuery extends AbstractQuery<MetricsQuery> {
public static String SERVICE_P99 = "service_p99";
public static String SERVICE_P95 = "service_p95";
public static String SERVICE_P90 = "service_p90";
public static String SERVICE_P75 = "service_p75";
public static String SERVICE_P50 = "service_p50";
public static String ENDPOINT_P99 = "endpoint_p99";
public static String ENDPOINT_P95 = "endpoint_p95";
public static String ENDPOINT_P90 = "endpoint_p90";
public static String ENDPOINT_P75 = "endpoint_p75";
public static String ENDPOINT_P50 = "endpoint_p50";
public static String SERVICE_INSTANCE_RESP_TIME = "service_instance_resp_time";
public static String SERVICE_INSTANCE_CPM = "service_instance_cpm";
public static String SERVICE_INSTANCE_SLA = "service_instance_sla";
private String id;
private String metricsName;
public String id() {
return id;
}
public MetricsQuery id(String id) {
this.id = id;
return this;
}
public String metricsName() {
return metricsName;
}
public MetricsQuery metricsName(String metricsName) {
this.metricsName = metricsName;
return this;
}
@Override
public String toString() {
return "MetricsQuery{" +
"id='" + id + '\'' +
", metricsName='" + metricsName + '\'' +
'}';
}
}
/*
* 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.metrics;
/**
* @author kezhenxu94
*/
public class MetricsValue {
private String value;
public String getValue() {
return value;
}
public MetricsValue setValue(String value) {
this.value = value;
return this;
}
@Override
public String toString() {
return "MetricsValue{" +
"value='" + value + '\'' +
'}';
}
}
/*
* 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.metrics;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.Objects;
/**
* @author kezhenxu94
*/
public class MetricsValueMatcher extends AbstractMatcher<MetricsValue> {
private String value;
@Override
public void verify(MetricsValue metricsValue) {
if (Objects.nonNull(getValue())) {
doVerify(getValue(), metricsValue.getValue());
}
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "MetricsValueMatcher{" +
"value='" + value + '\'' +
'}';
}
}
/*
* 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.service;
/**
* @author kezhenxu94
*/
public class Service {
private String key;
private String label;
public String getKey() {
return key;
}
public Service setKey(String key) {
this.key = key;
return this;
}
public String getLabel() {
return label;
}
public Service setLabel(String label) {
this.label = label;
return this;
}
@Override
public String toString() {
return "Service{" +
"key='" + key + '\'' +
", label='" + label + '\'' +
'}';
}
}
/*
* 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.service;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.Objects;
/**
* A simple matcher to verify the given {@code Service} is expected
*
* @author kezhenxu94
*/
public class ServiceMatcher extends AbstractMatcher<Service> {
private String key;
private String label;
@Override
public void verify(final Service service) {
if (Objects.nonNull(getKey())) {
verifyKey(service);
}
if (Objects.nonNull(getLabel())) {
verifyLabel(service);
}
}
private void verifyKey(Service service) {
final String expected = this.getKey();
final String actual = service.getKey();
doVerify(expected, actual);
}
private void verifyLabel(Service service) {
final String expected = this.getLabel();
final String actual = String.valueOf(service.getLabel());
doVerify(expected, actual);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
/*
* 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.service;
import java.util.List;
/**
* @author kezhenxu94
*/
public class ServicesData {
private List<Service> services;
public List<Service> getServices() {
return services;
}
public void setServices(List<Service> services) {
this.services = services;
}
}
/*
* 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.service;
import java.util.LinkedList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
public class ServicesMatcher {
private List<ServiceMatcher> services;
public ServicesMatcher() {
this.services = new LinkedList<>();
}
public List<ServiceMatcher> getServices() {
return services;
}
public void setServices(List<ServiceMatcher> services) {
this.services = services;
}
public void verify(final List<Service> services) {
assertThat(services).hasSameSizeAs(this.getServices());
int size = this.getServices().size();
for (int i = 0; i < size; i++) {
this.getServices().get(i).verify(services.get(i));
}
}
}
/*
* 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.service;
import org.apache.skywalking.e2e.AbstractQuery;
/**
* @author kezhenxu94
*/
public class ServicesQuery extends AbstractQuery<ServicesQuery> {
}
/*
* 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.service.endpoint;
/**
* @author kezhenxu94
*/
public class Endpoint {
private String key;
private String label;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@Override
public String toString() {
return "Endpoint{" +
"key='" + key + '\'' +
", label='" + label + '\'' +
'}';
}
}
/*
* 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.service.endpoint;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.Objects;
/**
* @author kezhenxu94
*/
public class EndpointMatcher extends AbstractMatcher<Endpoint> {
private String key;
private String label;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@Override
public void verify(final Endpoint endpoint) {
if (Objects.nonNull(getKey())) {
doVerify(getKey(), endpoint.getKey());
}
if (Objects.nonNull(getLabel())) {
doVerify(getLabel(), endpoint.getLabel());
}
}
}
/*
* 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.service.endpoint;
/**
* @author kezhenxu94
*/
public class EndpointQuery {
private String serviceId;
private String keyword;
public String serviceId() {
return serviceId;
}
public EndpointQuery serviceId(String serviceId) {
this.serviceId = serviceId;
return this;
}
public String keyword() {
return keyword;
}
public EndpointQuery keyword(String keyword) {
this.keyword = keyword;
return this;
}
@Override
public String toString() {
return "EndpointQuery{" +
"serviceId='" + serviceId + '\'' +
", keyword='" + keyword + '\'' +
'}';
}
}
/*
* 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.service.endpoint;
import java.util.List;
/**
* @author kezhenxu94
*/
public class Endpoints {
private List<Endpoint> endpoints;
public List<Endpoint> getEndpoints() {
return endpoints;
}
public void setEndpoints(List<Endpoint> endpoints) {
this.endpoints = endpoints;
}
@Override
public String toString() {
return "Endpoints{" +
"endpoints=" + endpoints +
'}';
}
}
/*
* 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.service.endpoint;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.List;
import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
public class EndpointsMatcher extends AbstractMatcher<Endpoints> {
private List<EndpointMatcher> endpoints;
public List<EndpointMatcher> getEndpoints() {
return endpoints;
}
public void setEndpoints(List<EndpointMatcher> endpoints) {
this.endpoints = endpoints;
}
@Override
public void verify(Endpoints endpoints) {
if (Objects.nonNull(getEndpoints())) {
assertThat(endpoints.getEndpoints()).hasSameSizeAs(getEndpoints());
int size = getEndpoints().size();
for (int i = 0; i < size; i++) {
getEndpoints().get(i).verify(endpoints.getEndpoints().get(i));
}
}
}
@Override
public String toString() {
return "EndpointsMatcher{" +
"endpoints=" + endpoints +
'}';
}
}
/*
* 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.service.instance;
/**
* @author kezhenxu94
*/
public class Attribute {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Attribute{" +
"name='" + name + '\'' +
", value='" + value + '\'' +
'}';
}
}
/*
* 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.service.instance;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.Objects;
/**
* @author kezhenxu94
*/
public class AttributeMatcher extends AbstractMatcher<Attribute> {
private String name;
private String value;
@Override
public void verify(final Attribute attribute) {
if (Objects.nonNull(attribute.getName())) {
doVerify(getName(), attribute.getName());
doVerify(getValue(), attribute.getValue());
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "Attribute{" +
"name='" + name + '\'' +
", value='" + value + '\'' +
'}';
}
}
/*
* 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.service.instance;
import java.util.List;
/**
* @author kezhenxu94
*/
public class Instance {
private String key;
private String label;
private List<Attribute> attributes;
public String getKey() {
return key;
}
public Instance setKey(String key) {
this.key = key;
return this;
}
public String getLabel() {
return label;
}
public Instance setLabel(String label) {
this.label = label;
return this;
}
public List<Attribute> getAttributes() {
return attributes;
}
public void setAttributes(List<Attribute> attributes) {
this.attributes = attributes;
}
@Override
public String toString() {
return "Instance{" +
"key='" + key + '\'' +
", label='" + label + '\'' +
", attributes=" + attributes +
'}';
}
}
/*
* 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.service.instance;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.List;
import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
/**
* A simple matcher to verify the given {@code Service} is expected
*
* @author kezhenxu94
*/
public class InstanceMatcher extends AbstractMatcher<Instance> {
private String key;
private String label;
private List<AttributeMatcher> attributes;
@Override
public void verify(final Instance instance) {
if (Objects.nonNull(getKey())) {
verifyKey(instance);
}
if (Objects.nonNull(getLabel())) {
verifyLabel(instance);
}
if (Objects.nonNull(getAttributes())) {
verifyAttributes(instance);
}
}
private void verifyKey(Instance instance) {
final String expected = this.getKey();
final String actual = instance.getKey();
doVerify(expected, actual);
}
private void verifyLabel(Instance instance) {
final String expected = this.getLabel();
final String actual = String.valueOf(instance.getLabel());
doVerify(expected, actual);
}
private void verifyAttributes(Instance instance) {
final List<AttributeMatcher> expected = this.getAttributes();
final List<Attribute> actual = instance.getAttributes();
assertThat(actual).hasSameSizeAs(expected);
int size = expected.size();
for (int i = 0; i < size; i++) {
expected.get(i).verify(actual.get(i));
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public List<AttributeMatcher> getAttributes() {
return attributes;
}
public void setAttributes(List<AttributeMatcher> attributes) {
this.attributes = attributes;
}
@Override
public String toString() {
return "InstanceMatcher{" +
"key='" + key + '\'' +
", label='" + label + '\'' +
", attributes=" + attributes +
'}';
}
}
/*
* 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.service.instance;
import java.util.List;
/**
* @author kezhenxu94
*/
public class Instances {
private List<Instance> instances;
public List<Instance> getInstances() {
return instances;
}
public void setInstances(List<Instance> instances) {
this.instances = instances;
}
}
/*
* 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.service.instance;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import org.assertj.core.api.Assertions;
import java.util.LinkedList;
import java.util.List;
/**
* @author kezhenxu94
*/
public class InstancesMatcher extends AbstractMatcher<Instances> {
private List<InstanceMatcher> instances;
public InstancesMatcher() {
this.instances = new LinkedList<>();
}
public List<InstanceMatcher> getInstances() {
return instances;
}
public void setInstances(List<InstanceMatcher> instances) {
this.instances = instances;
}
@Override
public void verify(final Instances instances) {
Assertions.assertThat(instances.getInstances()).hasSameSizeAs(this.getInstances());
int size = this.getInstances().size();
for (int i = 0; i < size; i++) {
this.getInstances().get(i).verify(instances.getInstances().get(i));
}
}
}
/*
* 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.service.instance;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
/**
* @author kezhenxu94
*/
public class InstancesQuery {
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HHmmss");
private String start = LocalDateTime.now(ZoneOffset.UTC).format(TIME_FORMATTER);
private String end = LocalDateTime.now(ZoneOffset.UTC).minusMinutes(15).format(TIME_FORMATTER);
private String step = "SECOND";
private String serviceId;
public String serviceId() {
return serviceId;
}
public InstancesQuery serviceId(String serviceId) {
this.serviceId = serviceId;
return this;
}
public String start() {
return start;
}
public InstancesQuery start(String start) {
this.start = start;
return this;
}
public InstancesQuery start(LocalDateTime start) {
this.start = start.format(TIME_FORMATTER);
return this;
}
public String end() {
return end;
}
public InstancesQuery end(String end) {
this.end = end;
return this;
}
public InstancesQuery end(LocalDateTime end) {
this.end = end.format(TIME_FORMATTER);
return this;
}
public String step() {
return step;
}
public InstancesQuery step(String step) {
this.step = step;
return this; }
}
/*
* 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.topo;
import java.util.List;
/**
* @author kezhenxu94
*/
public class Call {
private String id;
private String source;
private List<String> detectPoints;
private String target;
public String getId() {
return id;
}
public Call setId(String id) {
this.id = id;
return this;
}
public String getSource() {
return source;
}
public Call setSource(String source) {
this.source = source;
return this;
}
public List<String> getDetectPoints() {
return detectPoints;
}
public Call setDetectPoints(List<String> detectPoints) {
this.detectPoints = detectPoints;
return this;
}
public String getTarget() {
return target;
}
public Call setTarget(String target) {
this.target = target;
return this;
}
}
/*
* 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.topo;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.List;
import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
public class CallMatcher extends AbstractMatcher<Call> {
private String id;
private String source;
private List<String> detectPoints;
private String target;
@Override
public void verify(final Call call) {
if (Objects.nonNull(getId())) {
final String expected = this.getId();
final String actual = call.getId();
doVerify(expected, actual);
}
if (Objects.nonNull(getSource())) {
final String expected = this.getSource();
final String actual = call.getSource();
doVerify(expected, actual);
}
if (Objects.nonNull(getDetectPoints())) {
assertThat(getDetectPoints()).hasSameSizeAs(call.getDetectPoints());
int size = getDetectPoints().size();
for (int i = 0; i < size; i++) {
final String expected = getDetectPoints().get(i);
final String actual = call.getDetectPoints().get(i);
doVerify(expected, actual);
}
}
if (Objects.nonNull(getTarget())) {
final String expected = this.getTarget();
final String actual = call.getTarget();
doVerify(expected, actual);
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public List<String> getDetectPoints() {
return detectPoints;
}
public void setDetectPoints(List<String> detectPoints) {
this.detectPoints = detectPoints;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
}
/*
* 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.topo;
/**
* @author kezhenxu94
*/
public class Node {
private String id;
private String name;
private String type;
private String isReal;
public String getId() {
return id;
}
public Node setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Node setName(String name) {
this.name = name;
return this;
}
public String getType() {
return type;
}
public Node setType(String type) {
this.type = type;
return this;
}
public String getReal() {
return isReal;
}
public Node setIsReal(String real) {
isReal = real;
return this;
}
}
/*
* 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.topo;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.Objects;
/**
* @author kezhenxu94
*/
public class NodeMatcher extends AbstractMatcher<Node> {
private String id;
private String name;
private String type;
private String isReal;
@Override
public void verify(final Node node) {
if (Objects.nonNull(getId())) {
final String expected = this.getId();
final String actual = node.getId();
doVerify(expected, actual);
}
if (Objects.nonNull(getName())) {
final String expected = this.getName();
final String actual = node.getName();
doVerify(expected, actual);
}
if (Objects.nonNull(getType())) {
final String expected = this.getType();
final String actual = node.getType();
doVerify(expected, actual);
}
if (Objects.nonNull(getIsReal())) {
final String expected = this.getIsReal();
final String actual = String.valueOf(node.getReal());
doVerify(expected, actual);
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getIsReal() {
return isReal;
}
public void setIsReal(String isReal) {
this.isReal = isReal;
}
}
/*
* 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.topo;
import java.util.ArrayList;
import java.util.List;
/**
* @author kezhenxu94
*/
public class TopoData {
private List<Node> nodes;
private List<Call> calls;
public TopoData() {
nodes = new ArrayList<>();
calls = new ArrayList<>();
}
public List<Node> getNodes() {
return nodes;
}
public TopoData setNodes(List<Node> nodes) {
this.nodes = nodes;
return this;
}
public List<Call> getCalls() {
return calls;
}
public TopoData setCalls(List<Call> calls) {
this.calls = calls;
return this;
}
}
/*
* 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.topo;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.List;
import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
/**
* A simple matcher to verify the given {@code Service} is expected
*
* @author kezhenxu94
*/
public class TopoMatcher extends AbstractMatcher<TopoData> {
private List<NodeMatcher> nodes;
private List<CallMatcher> calls;
@Override
public void verify(final TopoData topoData) {
if (Objects.nonNull(getNodes())) {
verifyNodes(topoData);
}
if (Objects.nonNull(getCalls())) {
verifyCalls(topoData);
}
}
private void verifyNodes(TopoData topoData) {
assertThat(topoData.getNodes()).hasSameSizeAs(getNodes());
int size = getNodes().size();
for (int i = 0; i < size; i++) {
getNodes().get(i).verify(topoData.getNodes().get(i));
}
}
private void verifyCalls(TopoData topoData) {
assertThat(topoData.getCalls()).hasSameSizeAs(getCalls());
int size = getCalls().size();
for (int i = 0; i < size; i++) {
getCalls().get(i).verify(topoData.getCalls().get(i));
}
}
public List<NodeMatcher> getNodes() {
return nodes;
}
public void setNodes(List<NodeMatcher> nodes) {
this.nodes = nodes;
}
public List<CallMatcher> getCalls() {
return calls;
}
public void setCalls(List<CallMatcher> calls) {
this.calls = calls;
}
}
/*
* 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.topo;
import org.apache.skywalking.e2e.AbstractQuery;
/**
* @author kezhenxu94
*/
public class TopoQuery extends AbstractQuery<TopoQuery> {
}
/*
* 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.topo;
/**
* @author kezhenxu94
*/
public class TopoResponse {
private TopoData topo;
public TopoData getTopo() {
return topo;
}
public void setTopo(TopoData topo) {
this.topo = topo;
}
}
/*
* 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.trace;
import java.util.ArrayList;
import java.util.List;
/**
* @author kezhenxu94
*/
public class Trace {
private String key;
private final List<String> endpointNames;
private int duration;
private String start;
private boolean isError;
private final List<String> traceIds;
public Trace() {
this.endpointNames = new ArrayList<>();
this.traceIds = new ArrayList<>();
}
public String getKey() {
return key;
}
public Trace setKey(String key) {
this.key = key;
return this;
}
public List<String> getEndpointNames() {
return endpointNames;
}
public int getDuration() {
return duration;
}
public Trace setDuration(int duration) {
this.duration = duration;
return this;
}
public String getStart() {
return start;
}
public Trace setStart(String start) {
this.start = start;
return this;
}
public boolean isError() {
return isError;
}
public Trace setError(boolean error) {
isError = error;
return this;
}
public List<String> getTraceIds() {
return traceIds;
}
@Override
public String toString() {
return "Trace{" +
"key='" + key + '\'' +
", endpointNames=" + endpointNames +
", duration=" + duration +
", start='" + start + '\'' +
", isError=" + isError +
", traceIds=" + traceIds +
'}';
}
}
/*
* 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.trace;
import com.google.common.base.Strings;
import org.apache.skywalking.e2e.verification.AbstractMatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;
/**
* A simple matcher to verify the given {@code Trace} is expected
*
* @author kezhenxu94
*/
public class TraceMatcher extends AbstractMatcher<Trace> {
private String key;
private List<String> endpointNames;
private String duration;
private String start;
private String isError;
private List<String> traceIds;
@Override
public void verify(final Trace trace) {
if (Objects.nonNull(getKey())) {
verifyKey(trace);
}
if (Objects.nonNull(getEndpointNames())) {
verifyEndpointName(trace);
}
if (Objects.nonNull(getDuration())) {
verifyDuration(trace);
}
if (Objects.nonNull(getStart())) {
verifyStart(trace);
}
if (Objects.nonNull(getIsError())) {
verifyIsError(trace);
}
if (Objects.nonNull(getTraceIds())) {
verifyTraceIds(trace);
}
}
private void verifyKey(Trace trace) {
final String expected = this.getKey();
final String actual = trace.getKey();
doVerify(expected, actual);
}
private void verifyEndpointName(Trace trace) {
assertThat(trace.getEndpointNames()).hasSameSizeAs(getEndpointNames());
int size = getEndpointNames().size();
for (int i = 0; i < size; i++) {
final String expected = getEndpointNames().get(i);
final String actual = Strings.nullToEmpty(trace.getEndpointNames().get(i));
doVerify(expected, actual);
}
}
private void verifyDuration(Trace trace) {
final String expected = this.getDuration();
final String actual = String.valueOf(trace.getDuration());
doVerify(expected, actual);
}
private void verifyStart(Trace trace) {
final String expected = this.getStart();
final String actual = trace.getStart();
doVerify(expected, actual);
}
private void verifyIsError(Trace trace) {
final String expected = this.getIsError();
final String actual = Strings.nullToEmpty(String.valueOf(trace.isError()));
doVerify(expected, actual);
}
private void verifyTraceIds(Trace trace) {
assertThat(trace.getTraceIds()).hasSameSizeAs(getTraceIds());
int size = getTraceIds().size();
for (int i = 0; i < size; i++) {
final String expected = getTraceIds().get(i);
final String actual = trace.getTraceIds().get(i);
doVerify(expected, actual);
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public void setEndpointNames(List<String> endpointNames) {
this.endpointNames = endpointNames;
}
public List<String> getEndpointNames() {
return endpointNames != null ? endpointNames : new ArrayList<>();
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getIsError() {
return isError;
}
public void setIsError(String isError) {
this.isError = isError;
}
public void setTraceIds(List<String> traceIds) {
this.traceIds = traceIds;
}
public List<String> getTraceIds() {
return traceIds != null ? traceIds : new ArrayList<>();
}
}
/*
* 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.trace;
import java.util.List;
/**
* @author kezhenxu94
*/
public class TracesData {
public static class Traces {
private List<Trace> data;
public List<Trace> getData() {
return data;
}
public Traces setData(List<Trace> data) {
this.data = data;
return this;
}
}
private Traces traces;
public Traces getTraces() {
return traces;
}
public void setTraces(final Traces traces) {
this.traces = traces;
}
}
/*
* 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.trace;
import java.util.LinkedList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
public class TracesMatcher {
private List<TraceMatcher> traces;
public TracesMatcher() {
this.traces = new LinkedList<>();
}
public List<TraceMatcher> getTraces() {
return traces;
}
public void setTraces(List<TraceMatcher> traces) {
this.traces = traces;
}
public void verify(final List<Trace> traces) {
assertThat(traces).hasSameSizeAs(this.traces);
int size = this.traces.size();
for (int i = 0; i < size; i++) {
this.traces.get(i).verify(traces.get(i));
}
}
}
/*
* 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.trace;
import org.apache.skywalking.e2e.AbstractQuery;
/**
* @author kezhenxu94
*/
public class TracesQuery extends AbstractQuery<TracesQuery> {
private String traceState = "ALL";
private String pageNum = "1";
private String pageSize = "15";
private String needTotal = "true";
private String queryOrder = "BY_DURATION";
public String traceState() {
return traceState;
}
public TracesQuery traceState(String traceState) {
this.traceState = traceState;
return this;
}
public String pageNum() {
return pageNum;
}
public TracesQuery pageNum(String pageNum) {
this.pageNum = pageNum;
return this;
}
public TracesQuery pageNum(int pageNum) {
this.pageNum = String.valueOf(pageNum);
return this;
}
public String pageSize() {
return pageSize;
}
public TracesQuery pageSize(String pageSize) {
this.pageSize = pageSize;
return this;
}
public String needTotal() {
return needTotal;
}
public TracesQuery needTotal(boolean needTotal) {
this.needTotal = String.valueOf(needTotal);
return this;
}
public String queryOrder() {
return queryOrder;
}
public TracesQuery queryOrder(String queryOrder) {
this.queryOrder = queryOrder;
return this;
}
public TracesQuery orderByDuration() {
this.queryOrder = "BY_DURATION";
return this;
}
public TracesQuery pageSize(int pageSize) {
this.pageSize = String.valueOf(pageSize);
return this;
}
}
/*
* 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.verification;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
public abstract class AbstractMatcher<T> {
private static final Pattern NE_MATCHER = Pattern.compile("ne\\s+(?<val>.+)");
private static final Pattern GT_MATCHER = Pattern.compile("gt\\s+(?<val>.+)");
private static final Pattern GE_MATCHER = Pattern.compile("ge\\s+(?<val>.+)");
private static final Pattern NN_MATCHER = Pattern.compile("^not null$");
public abstract void verify(T t);
protected void doVerify(String expected, String actual) {
Matcher matcher = NN_MATCHER.matcher(expected);
if (matcher.find()) {
assertThat(actual).isNotNull();
return;
}
matcher = NE_MATCHER.matcher(expected);
if (matcher.find()) {
assertThat(actual).isNotEqualTo(matcher.group("val"));
return;
}
matcher = GT_MATCHER.matcher(expected);
if (matcher.find()) {
String val = matcher.group("val");
assertThat(val).isNotBlank();
assertThat(Double.parseDouble(actual)).isGreaterThan(Double.parseDouble(val));
return;
}
matcher = GE_MATCHER.matcher(expected);
if (matcher.find()) {
String val = matcher.group("val");
assertThat(val).isNotBlank();
assertThat(Double.parseDouble(actual)).isGreaterThanOrEqualTo(Double.parseDouble(val));
return;
}
assertThat(actual).isEqualTo(expected);
}
}
# 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.
{
"query":"query queryEndpoints($serviceId: ID!, $keyword: String!) {
endpoints: searchEndpoint(serviceId: $serviceId, keyword: $keyword, limit: 100) {
key: id
label: name
}
}",
"variables": {
"serviceId": "{serviceId}",
"keyword": ""
}
}
# 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.
{
"query":"query queryInstances($serviceId: ID!, $duration: Duration!) {
instances: getServiceInstances(duration: $duration, serviceId: $serviceId) {
key: id
label: name
attributes {
name
value
}
}
}",
"variables": {
"serviceId": "{serviceId}",
"duration": {
"start": "{start}",
"end": "{end}",
"step": "{step}"
}
}
}
# 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.
{
"query":"query ($id: ID!, $duration: Duration!) {
metrics: getLinearIntValues(metric: {
name: \"{metricsName}\"
id: $id
}, duration: $duration) {
values {
value
}
}
}",
"variables": {
"duration": {
"start": "{start}",
"end": "{end}",
"step": "{step}"
},
"id": "{id}"
}
}
# 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.
{
"query": "query queryServices($duration: Duration!) {
services: getAllServices(duration: $duration) {
key: id
label: name
}
}",
"variables": {
"duration": {
"start": "{start}",
"end": "{end}",
"step": "{step}"
}
}
}
# 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.
{
"query": "query queryTopo($duration: Duration!) {
topo: getGlobalTopology(duration: $duration) {
nodes {
id
name
type
isReal
}
calls {
id
source
detectPoints
target
}
}
}",
"variables": {
"duration": {
"start": "{start}",
"end": "{end}",
"step": "{step}"
}
}
}
# 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.
{
"query": "query queryTraces($condition: TraceQueryCondition) {
traces: queryBasicTraces(condition: $condition) {
data: traces {
key: segmentId endpointNames duration start isError traceIds
}
total
}
}",
"variables": {
"condition": {
"queryDuration": {
"start": "{start}",
"end": "{end}",
"step": "{step}"
},
"traceState": "{traceState}",
"paging": {
"pageNum": {pageNum},
"pageSize": {pageSize},
"needTotal": {needTotal}
},
"queryOrder": "{queryOrder}"
}
}
}
/*
* 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 org.apache.skywalking.e2e.trace.Trace;
import org.apache.skywalking.e2e.trace.TraceMatcher;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.io.InputStream;
/**
* @author kezhenxu94
*/
public class TestMatcher {
private InputStream expectedInputStream;
private TraceMatcher traceMatcher;
@Before
public void setUp() throws IOException {
expectedInputStream = new ClassPathResource("test.yml").getInputStream();
traceMatcher = new Yaml().loadAs(expectedInputStream, TraceMatcher.class);
}
@Test
public void shouldSuccess() {
final Trace trace = new Trace()
.setKey("abc")
.setStart("1")
.setError(false);
trace.getEndpointNames().add("e2e/test");
trace.getTraceIds().add("id1");
trace.getTraceIds().add("id2");
traceMatcher.verify(trace);
}
@Test(expected = AssertionError.class)
public void shouldVerifyNotNull() {
final Trace trace = new Trace()
.setStart("1")
.setError(false);
trace.getEndpointNames().add("e2e/test");
trace.getTraceIds().add("id1");
trace.getTraceIds().add("id2");
traceMatcher.verify(trace);
}
@Test(expected = AssertionError.class)
public void shouldVerifyGreaterOrEqualTo() {
final Trace trace = new Trace()
.setKey("abc")
.setDuration(-1)
.setStart("1")
.setError(false);
trace.getEndpointNames().add("e2e/test");
trace.getTraceIds().add("id1");
trace.getTraceIds().add("id2");
traceMatcher.verify(trace);
}
@Test(expected = AssertionError.class)
public void shouldVerifyGreaterThan() {
final Trace trace = new Trace()
.setKey("abc")
.setDuration(1)
.setStart("0")
.setError(false);
trace.getEndpointNames().add("e2e/test");
trace.getTraceIds().add("id1");
trace.getTraceIds().add("id2");
traceMatcher.verify(trace);
}
}
/*
* 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 org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
import org.apache.skywalking.e2e.metrics.Metrics;
import org.apache.skywalking.e2e.metrics.MetricsValue;
import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
import org.junit.Test;
/**
* @author kezhenxu94
*/
public class TestMetricsMatcher {
@Test
public void shouldVerifyOneOf() {
Metrics metrics = new Metrics();
metrics.getValues().add(new MetricsValue().setValue("12"));
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(metrics);
}
@Test(expected = AssertionError.class)
public void shouldFailedVerifyOneOf() {
Metrics metrics = new Metrics();
metrics.getValues().add(new MetricsValue().setValue("0"));
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(metrics);
}
}
# 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.
# 1 health-check by docker-maven-plugin
# 1 drop table if exists, because we have `ddl-auto: create-drop`
# 1 drop sequence
# 1 create sequence
# 1 create table statement
key: not null
endpointNames:
- e2e/test
duration: ge 0
start: gt 0
isError: false
traceIds:
- id1
- id2
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apache-skywalking-e2e</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>e2e-single-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-base</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<executable>true</executable>
<addResources>true</addResources>
<excludeDevtools>true</excludeDevtools>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t</containerNamePattern>
<images>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>skywalking-e2e-container-${build.id}</alias>
<run>
<env>
<INSTRUMENTED_SERVICE>${project.build.finalName}.jar</INSTRUMENTED_SERVICE>
</env>
<ports>
<port>+webapp.host:webapp.port:8080</port>
<port>+client.host:client.port:9090</port>
</ports>
<volumes>
<bind>
<volume>
${project.basedir}/../../../dist/apache-skywalking-apm-bin:/skywalking
</volume>
<volume>
${project.build.directory}:/home
</volume>
</bind>
</volumes>
<wait>
<http>
<url>
http://${docker.host.address}:${client.port}/e2e/health-check
</url>
<method>GET</method>
<status>200</status>
</http>
<time>300000</time>
</wait>
</run>
</image>
</images>
</configuration>
</plugin>
<!-- set the system properties that can be used in test codes -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<sw.webapp.host>
${webapp.host}
</sw.webapp.host>
<sw.webapp.port>
${webapp.port}
</sw.webapp.port>
<client.host>
${client.host}
</client.host>
<client.port>
${client.port}
</client.port>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* 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.sample.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
* @author kezhenxu94
*/
@EnableJpaRepositories
@SpringBootApplication
public class SampleClientApplication {
public static void main(String[] args) {
SpringApplication.run(SampleClientApplication.class, args);
}
}
/*
* 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.sample.client;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author kezhenxu94
*/
@RestController
@RequestMapping("/e2e")
public class TestController {
private final UserRepo userRepo;
public TestController(final UserRepo userRepo) {
this.userRepo = userRepo;
}
@GetMapping("/health-check")
public String hello() {
return "healthy";
}
@PostMapping("/users")
public User createAuthor(@RequestBody final User user) {
return userRepo.save(user);
}
}
/*
* 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.sample.client;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author kezhenxu94
*/
@Entity
public class User {
public User() {
}
@Id
@GeneratedValue
private Long id;
@Column
private String name;
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}
/*
* 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.sample.client;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author kezhenxu94
*/
public interface UserRepo extends JpaRepository<User, Long> {
}
# 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.
server:
port: 9090
spring:
main:
banner-mode: 'off'
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
data-username: sa
password: sa
platform: org.hibernate.dialect.H2Dialect
jpa:
generate-ddl: true
hibernate:
ddl-auto: create-drop
properties:
hibernate.format_sql: true
show-sql: true
/*
* 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 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.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.TopoData;
import org.apache.skywalking.e2e.topo.TopoMatcher;
import org.apache.skywalking.e2e.topo.TopoQuery;
import org.apache.skywalking.e2e.trace.Trace;
import org.apache.skywalking.e2e.trace.TracesMatcher;
import org.apache.skywalking.e2e.trace.TracesQuery;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.client.RestTemplate;
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ENDPOINT_P50;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ENDPOINT_P75;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ENDPOINT_P90;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ENDPOINT_P95;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.ENDPOINT_P99;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_INSTANCE_CPM;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_INSTANCE_RESP_TIME;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_INSTANCE_SLA;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_P50;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_P75;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_P90;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_P95;
import static org.apache.skywalking.e2e.metrics.MetricsQuery.SERVICE_P99;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author kezhenxu94
*/
@RunWith(SpringJUnit4ClassRunner.class)
public class SampleVerificationITCase {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleVerificationITCase.class);
private final RestTemplate restTemplate = new RestTemplate();
private SimpleQueryClient queryClient;
private String instrumentedServiceUrl;
@Before
public void setUp() {
final String swWebappHost = System.getProperty("sw.webapp.host", "127.0.0.1");
final String swWebappPort = System.getProperty("sw.webapp.port", "32783");
final String instrumentedServiceHost0 = System.getProperty("client.host", "127.0.0.1");
final String instrumentedServicePort0 = System.getProperty("client.port", "32782");
final String queryClientUrl = "http://" + swWebappHost + ":" + swWebappPort + "/graphql";
queryClient = new SimpleQueryClient(queryClientUrl);
instrumentedServiceUrl = "http://" + instrumentedServiceHost0 + ":" + instrumentedServicePort0;
}
@Test
@DirtiesContext
public void verify() throws Exception {
final LocalDateTime minutesAgo = LocalDateTime.now(ZoneOffset.UTC);
final Map<String, String> user = new HashMap<>();
user.put("name", "SkyWalking");
final ResponseEntity<String> responseEntity = restTemplate.postForEntity(
instrumentedServiceUrl + "/e2e/users",
user,
String.class
);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
Thread.sleep(5000);
verifyTraces(minutesAgo);
verifyServices(minutesAgo);
verifyTopo(minutesAgo);
}
private void verifyTopo(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final TopoData topoData = queryClient.topo(
new TopoQuery()
.step("MINUTE")
.start(minutesAgo.minusDays(1))
.end(now)
);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.topo.yml").getInputStream();
final TopoMatcher topoMatcher = new Yaml().loadAs(expectedInputStream, TopoMatcher.class);
topoMatcher.verify(topoData);
}
private void verifyServices(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final List<Service> services = queryClient.services(
new ServicesQuery()
.start(minutesAgo)
.end(now)
);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.services.yml").getInputStream();
final ServicesMatcher servicesMatcher = new Yaml().loadAs(expectedInputStream, ServicesMatcher.class);
servicesMatcher.verify(services);
for (Service service : services) {
LOGGER.info("verifying service instances: {}", service);
verifyServiceMetrics(service);
Instances instances = verifyServiceInstances(minutesAgo, now, service);
verifyInstancesMetrics(instances);
Endpoints endpoints = verifyServiceEndpoints(minutesAgo, now, service);
verifyEndpointsMetrics(endpoints);
}
}
private Instances verifyServiceInstances(LocalDateTime minutesAgo, LocalDateTime now, Service service) throws Exception {
InputStream expectedInputStream;
Instances instances = queryClient.instances(
new InstancesQuery()
.serviceId(service.getKey())
.start(minutesAgo)
.end(now)
);
expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.instances.yml").getInputStream();
final InstancesMatcher instancesMatcher = new Yaml().loadAs(expectedInputStream, InstancesMatcher.class);
instancesMatcher.verify(instances);
return instances;
}
private Endpoints verifyServiceEndpoints(LocalDateTime minutesAgo, LocalDateTime now, Service service) throws Exception {
Endpoints instances = queryClient.endpoints(
new EndpointQuery().serviceId(service.getKey())
);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.endpoints.yml").getInputStream();
final EndpointsMatcher endpointsMatcher = new Yaml().loadAs(expectedInputStream, EndpointsMatcher.class);
endpointsMatcher.verify(instances);
return instances;
}
private void verifyInstancesMetrics(Instances instances) throws Exception {
final String[] instanceMetricsNames = new String[] {
SERVICE_INSTANCE_RESP_TIME,
SERVICE_INSTANCE_CPM,
SERVICE_INSTANCE_SLA
};
for (Instance instance : instances.getInstances()) {
for (String metricsName : instanceMetricsNames) {
LOGGER.info("verifying service instance response time: {}", instance);
final Metrics instanceRespTime = queryClient.metrics(
new MetricsQuery()
.step("MINUTE")
.metricsName(metricsName)
.id(instance.getKey())
);
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(instanceRespTime);
LOGGER.info("{}: {}", metricsName, instanceRespTime);
}
}
}
private void verifyEndpointsMetrics(Endpoints endpoints) throws Exception {
final String[] endpointMetricsNames = {
ENDPOINT_P99,
ENDPOINT_P95,
ENDPOINT_P90,
ENDPOINT_P75,
ENDPOINT_P50
};
for (Endpoint endpoint : endpoints.getEndpoints()) {
if (!endpoint.getLabel().equals("/e2e/users")) {
continue;
}
for (String metricName : endpointMetricsNames) {
LOGGER.info("verifying endpoint {}, metrics: {}", endpoint, metricName);
final Metrics metrics = queryClient.metrics(
new MetricsQuery()
.step("MINUTE")
.metricsName(metricName)
.id(endpoint.getKey())
);
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(metrics);
LOGGER.info("metrics: {}", metrics);
}
}
}
private void verifyServiceMetrics(Service service) throws Exception {
final String[] serviceMetrics = {
SERVICE_P99,
SERVICE_P95,
SERVICE_P90,
SERVICE_P75,
SERVICE_P50
};
for (String metricName : serviceMetrics) {
LOGGER.info("verifying service {}, metrics: {}", service, metricName);
final Metrics instanceRespTime = queryClient.metrics(
new MetricsQuery()
.step("MINUTE")
.metricsName(metricName)
.id(service.getKey())
);
AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
greaterThanZero.setValue("gt 0");
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(instanceRespTime);
LOGGER.info("instanceRespTime: {}", instanceRespTime);
}
}
private void verifyTraces(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final List<Trace> traces = queryClient.traces(
new TracesQuery()
.start(minutesAgo)
.end(now)
.orderByDuration()
);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.traces.yml").getInputStream();
final TracesMatcher tracesMatcher = new Yaml().loadAs(expectedInputStream, TracesMatcher.class);
tracesMatcher.verify(traces);
}
}
# 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.
# 1 health-check by docker-maven-plugin
# 1 drop table if exists, because we have `ddl-auto: create-drop`
# 1 drop sequence
# 1 create sequence
# 1 create table statement
endpoints:
- key: not null
label: /e2e/health-check
- key: not null
label: /e2e/users
# 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.
# 1 health-check by docker-maven-plugin
# 1 drop table if exists, because we have `ddl-auto: create-drop`
# 1 drop sequence
# 1 create sequence
# 1 create table statement
instances:
- key: 2
label: not null
attributes:
- name: os_name
value: not null
- name: host_name
value: not null
- name: process_no
value: gt 0
- name: ipv4s
value: not null
# 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.
# 1 health-check by docker-maven-plugin
# 1 drop table if exists, because we have `ddl-auto: create-drop`
# 1 drop sequence
# 1 create sequence
# 1 create table statement
services:
- key: 2
label: "Your_ApplicationName"
# 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.
# 1 health-check by docker-maven-plugin
# 1 drop table if exists, because we have `ddl-auto: create-drop`
# 1 drop sequence
# 1 create sequence
# 1 create table statement
nodes:
- id: 1
name: User
type: USER
isReal: false
- id: 2
name: Your_ApplicationName
type: Tomcat
isReal: true
- id: 3
name: "localhost:-1"
type: H2
isReal: false
calls:
- id: 2_3
source: 2
detectPoints:
- CLIENT
target: 3
- id: 1_2
source: 1
detectPoints:
- SERVER
target: 2
# 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.
# 1 health-check by docker-maven-plugin
# 1 drop table if exists, because we have `ddl-auto: create-drop`
# 1 drop sequence
# 1 create sequence
# 1 create table statement
traces:
- key: not null
endpointNames:
- /e2e/users
duration: ge 0
start: gt 0
isError: false
traceIds:
- not null
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.skywalking</groupId>
<artifactId>apache-skywalking-e2e</artifactId>
<version>1.0.0</version>
<name>SkyWalking End to End Tests</name>
<packaging>pom</packaging>
<modules>
<module>e2e-base</module>
<module>e2e-single-service</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>2.1.5.RELEASE</spring.boot.version>
<faster.jackson.version>2.9.7</faster.jackson.version>
<junit.version>4.12</junit.version>
<jackson.version>2.9.7</jackson.version>
<guava.version>28.0-jre</guava.version>
<snake.version>1.23</snake.version>
<gson.version>2.8.5</gson.version>
<h2.version>1.4.199</h2.version>
<!-- build.id is an available environment variable in Jenkins to
distinguish the different build jobs, once Jenkins job is aborted,
we will use this build.id to stop all containers that are started
during this specific build, see Jenkins-E2E (post stage) for detail
-->
<build.id>local</build.id>
<e2e.container.version>1.0.0</e2e.container.version>
<maven-failsafe-plugin.version>2.22.0</maven-failsafe-plugin.version>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
<docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker-maven-plugin.version}</version>
<configuration>
<sourceMode>all</sourceMode>
<showLogs>true</showLogs>
<logDate>default</logDate>
<imagePullPolicy>IfNotPresent</imagePullPolicy>
</configuration>
<executions>
<execution>
<id>start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册