diff --git a/Jenkinsfile-E2E b/Jenkinsfile-E2E
index 63f2ca99450000fe1879e951579442b5793614ff..cf767edc6fbd6655229a014dff55649325aeb628 100755
--- a/Jenkinsfile-E2E
+++ b/Jenkinsfile-E2E
@@ -83,6 +83,12 @@ pipeline {
sh 'E2E_VERSION=jdk8-1.3 bash -x test/e2e/run.sh e2e-single-service'
}
}
+
+ stage('Single Node Tests(MySQL/JDK8)') {
+ steps {
+ sh 'E2E_VERSION=jdk8-1.3 bash -x test/e2e/run.sh e2e-mysql'
+ }
+ }
stage('Single Node Tests(JDK9)') {
steps {
diff --git a/test/e2e/e2e-mysql/pom.xml b/test/e2e/e2e-mysql/pom.xml
new file mode 100755
index 0000000000000000000000000000000000000000..6406222d351a8a67fd223d0fe46aeda03174b56b
--- /dev/null
+++ b/test/e2e/e2e-mysql/pom.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+ apache-skywalking-e2e
+ org.apache.skywalking
+ 1.0.0
+
+
+ 4.0.0
+
+ e2e-mysql
+
+
+ skywalking-e2e-container-${build.id}-single-node-mysql
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ ${spring.boot.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+
+ org.apache.skywalking
+ e2e-base
+ ${project.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring.boot.version}
+
+ true
+ true
+ true
+
+
+
+
+ repackage
+
+
+
+
+
+ io.fabric8
+ docker-maven-plugin
+
+ %a-%t-%i
+
+
+ mysql/mysql-server:${mysql.version}
+ ${e2e.container.name.prefix}-mysql
+
+
+ Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 3306
+
+
+
+ root@1234
+ swtest
+ %
+
+
+ mysql.port:3306
+
+
+
+
+ skyapm/e2e-container:${e2e.container.version}
+ ${e2e.container.name.prefix}
+
+
+ ${project.build.finalName}.jar
+ jdbc:mysql://${e2e.container.name.prefix}-mysql:3306/swtest
+
+
+ ${e2e.container.name.prefix}-mysql
+
+
+ ${e2e.container.name.prefix}-mysql
+
+
+ +webapp.host:webapp.port:8081
+ +client.host:client.port:9090
+
+
+
+ ${sw.home}:/sw
+ ${project.build.directory}:/home
+ ${project.basedir}/src/docker/rc.d:/rc.d:ro
+
+
+
+
+
+ http://${docker.host.address}:${client.port}/e2e/health-check
+
+ GET
+ 200
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+
+ ${webapp.host}
+
+
+ ${webapp.port}
+
+
+ ${client.host}
+
+
+ ${client.port}
+
+
+
+
+
+
+ verify
+
+
+
+
+
+
+
diff --git a/test/e2e/e2e-mysql/src/docker/rc.d/rc0-prepare.sh b/test/e2e/e2e-mysql/src/docker/rc.d/rc0-prepare.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a3224a7f605dd5de8eeb79a80b30d8184cd99b3e
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/docker/rc.d/rc0-prepare.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+# Licensed to the SkyAPM 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.
+
+MYSQL_URL="http://central.maven.org/maven2/mysql/mysql-connector-java/8.0.13/mysql-connector-java-8.0.13.jar"
+MYSQL_DRIVER="mysql-connector-java-8.0.13.jar"
+TMP_APP_YML="tmp_app.yml"
+
+echo "MySQL database is storage provider..."
+# Download MySQL connector.
+curl ${MYSQL_URL} > "${SW_HOME}/oap-libs/${MYSQL_DRIVER}"
+[[ $? -ne 0 ]] && echo "Fail to download ${MYSQL_DRIVER}." && exit 1
+
+# Modify application.yml to set MySQL as storage provider.
+cat "${SW_HOME}/config/application.yml" | sed '/elasticsearch/,/mysql/d' | sed "/storage:/a \ mysql:" | sed "/storage:/,/receiver-sharing-server:/s/#//" > ${TMP_APP_YML}
+cat ${TMP_APP_YML} > "${SW_HOME}/config/application.yml"
+rm -f ${TMP_APP_YML}
diff --git a/test/e2e/e2e-mysql/src/docker/rc.d/rc1-startup.sh b/test/e2e/e2e-mysql/src/docker/rc.d/rc1-startup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f9382e4343c619048596875fddf933d8d5cfd38b
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/docker/rc.d/rc1-startup.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+# Licensed to the SkyAPM 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.
+
+echo 'starting OAP server...' && start_oap 'init'
+
+echo 'starting Web app...' && start_webapp '0.0.0.0' 8081
+
+echo 'starting instrumented services...' && start_instrumented_services
+
+check_tcp 127.0.0.1 \
+ 9090 \
+ 60 \
+ 10 \
+ "waiting for the instrumented service to be ready"
+
+if [[ $? -ne 0 ]]; then
+ echo "instrumented service 0 failed to start in 30 * 10 seconds: "
+ cat ${SERVICE_LOG}/*
+ exit 1
+fi
+
+echo "SkyWalking e2e container is ready for tests"
+
+tail -f ${OAP_LOG_DIR}/* \
+ ${WEBAPP_LOG_DIR}/* \
+ ${SERVICE_LOG}/*
diff --git a/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/SampleClientApplication.java b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/SampleClientApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..a55dbd685769d4033780cfed97becf8b0258a097
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/SampleClientApplication.java
@@ -0,0 +1,34 @@
+/*
+ * 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);
+ }
+}
diff --git a/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/TestController.java b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/TestController.java
new file mode 100644
index 0000000000000000000000000000000000000000..566bcdea4aa9aa67da3db8ecd031a19cb63c50e3
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/TestController.java
@@ -0,0 +1,49 @@
+/*
+ * 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) throws InterruptedException {
+ Thread.sleep(1000L);
+ return userRepo.save(user);
+ }
+}
diff --git a/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/User.java b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..4589c7f2c424632c9387f031bb2870329064869a
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/User.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+ }
+}
diff --git a/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/UserRepo.java b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/UserRepo.java
new file mode 100644
index 0000000000000000000000000000000000000000..882af92a82117e6250a626b870516fd5a64f606d
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/main/java/org/apache/skywalking/e2e/sample/client/UserRepo.java
@@ -0,0 +1,27 @@
+/*
+ * 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 {
+}
diff --git a/test/e2e/e2e-mysql/src/main/resources/application.yml b/test/e2e/e2e-mysql/src/main/resources/application.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ef3ed01cd41127298e112d5fad0dae7714aadc3d
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/main/resources/application.yml
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+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
diff --git a/test/e2e/e2e-mysql/src/test/java/org/apache/skywalking/e2e/SampleVerificationITCase.java b/test/e2e/e2e-mysql/src/test/java/org/apache/skywalking/e2e/SampleVerificationITCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..68a4070899021bbf02d58c803d63961f9339abe9
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/test/java/org/apache/skywalking/e2e/SampleVerificationITCase.java
@@ -0,0 +1,316 @@
+/*
+ * 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.ALL_ENDPOINT_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_INSTANCE_METRICS;
+import static org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_SERVICE_METRICS;
+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 final int retryInterval = 30;
+
+ 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 instrumentedServiceHost = System.getProperty("client.host", "127.0.0.1");
+ final String instrumentedServicePort = System.getProperty("client.port", "32782");
+ queryClient = new SimpleQueryClient(swWebappHost, swWebappPort);
+ instrumentedServiceUrl = "http://" + instrumentedServiceHost + ":" + instrumentedServicePort;
+ }
+
+ @Test
+ @DirtiesContext
+ public void verify() throws Exception {
+ final LocalDateTime minutesAgo = LocalDateTime.now(ZoneOffset.UTC);
+
+ while (true) {
+ try {
+ final Map user = new HashMap<>();
+ user.put("name", "SkyWalking");
+ final ResponseEntity responseEntity = restTemplate.postForEntity(
+ instrumentedServiceUrl + "/e2e/users",
+ user,
+ String.class
+ );
+ LOGGER.info("responseEntity: {}", responseEntity);
+ assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
+ final List traces = queryClient.traces(
+ new TracesQuery()
+ .start(minutesAgo)
+ .end(LocalDateTime.now())
+ .orderByDuration()
+ );
+ if (!traces.isEmpty()) {
+ break;
+ }
+ Thread.sleep(10000L);
+ } catch (Exception ignored) {
+ }
+ }
+
+ doRetryableVerification(() -> {
+ try {
+ verifyTraces(minutesAgo);
+ } catch (Exception e) {
+ LOGGER.warn(e.getMessage(), e);
+ }
+ });
+
+ doRetryableVerification(() -> {
+ try {
+ verifyServices(minutesAgo);
+ } catch (Exception e) {
+ LOGGER.warn(e.getMessage(), e);
+ }
+ });
+
+ doRetryableVerification(() -> {
+ try {
+ verifyTopo(minutesAgo);
+ } catch (Exception e) {
+ LOGGER.warn(e.getMessage(), e);
+ }
+ });
+ }
+
+ private void verifyTopo(LocalDateTime minutesAgo) throws Exception {
+ final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
+
+ final TopoData topoData = queryClient.topo(
+ new TopoQuery()
+ .stepByMinute()
+ .start(minutesAgo.minusDays(1))
+ .end(now)
+ );
+ LOGGER.info("topoData: {}", topoData);
+
+ 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 services = queryClient.services(
+ new ServicesQuery()
+ .start(minutesAgo)
+ .end(now)
+ );
+ LOGGER.info("services: {}", services);
+
+ 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)
+ );
+ LOGGER.info("instances: {}", instances);
+ 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())
+ );
+ LOGGER.info("instances: {}", instances);
+ 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 {
+ for (Instance instance : instances.getInstances()) {
+ for (String metricsName : ALL_INSTANCE_METRICS) {
+ LOGGER.info("verifying service instance response time: {}", instance);
+ final Metrics instanceMetrics = queryClient.metrics(
+ new MetricsQuery()
+ .stepByMinute()
+ .metricsName(metricsName)
+ .id(instance.getKey())
+ );
+ LOGGER.info("instanceMetrics: {}", instanceMetrics);
+ AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
+ MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(instanceMetrics);
+ LOGGER.info("{}: {}", metricsName, instanceMetrics);
+ }
+ }
+ }
+
+ private void verifyEndpointsMetrics(Endpoints endpoints) throws Exception {
+ for (Endpoint endpoint : endpoints.getEndpoints()) {
+ if (!endpoint.getLabel().equals("/e2e/users")) {
+ continue;
+ }
+ for (String metricName : ALL_ENDPOINT_METRICS) {
+ LOGGER.info("verifying endpoint {}, metrics: {}", endpoint, metricName);
+ final Metrics metrics = queryClient.metrics(
+ new MetricsQuery()
+ .stepByMinute()
+ .metricsName(metricName)
+ .id(endpoint.getKey())
+ );
+ LOGGER.info("metrics: {}", metrics);
+ AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
+ MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(metrics);
+ LOGGER.info("{}: {}", metricName, metrics);
+ }
+ }
+ }
+
+ private void verifyServiceMetrics(Service service) throws Exception {
+ for (String metricName : ALL_SERVICE_METRICS) {
+ LOGGER.info("verifying service {}, metrics: {}", service, metricName);
+ final Metrics serviceMetrics = queryClient.metrics(
+ new MetricsQuery()
+ .stepByMinute()
+ .metricsName(metricName)
+ .id(service.getKey())
+ );
+ LOGGER.info("serviceMetrics: {}", serviceMetrics);
+ AtLeastOneOfMetricsMatcher instanceRespTimeMatcher = new AtLeastOneOfMetricsMatcher();
+ MetricsValueMatcher greaterThanZero = new MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(serviceMetrics);
+ LOGGER.info("{}: {}", metricName, serviceMetrics);
+ }
+ }
+
+ private void verifyTraces(LocalDateTime minutesAgo) throws Exception {
+ final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
+
+ final List traces = queryClient.traces(
+ new TracesQuery()
+ .start(minutesAgo)
+ .end(now)
+ .orderByDuration()
+ );
+ LOGGER.info("traces: {}", traces);
+
+ 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);
+ }
+
+ private void doRetryableVerification(Runnable runnable) throws InterruptedException {
+ while (true) {
+ try {
+ runnable.run();
+ break;
+ } catch (Throwable ignored) {
+ Thread.sleep(retryInterval);
+ }
+ }
+ }
+}
diff --git a/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.endpoints.yml b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.endpoints.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a1f5b450af380a8b16eda893abf5d39d6adb0cb1
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.endpoints.yml
@@ -0,0 +1,27 @@
+# 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
diff --git a/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.instances.yml b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.instances.yml
new file mode 100644
index 0000000000000000000000000000000000000000..26bb314d2b5d486a486b158349d80cde573e77a6
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.instances.yml
@@ -0,0 +1,34 @@
+# 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
diff --git a/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.services.yml b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.services.yml
new file mode 100644
index 0000000000000000000000000000000000000000..07ff835878d8a6f111bce16ec743236184814220
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.services.yml
@@ -0,0 +1,25 @@
+# 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"
diff --git a/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.topo.yml b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.topo.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3a455f5b60c8f29b41989fb8f2b5e5016fb9d249
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.topo.yml
@@ -0,0 +1,46 @@
+# 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
diff --git a/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.traces.yml b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.traces.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2052aad3acd3776b972a62b321a77064cc278e4e
--- /dev/null
+++ b/test/e2e/e2e-mysql/src/test/resources/expected-data/org.apache.skywalking.e2e.SampleVerificationITCase.traces.yml
@@ -0,0 +1,31 @@
+# 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
diff --git a/test/e2e/pom.xml b/test/e2e/pom.xml
index 28be321069de7a4dc0d2b48d8ff36ddb2f35497d..204be6e92340a956ff1a878e898a934e608b13b6 100644
--- a/test/e2e/pom.xml
+++ b/test/e2e/pom.xml
@@ -34,6 +34,7 @@
e2e-basee2e-single-service
+ e2e-mysqle2e-clustere2e-agent-reboote2e-ttl
@@ -55,6 +56,7 @@
1.232.8.51.4.199
+ 8.0.136.3.23.51.18.4
diff --git a/test/e2e/run.sh b/test/e2e/run.sh
index 940092485d927349fbd1049425597838002c7b33..5c76cecc269d8af99ce6f02545f761984b264fa3 100755
--- a/test/e2e/run.sh
+++ b/test/e2e/run.sh
@@ -59,7 +59,7 @@ do
# Some of the tests will modify files in the distribution folder, e.g. cluster test will modify the application.yml
# so we give each test a separate distribution folder here
mkdir -p "$test_case" && tar -zxf dist/apache-skywalking-apm-bin.tar.gz -C "$test_case"
-
+
./mvnw -Dbuild.id="${BUILD_ID:-local}" -De2e.container.version="${E2E_VERSION}" -Dsw.home="${base_dir}/$test_case/apache-skywalking-apm-bin" -f test/e2e/pom.xml -pl "$test_case" -am verify
status_code=$?