提交 8e4c1e95 编写于 作者: 静夜思朝颜's avatar 静夜思朝颜 提交者: kezhenxu94

Merge e2e profile test project (#4268)

* merge e2e profile test project, Use `env` to distinguish different storage types

* remove maven child module

* change `env` -> `storage`
Co-authored-by: Nkezhenxu94 <kezhenxu94@163.com>
上级 75aefd34
......@@ -111,10 +111,10 @@ jobs:
./mvnw -Dcheckstyle.skip -Drat.skip -T2 -Dmaven.compile.fork -Dmaven.compiler.maxmem=3072 -DskipTests clean install
./mvnw -f test/e2e/pom.xml -pl e2e-base clean install
- name: Profile Tests H2(JDK8)
run: export E2E_VERSION=jdk8-1.3 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-h2-test-runner
run: export E2E_VERSION=jdk8-1.3 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-test-runner --storage=h2
- name: Profile Tests MySQL(JDK8)
run: export E2E_VERSION=jdk8-1.3 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-mysql-test-runner
run: export E2E_VERSION=jdk8-1.3 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-test-runner --storage=mysql
- name: Profile Tests ES6(JDK8)
run: export E2E_VERSION=jdk8-1.3 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-es-test-runner
run: export E2E_VERSION=jdk8-1.3 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-test-runner --storage=elasticsearch
- name: Profile Tests ES7(JDK8)
run: export E2E_VERSION=jdk8-1.3 DIST_PACKAGE=apache-skywalking-apm-bin-es7.tar.gz ES_VERSION=7.4.2 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-es-test-runner
run: export E2E_VERSION=jdk8-1.3 DIST_PACKAGE=apache-skywalking-apm-bin-es7.tar.gz ES_VERSION=7.4.2 && bash -x test/e2e/run.sh e2e-profile/e2e-profile-test-runner --storage=elasticsearch
<?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>e2e-profile</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>e2e-profile-es-test-runner</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-profile-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-profile-test-runner</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<properties>
<provider.name>e2e-profile-service</provider.name>
<e2e.container.version>1.1</e2e.container.version>
<e2e.container.name.prefix>skywalking-e2e-container-${build.id}-es-profile</e2e.container.name.prefix>
</properties>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t-%i</containerNamePattern>
<imagePullPolicy>Always</imagePullPolicy>
<images>
<image>
<name>elastic/elasticsearch:${elasticsearch.version}</name>
<alias>${e2e.container.name.prefix}-elasticsearch</alias>
<run>
<ports>
<port>es.port:9200</port>
</ports>
<wait>
<http>
<url>http://localhost:${es.port}</url>
<method>GET</method>
<status>200</status>
</http>
<time>120000</time>
</wait>
<env>
<discovery.type>single-node</discovery.type>
</env>
</run>
</image>
<image>
<name>zookeeper:${zookeeper.image.version}</name>
<alias>${e2e.container.name.prefix}-zookeeper</alias>
<run>
<ports>
<port>zk.port:2181</port>
</ports>
<wait>
<log>binding to port</log>
<time>120000</time>
</wait>
</run>
</image>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>${e2e.container.name.prefix}</alias>
<run>
<env>
<MODE>cluster</MODE>
<ES_VERSION>${elasticsearch.version}</ES_VERSION>
<SW_STORAGE_ES_CLUSTER_NODES>
${e2e.container.name.prefix}-elasticsearch:9200
</SW_STORAGE_ES_CLUSTER_NODES>
<SW_CLUSTER_ZK_HOST_PORT>
${e2e.container.name.prefix}-zookeeper:2181
</SW_CLUSTER_ZK_HOST_PORT>
<INSTRUMENTED_SERVICE_1>
${provider.name}-${project.version}.jar
</INSTRUMENTED_SERVICE_1>
<INSTRUMENTED_SERVICE_1_OPTS>
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_PROFILE_ACTIVE=true
-DSW_AGENT_NAME=${provider.name}
-Dserver.port=9090
</INSTRUMENTED_SERVICE_1_OPTS>
</env>
<dependsOn>
<container>${e2e.container.name.prefix}-elasticsearch</container>
<container>${e2e.container.name.prefix}-zookeeper</container>
</dependsOn>
<ports>
<port>+webapp.host:webapp.port:8081</port>
<port>+service.host:service.port:9090</port>
</ports>
<links>
<link>${e2e.container.name.prefix}-elasticsearch</link>
<link>${e2e.container.name.prefix}-zookeeper</link>
</links>
<volumes>
<bind>
<volume>${sw.home}:/sw</volume>
<volume>
../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar
</volume>
<volume>
${project.basedir}/src/docker/rc.d:/rc.d:ro
</volume>
<volume>
${project.basedir}/src/docker/clusterize.awk:/clusterize.awk
</volume>
</bind>
</volumes>
<wait>
<log>SkyWalking e2e container is ready for tests</log>
<time>3000000</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>
<service.host>${service.host}</service.host>
<service.port>${service.port}</service.port>
<provider.name>${provider.name}</provider.name>
<consumer.name>${consumer.name}</consumer.name>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
#!/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...' \
&& SW_STORAGE_ES_BULK_ACTIONS=1 \
SW_STORAGE_ES_FLUSH_INTERVAL=1 \
SW_RECEIVER_BUFFER_PATH=/tmp/oap/trace_buffer1 \
SW_SERVICE_MESH_BUFFER_PATH=/tmp/oap/mesh_buffer1 \
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 0 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}/* \
${ES_HOME}/logs/elasticsearch.log \
${ES_HOME}/logs/stdout.log
\ No newline at end of file
/*
* 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.profile.ProfileClient;
import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationRequest;
import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationResult;
import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationResultMatcher;
import org.apache.skywalking.e2e.profile.query.ProfileTaskQuery;
import org.apache.skywalking.e2e.profile.query.ProfileTasks;
import org.apache.skywalking.e2e.profile.query.ProfilesTasksMatcher;
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.EndpointQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
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.trace.Trace;
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 java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Mrpro
*/
@RunWith(SpringJUnit4ClassRunner.class)
public class ProfileVerificationITCase {
private static final Logger LOGGER = LoggerFactory.getLogger(ProfileVerificationITCase.class);
private final RestTemplate restTemplate = new RestTemplate();
private final int retryInterval = 10;
private ProfileClient profileClient;
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 swWebappPort = System.getProperty("sw.webapp.port", "12800");
final String instrumentedServiceHost = System.getProperty("service.host", "127.0.0.1");
final String instrumentedServicePort = System.getProperty("service.port", "32782");
// final String instrumentedServicePort = System.getProperty("service.port", "9090");
profileClient = new ProfileClient(swWebappHost, swWebappPort);
instrumentedServiceUrl = "http://" + instrumentedServiceHost + ":" + instrumentedServicePort;
}
@Test(timeout = 1200000)
@DirtiesContext
public void verify() throws Exception {
final LocalDateTime minutesAgo = LocalDateTime.now(ZoneOffset.UTC);
while (true) {
try {
final ResponseEntity<String> responseEntity = sendRequest(false);
LOGGER.info("responseEntity: {}", responseEntity);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
final List<Trace> traces = profileClient.traces(
new TracesQuery()
.start(minutesAgo)
.end(LocalDateTime.now())
.orderByDuration()
);
if (!traces.isEmpty()) {
break;
}
Thread.sleep(10000L);
} catch (Exception ignored) {
LOGGER.error(ignored.getMessage(), ignored);
}
}
// verify basic info
verifyServices(minutesAgo);
// create profile task
verifyCreateProfileTask(minutesAgo);
}
private ResponseEntity<String> sendRequest(boolean needProfiling) {
final Map<String, String> user = new HashMap<>();
user.put("name", "SkyWalking");
user.put("enableProfiling", String.valueOf(needProfiling));
return restTemplate.postForEntity(
instrumentedServiceUrl + "/e2e/users",
user,
String.class
);
}
/**
* verify create profile task
* @param minutesAgo
* @throws Exception
*/
private void verifyCreateProfileTask(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final ProfileTaskCreationRequest creationRequest = ProfileTaskCreationRequest.builder()
.serviceId(2)
.endpointName("/e2e/users")
.duration(1)
.startTime(-1)
.minDurationThreshold(1000)
.dumpPeriod(50)
.maxSamplingCount(5).build();
// verify create task
final ProfileTaskCreationResult creationResult = profileClient.createProfileTask(creationRequest);
LOGGER.info("create profile task result: {}", creationResult);
ProfileTaskCreationResultMatcher creationResultMatcher = new ProfileTaskCreationResultMatcher();
creationResultMatcher.verify(creationResult);
// verify get task list and sniffer get task logs
verifyProfileTask(creationRequest.getServiceId(), "expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileTasks.notified.yml");
// send a profile request
sendRequest(true);
// verify task execution finish
verifyProfileTask(creationRequest.getServiceId(), "expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileTasks.finished.yml");
}
private void verifyProfileTask(int serviceId, String verifyResources) throws InterruptedException {
// verify get task list and logs
for (int i = 0; i < 10; i++) {
try {
final ProfileTasks tasks = profileClient.getProfileTaskList(
new ProfileTaskQuery()
.serviceId(serviceId)
.endpointName("")
);
LOGGER.info("get profile task list: {}", tasks);
InputStream expectedInputStream =
new ClassPathResource(verifyResources).getInputStream();
final ProfilesTasksMatcher servicesMatcher = new Yaml().loadAs(expectedInputStream, ProfilesTasksMatcher.class);
servicesMatcher.verify(tasks);
break;
} catch (Throwable e) {
if (i == 10 - 1) {
throw new IllegalStateException("match profile task list fail!", e);
}
TimeUnit.SECONDS.sleep(retryInterval);
}
}
}
private void verifyServices(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final List<Service> services = profileClient.services(
new ServicesQuery()
.start(minutesAgo)
.end(now)
);
LOGGER.info("services: {}", services);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.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);
verifyServiceInstances(minutesAgo, now, service);
verifyServiceEndpoints(minutesAgo, now, service);
}
}
private Instances verifyServiceInstances(LocalDateTime minutesAgo, LocalDateTime now,
Service service) throws Exception {
InputStream expectedInputStream;
Instances instances = profileClient.instances(
new InstancesQuery()
.serviceId(service.getKey())
.start(minutesAgo)
.end(now)
);
LOGGER.info("instances: {}", instances);
expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.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 = profileClient.endpoints(
new EndpointQuery().serviceId(service.getKey())
);
LOGGER.info("instances: {}", instances);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.endpoints.yml").getInputStream();
final EndpointsMatcher endpointsMatcher = new Yaml().loadAs(expectedInputStream, EndpointsMatcher.class);
endpointsMatcher.verify(instances);
return instances;
}
}
<?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>e2e-profile</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>e2e-profile-h2-test-runner</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-profile-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-profile-test-runner</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<properties>
<provider.name>e2e-profile-service</provider.name>
<e2e.container.version>1.1</e2e.container.version>
<e2e.container.name.prefix>skywalking-e2e-container-${build.id}-h2-profile</e2e.container.name.prefix>
</properties>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t-%i</containerNamePattern>
<imagePullPolicy>Always</imagePullPolicy>
<images>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>${e2e.container.name.prefix}</alias>
<run>
<env>
<MODE>profile</MODE>
<INSTRUMENTED_SERVICE_1>
${provider.name}-${project.version}.jar
</INSTRUMENTED_SERVICE_1>
<INSTRUMENTED_SERVICE_1_OPTS>
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_PROFILE_ACTIVE=true
-DSW_AGENT_NAME=${provider.name}
-Dserver.port=9090
</INSTRUMENTED_SERVICE_1_OPTS>
</env>
<ports>
<port>+webapp.host:webapp.port:8081</port>
<port>+service.host:service.port:9090</port>
</ports>
<volumes>
<bind>
<volume>${sw.home}:/sw</volume>
<volume>
../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar
</volume>
<volume>
${project.basedir}/src/docker/rc.d:/rc.d:ro
</volume>
</bind>
</volumes>
<wait>
<log>SkyWalking e2e container is ready for tests</log>
<time>3000000</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>
<service.host>${service.host}</service.host>
<service.port>${service.port}</service.port>
<provider.name>${provider.name}</provider.name>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
<?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>e2e-profile</artifactId>
<groupId>org.apache.skywalking</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>e2e-profile-mysql-test-runner</artifactId>
<properties>
<provider.name>e2e-profile-service</provider.name>
<e2e.container.version>1.1</e2e.container.version>
<e2e.container.name.prefix>skywalking-e2e-container-${build.id}-mysql-profile</e2e.container.name.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-profile-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>e2e-profile-test-runner</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t-%i</containerNamePattern>
<images>
<image>
<name>mysql/mysql-server:${mysql.version}</name>
<alias>${e2e.container.name.prefix}-mysql</alias>
<run>
<wait>
<log>Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 3306</log>
<time>120000</time>
</wait>
<env>
<MYSQL_ROOT_PASSWORD>root@1234</MYSQL_ROOT_PASSWORD>
<MYSQL_DATABASE>swtest</MYSQL_DATABASE>
<MYSQL_ROOT_HOST>%</MYSQL_ROOT_HOST>
</env>
<ports>
<port>mysql.port:3306</port>
</ports>
</run>
</image>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>${e2e.container.name.prefix}</alias>
<run>
<env>
<MODE>profile</MODE>
<SW_JDBC_URL>jdbc:mysql://${e2e.container.name.prefix}-mysql:3306/swtest</SW_JDBC_URL>
<INSTRUMENTED_SERVICE_1>
${provider.name}-${project.version}.jar
</INSTRUMENTED_SERVICE_1>
<INSTRUMENTED_SERVICE_1_OPTS>
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_NAME=${provider.name}
-DSW_AGENT_PROFILE_ACTIVE=true
-Dserver.port=9090
</INSTRUMENTED_SERVICE_1_OPTS>
</env>
<dependsOn>
<container>${e2e.container.name.prefix}-mysql</container>
</dependsOn>
<links>
<link>${e2e.container.name.prefix}-mysql</link>
</links>
<ports>
<port>+webapp.host:webapp.port:8081</port>
<port>+service.host:service.port:9090</port>
</ports>
<volumes>
<bind>
<volume>${sw.home}:/sw</volume>
<volume>${project.build.directory}:/home</volume>
<volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume>
<volume>${project.basedir}/src/docker/application.yml:/application.yml</volume>
<volume>
../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar
</volume>
</bind>
</volumes>
<wait>
<log>SkyWalking e2e container is ready for tests</log>
<time>3000000</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>
<service.host>${service.host}</service.host>
<service.port>${service.port}</service.port>
<provider.name>${provider.name}</provider.name>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
# 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.
cluster:
standalone:
# Please check your ZooKeeper is 3.5+, However, it is also compatible with ZooKeeper 3.4.x. Replace the ZooKeeper 3.5+
# library the oap-libs folder with your ZooKeeper 3.4.x library.
# zookeeper:
# nameSpace: ${SW_NAMESPACE:""}
# hostPort: ${SW_CLUSTER_ZK_HOST_PORT:localhost:2181}
# #Retry Policy
# baseSleepTimeMs: ${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries
# maxRetries: ${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry
# # Enable ACL
# enableACL: ${SW_ZK_ENABLE_ACL:false} # disable ACL in default
# schema: ${SW_ZK_SCHEMA:digest} # only support digest schema
# expression: ${SW_ZK_EXPRESSION:skywalking:skywalking}
# kubernetes:
# watchTimeoutSeconds: ${SW_CLUSTER_K8S_WATCH_TIMEOUT:60}
# namespace: ${SW_CLUSTER_K8S_NAMESPACE:default}
# labelSelector: ${SW_CLUSTER_K8S_LABEL:app=collector,release=skywalking}
# uidEnvName: ${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID}
# consul:
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
# Consul cluster nodes, example: 10.0.0.1:8500,10.0.0.2:8500,10.0.0.3:8500
# hostPort: ${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500}
# nacos:
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
# # Nacos Configuration namespace
# namespace: ${SW_CLUSTER_NACOS_NAMESPACE:"public"}
# hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
# etcd:
# serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
# etcd cluster nodes, example: 10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379
# hostPort: ${SW_CLUSTER_ETCD_HOST_PORT:localhost:2379}
core:
default:
# Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate
# Receiver: Receive agent data, Level 1 aggregate
# Aggregator: Level 2 aggregate
role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator
restHost: ${SW_CORE_REST_HOST:0.0.0.0}
restPort: ${SW_CORE_REST_PORT:12800}
restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/}
gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}
gRPCPort: ${SW_CORE_GRPC_PORT:11800}
downsampling:
- Hour
- Day
- Month
# Set a timeout on metrics data. After the timeout has expired, the metrics data will automatically be deleted.
enableDataKeeperExecutor: ${SW_CORE_ENABLE_DATA_KEEPER_EXECUTOR:true} # Turn it off then automatically metrics data delete will be close.
dataKeeperExecutePeriod: ${SW_CORE_DATA_KEEPER_EXECUTE_PERIOD:5} # How often the data keeper executor runs periodically, unit is minute
recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:90} # Unit is minute
minuteMetricsDataTTL: ${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # Unit is minute
hourMetricsDataTTL: ${SW_CORE_HOUR_METRIC_DATA_TTL:36} # Unit is hour
dayMetricsDataTTL: ${SW_CORE_DAY_METRIC_DATA_TTL:45} # Unit is day
monthMetricsDataTTL: ${SW_CORE_MONTH_METRIC_DATA_TTL:18} # Unit is month
# Cache metric data for 1 minute to reduce database queries, and if the OAP cluster changes within that minute,
# the metrics may not be accurate within that minute.
enableDatabaseSession: ${SW_CORE_ENABLE_DATABASE_SESSION:true}
storage:
# elasticsearch:
# nameSpace: ${SW_NAMESPACE:""}
# clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
# protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
# #trustStorePath: ${SW_SW_STORAGE_ES_SSL_JKS_PATH:"../es_keystore.jks"}
# #trustStorePass: ${SW_SW_STORAGE_ES_SSL_JKS_PASS:""}
# user: ${SW_ES_USER:""}
# password: ${SW_ES_PASSWORD:""}
# indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}
# indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
# # Those data TTL settings will override the same settings in core module.
# recordDataTTL: ${SW_STORAGE_ES_RECORD_DATA_TTL:7} # Unit is day
# otherMetricsDataTTL: ${SW_STORAGE_ES_OTHER_METRIC_DATA_TTL:45} # Unit is day
# monthMetricsDataTTL: ${SW_STORAGE_ES_MONTH_METRIC_DATA_TTL:18} # Unit is month
# # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
# bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:1000} # Execute the bulk every 1000 requests
# flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
# concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
# metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
# segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
# profileTaskQueryMaxSize: ${SW_STORAGE_ES_QUERY_PROFILE_TASK_SIZE:200}
# h2:
# driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
# url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
# user: ${SW_STORAGE_H2_USER:sa}
# metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}
mysql:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root@1234}
dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}
dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}
dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}
dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}
metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
receiver-sharing-server:
default:
receiver-register:
default:
receiver-trace:
default:
bufferPath: ${SW_RECEIVER_BUFFER_PATH:../trace-buffer/} # Path to trace buffer files, suggest to use absolute path
bufferOffsetMaxFileSize: ${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
bufferDataMaxFileSize: ${SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
bufferFileCleanWhenRestart: ${SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
sampleRate: ${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default.
slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms.
receiver-jvm:
default:
receiver-clr:
default:
#receiver-so11y:
# default:
receiver-profile:
default:
service-mesh:
default:
bufferPath: ${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path
bufferOffsetMaxFileSize: ${SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE:100} # Unit is MB
bufferDataMaxFileSize: ${SW_SERVICE_MESH_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB
bufferFileCleanWhenRestart: ${SW_SERVICE_MESH_BUFFER_FILE_CLEAN_WHEN_RESTART:false}
istio-telemetry:
default:
envoy-metric:
default:
# alsHTTPAnalysis: ${SW_ENVOY_METRIC_ALS_HTTP_ANALYSIS:k8s-mesh}
#receiver_zipkin:
# default:
# host: ${SW_RECEIVER_ZIPKIN_HOST:0.0.0.0}
# port: ${SW_RECEIVER_ZIPKIN_PORT:9411}
# contextPath: ${SW_RECEIVER_ZIPKIN_CONTEXT_PATH:/}
#receiver_jaeger:
# default:
# gRPCHost: ${SW_RECEIVER_JAEGER_HOST:0.0.0.0}
# gRPCPort: ${SW_RECEIVER_JAEGER_PORT:14250}
query:
graphql:
path: ${SW_QUERY_GRAPHQL_PATH:/graphql}
alarm:
default:
telemetry:
none:
# prometheus:
# host: ${SW_TELEMETRY_PROMETHEUS_HOST:0.0.0.0}
# port: ${SW_TELEMETRY_PROMETHEUS_PORT:1234}
# so11y:
# prometheusExporterEnabled: ${SW_TELEMETRY_SO11Y_PROMETHEUS_ENABLED:true}
# prometheusExporterHost: ${SW_TELEMETRY_PROMETHEUS_HOST:0.0.0.0}
# prometheusExporterPort: ${SW_TELEMETRY_PROMETHEUS_PORT:1234}
configuration:
none:
# apollo:
# apolloMeta: http://106.12.25.204:8080
# apolloCluster: default
# # apolloEnv: # defaults to null
# appId: skywalking
# period: 5
# nacos:
# # Nacos Server Host
# serverAddr: 127.0.0.1
# # Nacos Server Port
# port: 8848
# # Nacos Configuration Group
# group: 'skywalking'
# # Nacos Configuration namespace
# namespace: ''
# # Unit seconds, sync period. Default fetch every 60 seconds.
# period : 5
# # the name of current cluster, set the name if you want to upstream system known.
# clusterName: "default"
# zookeeper:
# period : 60 # Unit seconds, sync period. Default fetch every 60 seconds.
# nameSpace: /default
# hostPort: localhost:2181
# #Retry Policy
# baseSleepTimeMs: 1000 # initial amount of time to wait between retries
# maxRetries: 3 # max number of times to retry
# etcd:
# period : 60 # Unit seconds, sync period. Default fetch every 60 seconds.
# group : 'skywalking'
# serverAddr: localhost:2379
# clusterName: "default"
# consul:
# # Consul host and ports, separated by comma, e.g. 1.2.3.4:8500,2.3.4.5:8500
# hostAndPorts: ${consul.address}
# # Sync period in seconds. Defaults to 60 seconds.
# period: 1
#exporter:
# grpc:
# targetHost: ${SW_EXPORTER_GRPC_HOST:127.0.0.1}
# targetPort: ${SW_EXPORTER_GRPC_PORT:9870}
#!/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="https://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"
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 /application.yml > "${SW_HOME}/config/application.yml"
#!/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}/*
/*
* 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.profile.ProfileClient;
import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationRequest;
import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationResult;
import org.apache.skywalking.e2e.profile.creation.ProfileTaskCreationResultMatcher;
import org.apache.skywalking.e2e.profile.query.ProfileTaskQuery;
import org.apache.skywalking.e2e.profile.query.ProfileTasks;
import org.apache.skywalking.e2e.profile.query.ProfilesTasksMatcher;
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.EndpointQuery;
import org.apache.skywalking.e2e.service.endpoint.Endpoints;
import org.apache.skywalking.e2e.service.endpoint.EndpointsMatcher;
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.trace.Trace;
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 java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Mrpro
*/
@RunWith(SpringJUnit4ClassRunner.class)
public class ProfileVerificationITCase {
private static final Logger LOGGER = LoggerFactory.getLogger(ProfileVerificationITCase.class);
private final RestTemplate restTemplate = new RestTemplate();
private final int retryInterval = 10;
private ProfileClient profileClient;
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 swWebappPort = System.getProperty("sw.webapp.port", "12800");
final String instrumentedServiceHost = System.getProperty("service.host", "127.0.0.1");
final String instrumentedServicePort = System.getProperty("service.port", "32782");
// final String instrumentedServicePort = System.getProperty("service.port", "9090");
profileClient = new ProfileClient(swWebappHost, swWebappPort);
instrumentedServiceUrl = "http://" + instrumentedServiceHost + ":" + instrumentedServicePort;
}
@Test(timeout = 1200000)
@DirtiesContext
public void verify() throws Exception {
final LocalDateTime minutesAgo = LocalDateTime.now(ZoneOffset.UTC);
while (true) {
try {
final ResponseEntity<String> responseEntity = sendRequest(false);
LOGGER.info("responseEntity: {}", responseEntity);
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
final List<Trace> traces = profileClient.traces(
new TracesQuery()
.start(minutesAgo)
.end(LocalDateTime.now())
.orderByDuration()
);
if (!traces.isEmpty()) {
break;
}
Thread.sleep(10000L);
} catch (Exception ignored) {
}
}
// verify basic info
verifyServices(minutesAgo);
// create profile task
verifyCreateProfileTask(minutesAgo);
}
private ResponseEntity<String> sendRequest(boolean needProfiling) {
final Map<String, String> user = new HashMap<>();
user.put("name", "SkyWalking");
user.put("enableProfiling", String.valueOf(needProfiling));
return restTemplate.postForEntity(
instrumentedServiceUrl + "/e2e/users",
user,
String.class
);
}
/**
* verify create profile task
* @param minutesAgo
* @throws Exception
*/
private void verifyCreateProfileTask(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final ProfileTaskCreationRequest creationRequest = ProfileTaskCreationRequest.builder()
.serviceId(2)
.endpointName("/e2e/users")
.duration(1)
.startTime(-1)
.minDurationThreshold(1000)
.dumpPeriod(50)
.maxSamplingCount(5).build();
// verify create task
final ProfileTaskCreationResult creationResult = profileClient.createProfileTask(creationRequest);
LOGGER.info("create profile task result: {}", creationResult);
ProfileTaskCreationResultMatcher creationResultMatcher = new ProfileTaskCreationResultMatcher();
creationResultMatcher.verify(creationResult);
// verify get task list and sniffer get task logs
verifyProfileTask(creationRequest.getServiceId(), "expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileTasks.notified.yml");
// send a profile request
sendRequest(true);
// verify task execution finish
verifyProfileTask(creationRequest.getServiceId(), "expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.profileTasks.finished.yml");
}
private void verifyProfileTask(int serviceId, String verifyResources) throws InterruptedException {
// verify get task list and logs
for (int i = 0; i < 10; i++) {
try {
final ProfileTasks tasks = profileClient.getProfileTaskList(
new ProfileTaskQuery()
.serviceId(serviceId)
.endpointName("")
);
LOGGER.info("get profile task list: {}", tasks);
InputStream expectedInputStream =
new ClassPathResource(verifyResources).getInputStream();
final ProfilesTasksMatcher servicesMatcher = new Yaml().loadAs(expectedInputStream, ProfilesTasksMatcher.class);
servicesMatcher.verify(tasks);
break;
} catch (Throwable e) {
if (i == 10 - 1) {
throw new IllegalStateException("match profile task list fail!", e);
}
TimeUnit.SECONDS.sleep(retryInterval);
}
}
}
private void verifyServices(LocalDateTime minutesAgo) throws Exception {
final LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
final List<Service> services = profileClient.services(
new ServicesQuery()
.start(minutesAgo)
.end(now)
);
LOGGER.info("services: {}", services);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.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);
verifyServiceInstances(minutesAgo, now, service);
verifyServiceEndpoints(minutesAgo, now, service);
}
}
private Instances verifyServiceInstances(LocalDateTime minutesAgo, LocalDateTime now,
Service service) throws Exception {
InputStream expectedInputStream;
Instances instances = profileClient.instances(
new InstancesQuery()
.serviceId(service.getKey())
.start(minutesAgo)
.end(now)
);
LOGGER.info("instances: {}", instances);
expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.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 = profileClient.endpoints(
new EndpointQuery().serviceId(service.getKey())
);
LOGGER.info("instances: {}", instances);
InputStream expectedInputStream =
new ClassPathResource("expected-data/org.apache.skywalking.e2e.ProfileVerificationITCase.endpoints.yml").getInputStream();
final EndpointsMatcher endpointsMatcher = new Yaml().loadAs(expectedInputStream, EndpointsMatcher.class);
endpointsMatcher.verify(instances);
return instances;
}
}
......@@ -46,5 +46,254 @@
</dependencies>
<properties>
<provider.name>e2e-profile-service</provider.name>
<e2e.container.version>1.1</e2e.container.version>
<e2e.container.name.prefix>skywalking-e2e-container-${build.id}-profile</e2e.container.name.prefix>
</properties>
<profiles>
<!--mysql storage -->
<profile>
<id>mysql</id>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t-%i</containerNamePattern>
<images>
<image>
<name>mysql/mysql-server:${mysql.version}</name>
<alias>${e2e.container.name.prefix}-datasource</alias>
<run>
<wait>
<log>Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 3306</log>
<time>120000</time>
</wait>
<env>
<MYSQL_ROOT_PASSWORD>root@1234</MYSQL_ROOT_PASSWORD>
<MYSQL_DATABASE>swtest</MYSQL_DATABASE>
<MYSQL_ROOT_HOST>%</MYSQL_ROOT_HOST>
</env>
<ports>
<port>mysql.port:3306</port>
</ports>
</run>
</image>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>${e2e.container.name.prefix}-runner</alias>
<run>
<env>
<STORAGE>mysql</STORAGE>
<SW_JDBC_URL>jdbc:mysql://${e2e.container.name.prefix}-datasource:3306/swtest</SW_JDBC_URL>
<INSTRUMENTED_SERVICE_1>
${provider.name}-${project.version}.jar
</INSTRUMENTED_SERVICE_1>
<INSTRUMENTED_SERVICE_1_OPTS>
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_PROFILE_ACTIVE=true
-DSW_AGENT_NAME=${provider.name}
-Dserver.port=9090
</INSTRUMENTED_SERVICE_1_OPTS>
</env>
<dependsOn>
<container>${e2e.container.name.prefix}-datasource</container>
</dependsOn>
<links>
<link>${e2e.container.name.prefix}-datasource</link>
</links>
<ports>
<port>+webapp.host:webapp.port:8081</port>
<port>+service.host:service.port:9090</port>
</ports>
<volumes>
<bind>
<volume>${sw.home}:/sw</volume>
<volume>${project.build.directory}:/home</volume>
<volume>../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar</volume>
<volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume>
<volume>${project.basedir}/src/docker/clusterize.awk:/clusterize.awk</volume>
</bind>
</volumes>
<wait>
<log>SkyWalking e2e container is ready for tests</log>
<time>3000000</time>
</wait>
</run>
</image>
</images>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!--h2 storage -->
<profile>
<id>h2</id>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t-%i</containerNamePattern>
<imagePullPolicy>Always</imagePullPolicy>
<images>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>${e2e.container.name.prefix}</alias>
<run>
<env>
<STORAGE>h2</STORAGE>
<INSTRUMENTED_SERVICE_1>
${provider.name}-${project.version}.jar
</INSTRUMENTED_SERVICE_1>
<INSTRUMENTED_SERVICE_1_OPTS>
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_PROFILE_ACTIVE=true
-DSW_AGENT_NAME=${provider.name}
-Dserver.port=9090
</INSTRUMENTED_SERVICE_1_OPTS>
</env>
<ports>
<port>+webapp.host:webapp.port:8081</port>
<port>+service.host:service.port:9090</port>
</ports>
<volumes>
<bind>
<volume>${sw.home}:/sw</volume>
<volume>../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar</volume>
<volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume>
<volume>${project.basedir}/src/docker/clusterize.awk:/clusterize.awk</volume>
</bind>
</volumes>
<wait>
<log>SkyWalking e2e container is ready for tests</log>
<time>3000000</time>
</wait>
</run>
</image>
</images>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!--elasticsearch storage -->
<profile>
<id>elasticsearch</id>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<containerNamePattern>%a-%t-%i</containerNamePattern>
<imagePullPolicy>Always</imagePullPolicy>
<images>
<image>
<name>elastic/elasticsearch:${elasticsearch.version}</name>
<alias>${e2e.container.name.prefix}-elasticsearch</alias>
<run>
<ports>
<port>es.port:9200</port>
</ports>
<wait>
<http>
<url>http://localhost:${es.port}</url>
<method>GET</method>
<status>200</status>
</http>
<time>120000</time>
</wait>
<env>
<discovery.type>single-node</discovery.type>
</env>
</run>
</image>
<image>
<name>skyapm/e2e-container:${e2e.container.version}</name>
<alias>${e2e.container.name.prefix}</alias>
<run>
<env>
<STORAGE>elasticsearch</STORAGE>
<ES_VERSION>${elasticsearch.version}</ES_VERSION>
<SW_STORAGE_ES_CLUSTER_NODES>
${e2e.container.name.prefix}-elasticsearch:9200
</SW_STORAGE_ES_CLUSTER_NODES>
<INSTRUMENTED_SERVICE_1>
${provider.name}-${project.version}.jar
</INSTRUMENTED_SERVICE_1>
<INSTRUMENTED_SERVICE_1_OPTS>
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_PROFILE_ACTIVE=true
-DSW_AGENT_NAME=${provider.name}
-Dserver.port=9090
</INSTRUMENTED_SERVICE_1_OPTS>
</env>
<dependsOn>
<container>${e2e.container.name.prefix}-elasticsearch</container>
</dependsOn>
<ports>
<port>+webapp.host:webapp.port:8081</port>
<port>+service.host:service.port:9090</port>
</ports>
<links>
<link>${e2e.container.name.prefix}-elasticsearch</link>
</links>
<volumes>
<bind>
<volume>${sw.home}:/sw</volume>
<volume>../${provider.name}/target/${provider.name}-${project.version}.jar:/home/${provider.name}-${project.version}.jar</volume>
<volume>${project.basedir}/src/docker/rc.d:/rc.d:ro</volume>
<volume>${project.basedir}/src/docker/clusterize.awk:/clusterize.awk</volume>
</bind>
</volumes>
<wait>
<log>SkyWalking e2e container is ready for tests</log>
<time>3000000</time>
</wait>
</run>
</image>
</images>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<!-- 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>
<service.host>${service.host}</service.host>
<service.port>${service.port}</service.port>
<provider.name>${provider.name}</provider.name>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
......@@ -17,77 +17,45 @@
#!/usr/bin/awk -f
BEGIN {
in_cluster_section=0;
in_cluster_zk_section=0;
in_storage_section=0;
in_storage_es_section=0;
in_storage_h2_section=0;
in_storage_type_section=0;
}
{
if (in_cluster_section == 0) {
in_cluster_section=$0 ~ /^cluster:$/
} else {
in_cluster_section=$0 ~ /^(#|\s{2})/
}
if (in_storage_section == 0) {
in_storage_section=$0 ~ /^storage:$/
} else {
in_storage_section=$0 ~ /^(#|\s{2})/
}
if (in_cluster_section == 1) {
# in the cluster: section now
# disable standalone module
if ($0 ~ /^ standalone:$/) {
print "#" $0
} else {
if (in_cluster_zk_section == 0) {
in_cluster_zk_section=$0 ~ /^#?\s+zookeeper:$/
} else {
in_cluster_zk_section=$0 ~ /^(#\s{4}|\s{2})/
}
if (in_cluster_zk_section == 1) {
# in the cluster.zookeeper section now
# uncomment zk config
gsub("^#", "", $0)
print
} else {
print
}
}
} else if (in_storage_section == 1) {
if (in_storage_section == 1) {
# in the storage: section now
# disable h2 module
if (in_storage_es_section == 0) {
if (in_storage_type_section == 0) {
if (ENVIRON["ES_VERSION"] ~ /^6.+/) {
in_storage_es_section=$0 ~ /^#?\s+elasticsearch:$/
in_storage_type_section=$0 ~ /^#?\s+elasticsearch:$/
} else if (ENVIRON["ES_VERSION"] ~ /^7.+/) {
in_storage_es_section=$0 ~ /^#?\s+elasticsearch7:$/
in_storage_type_section=$0 ~ /^#?\s+elasticsearch7:$/
} else if (ENVIRON["STORAGE"] ~ /^mysql.*$/) {
in_storage_type_section=$0 ~ /^#?\s+mysql/
} else if (ENVIRON["STORAGE"] ~ /^h2.*$/) {
in_storage_type_section=$0 ~ /^#?\s+h2:$/
}
} else {
in_storage_es_section=$0 ~ /^#?\s{4}/
}
if (in_storage_h2_section == 0) {
in_storage_h2_section=$0 ~ /^#?\s+h2:$/
} else {
in_storage_h2_section=$0 ~ /^#?\s{4}/
in_storage_type_section=$0 ~ /^#?\s{4}/
}
if (in_storage_es_section == 1) {
# in the storage.elasticsearch section now
# uncomment es config
if (in_storage_type_section == 1) {
gsub("^#", "", $0)
print
} else if (in_storage_h2_section == 1) {
# comment out h2 config
} else {
if ($0 !~ /^#/) {
print "#" $0
if ($0 ~ /^storage:$/) {
print
} else {
print "#" $0
}
} else {
print
}
} else {
print
}
} else {
print
......
......@@ -17,16 +17,22 @@
apt-get update && apt-get install -y gawk
if test "${MODE}" = "cluster"; then
original_wd=$(pwd)
original_wd=$(pwd)
# substitute application.yml to be capable of cluster mode
cd ${SW_HOME}/config \
&& gawk -f /clusterize.awk application.yml > clusterized_app.yml \
&& mv clusterized_app.yml application.yml \
&& sed '/<Loggers>/a<logger name="org.apache.skywalking.oap.server.receiver.trace.provider.UninstrumentedGatewaysConfig" level="DEBUG"/>\
\n<logger name="org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.service.ServiceMappingSpanListener" level="DEBUG"/>' log4j2.xml > log4j2debuggable.xml \
&& mv log4j2debuggable.xml log4j2.xml
cd ${original_wd}
if test "${STORAGE}" = "mysql"; then
MYSQL_URL="https://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"
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
fi
# substitute application.yml to adapt the storage
cd ${SW_HOME}/config \
&& gawk -f /adapt_storage.awk application.yml > clusterized_app.yml \
&& mv clusterized_app.yml application.yml
cd ${original_wd}
......@@ -33,9 +33,6 @@
<modules>
<module>e2e-profile-service</module>
<module>e2e-profile-test-runner</module>
<module>e2e-profile-h2-test-runner</module>
<module>e2e-profile-mysql-test-runner</module>
<module>e2e-profile-es-test-runner</module>
</modules>
<dependencies>
......
......@@ -36,6 +36,9 @@ while [[ $# -gt 0 ]]; do
--profiles=*)
profiles=${1#*=}
;;
--storage=*)
storage=${1#*=}
;;
*)
cases+=($1)
esac
......@@ -70,6 +73,7 @@ do
-De2e.container.version="${E2E_VERSION}" \
-Delasticsearch.version="${ES_VERSION}" \
-Dsw.home="${base_dir}/$test_case/${DIST_PACKAGE//.tar.gz/}" \
`if [ ! -z "${storage}" ] ; then echo -P"${storage}"; fi` \
-f test/e2e/pom.xml -pl "$test_case" -am verify
status_code=$?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册