You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by al...@apache.org on 2022/04/25 06:00:04 UTC
[dubbo-samples] branch master updated: Add jacoco agent inject support (#441)
This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-samples.git
The following commit(s) were added to refs/heads/master by this push:
new 63013d29 Add jacoco agent inject support (#441)
63013d29 is described below
commit 63013d29ef393fe9294e5d93e456d3ed2a3f7763
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Mon Apr 25 13:59:56 2022 +0800
Add jacoco agent inject support (#441)
* Add jacoco collector
* add asf header
---
test/dubbo-scenario-builder/pom.xml | 6 +
.../dubbo/scenario/builder/ConfigurationImpl.java | 22 ++-
.../dubbo/scenario/builder/IConfiguration.java | 2 +
.../dubbo/scenario/builder/JacocoDownloader.java | 181 +++++++++++++++++++++
.../scenario/builder/ScenarioBuilderMain.java | 1 +
5 files changed, 208 insertions(+), 4 deletions(-)
diff --git a/test/dubbo-scenario-builder/pom.xml b/test/dubbo-scenario-builder/pom.xml
index eaf7c870..c51b3ba2 100644
--- a/test/dubbo-scenario-builder/pom.xml
+++ b/test/dubbo-scenario-builder/pom.xml
@@ -36,6 +36,12 @@
<version>2.3.28</version>
</dependency>
+ <dependency>
+ <groupId>org.asynchttpclient</groupId>
+ <artifactId>async-http-client</artifactId>
+ <version>2.12.1</version>
+ </dependency>
+
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
diff --git a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ConfigurationImpl.java b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ConfigurationImpl.java
index 1c9894d8..140698e1 100644
--- a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ConfigurationImpl.java
+++ b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ConfigurationImpl.java
@@ -17,11 +17,12 @@
package org.apache.dubbo.scenario.builder;
-import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.scenario.builder.exception.ConfigureFileNotFoundException;
import org.apache.dubbo.scenario.builder.vo.CaseConfiguration;
import org.apache.dubbo.scenario.builder.vo.DockerService;
import org.apache.dubbo.scenario.builder.vo.ServiceComponent;
+
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;
@@ -72,6 +73,7 @@ public class ConfigurationImpl implements IConfiguration {
private String configBasedir;
private String scenarioName;
private final String scenarioLogDir;
+ private final boolean jacocoEnable = Boolean.parseBoolean(System.getProperty("jacoco.enable"));
private int scenarioTimeout = 200;
private int javaDebugPort = 20660;
private int debugTimeout = 36000;
@@ -241,12 +243,13 @@ public class ConfigurationImpl implements IConfiguration {
private void fillupServices(CaseConfiguration caseConfiguration) throws IOException {
List<String> caseSystemProps = caseConfiguration.getSystemProps();
+ int index = 0;
for (Map.Entry<String, ServiceComponent> entry : caseConfiguration.getServices().entrySet()) {
String serviceName = entry.getKey();
ServiceComponent service = entry.getValue();
String type = service.getType();
if (isAppOrTestService(type)) {
- service.setImage(SAMPLE_TEST_IMAGE+":"+testImageVersion);
+ service.setImage(SAMPLE_TEST_IMAGE + ":" + testImageVersion);
service.setBasedir(toAbsolutePath(service.getBasedir()));
if (service.getVolumes() == null) {
service.setVolumes(new ArrayList<>());
@@ -272,7 +275,7 @@ public class ConfigurationImpl implements IConfiguration {
//set run delay
if (service.getRunDelay() > 0) {
- setEnv(service, ENV_RUN_DELAY, service.getRunDelay()+"");
+ setEnv(service, ENV_RUN_DELAY, service.getRunDelay() + "");
}
//set check timeout
@@ -286,7 +289,7 @@ public class ConfigurationImpl implements IConfiguration {
String debugOpts;
if (isJdk9OrLater) {
debugOpts = String.format("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:%s", debugPort);
- }else {
+ } else {
debugOpts = String.format("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=%s", debugPort);
}
appendEnv(service, ENV_DEBUG_OPTS, debugOpts);
@@ -377,6 +380,12 @@ public class ConfigurationImpl implements IConfiguration {
appendEnv(service, ENV_JAVA_OPTS, str);
}
+ if (jacocoEnable) {
+ //set jacoco agent
+ String jacoco = "-javaagent:/usr/local/dubbo/app/jacocoagent.jar=destfile=/usr/local/dubbo/app/jacoco/" + index++ + "-jacoco.exec";
+ appendEnv(service, ENV_JAVA_OPTS, jacoco);
+ }
+
if (service.getHealthcheck() != null) {
healthcheckServices.add(serviceName);
}
@@ -530,6 +539,11 @@ public class ConfigurationImpl implements IConfiguration {
return System.getProperty("jacoco.home");
}
+ @Override
+ public boolean enableJacoco() {
+ return jacocoEnable;
+ }
+
@Override
public String debugMode() {
return isDebug() ? "1" : "0";
diff --git a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/IConfiguration.java b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/IConfiguration.java
index abebb5d2..acc8cf97 100644
--- a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/IConfiguration.java
+++ b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/IConfiguration.java
@@ -44,6 +44,8 @@ public interface IConfiguration {
String jacocoHome();
+ boolean enableJacoco();
+
String debugMode();
Map<String, Object> toMap();
diff --git a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/JacocoDownloader.java b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/JacocoDownloader.java
new file mode 100644
index 00000000..d0660665
--- /dev/null
+++ b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/JacocoDownloader.java
@@ -0,0 +1,181 @@
+/*
+ * 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.dubbo.scenario.builder;
+
+import org.asynchttpclient.AsyncCompletionHandler;
+import org.asynchttpclient.AsyncHttpClient;
+import org.asynchttpclient.DefaultAsyncHttpClient;
+import org.asynchttpclient.DefaultAsyncHttpClientConfig;
+import org.asynchttpclient.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class JacocoDownloader {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ /**
+ * The jacoco agent version
+ */
+ private static final String JACOCO_VERSION = "0.8.8";
+
+ /**
+ * The jacoco binary file name
+ */
+ private static final String JACOCO_BINARY_FILE_NAME = "org.jacoco.agent-" + JACOCO_VERSION + "-runtime.jar";
+
+ /**
+ * The url format for jacoco binary file.
+ */
+ private static final String JACOCO_BINARY_URL_FORMAT = "https://repo1.maven.org/maven2/org/jacoco/org.jacoco.agent/" + JACOCO_VERSION + "/org.jacoco.agent-" + JACOCO_VERSION + "-runtime.jar";
+
+ /**
+ * The temporary directory.
+ */
+ private static final String TEMPORARY_DIRECTORY = "jacoco";
+
+ /**
+ * The timeout when download jacoco binary archive file.
+ */
+ private static final int REQUEST_TIMEOUT = 30 * 1000;
+
+ /**
+ * The timeout when connect the download url.
+ */
+ private static final int CONNECT_TIMEOUT = 10 * 1000;
+
+ /**
+ * Returns {@code true} if the file exists with the given file path, otherwise {@code false}.
+ *
+ * @param filePath the file path to check.
+ */
+ private static boolean checkFile(Path filePath) {
+ return Files.exists(filePath) && filePath.toFile().isFile();
+ }
+
+ public static void initialize(IConfiguration configuration) {
+ if (!configuration.enableJacoco()) {
+ return;
+ }
+
+ Path expectedFile = new File(configuration.outputDir() + File.separator + "jacocoagent.jar").toPath();
+ // checks the jacoco binary file exists or not
+ if (checkFile(expectedFile)) {
+ return;
+ }
+ Path temporaryFilePath;
+ try {
+ temporaryFilePath = Paths.get(Files.createTempDirectory("").getParent().toString(),
+ TEMPORARY_DIRECTORY,
+ JACOCO_BINARY_FILE_NAME);
+ } catch (IOException e) {
+ throw new RuntimeException(String.format("Cannot create the temporary directory, file path: %s", TEMPORARY_DIRECTORY), e);
+ }
+
+ // create the temporary directory path.
+ try {
+ Files.createDirectories(temporaryFilePath.getParent());
+ } catch (IOException e) {
+ throw new RuntimeException(String.format("Failed to create the temporary directory to save jacoco binary file, file path:%s", temporaryFilePath.getParent()), e);
+ }
+
+ // download jacoco binary file in temporary directory.
+ try {
+ LOGGER.info("It is beginning to download the jacoco binary archive, it will take several minutes..." +
+ "\nThe jacoco binary archive file will be download from " + JACOCO_BINARY_URL_FORMAT + "," +
+ "\nwhich will be saved in " + temporaryFilePath.toString() + "," +
+ "\nalso it will be renamed to '" + JACOCO_BINARY_FILE_NAME + "' and moved into " + expectedFile + ".\n");
+ download(temporaryFilePath);
+ } catch (Exception e) {
+ throw new RuntimeException(String.format("Download jacoco binary archive failed, download url:%s, file path:%s." +
+ "\nOr you can do something to avoid this problem as below:" +
+ "\n1. Download jacoco binary archive manually regardless of the version" +
+ "\n2. Rename the downloaded file named 'org.jacoco.agent-{version}-runtime.jar' to 'jacocoagent.jar'" +
+ "\n3. Put the renamed file in %s, you maybe need to create the directory if necessary.\n",
+ JACOCO_BINARY_URL_FORMAT, temporaryFilePath, expectedFile), e);
+ }
+
+ // check downloaded jacoco binary file in temporary directory.
+ if (!checkFile(temporaryFilePath)) {
+ throw new IllegalArgumentException(String.format("There are some unknown problem occurred when downloaded the jacoco binary archive file, file path:%s", temporaryFilePath));
+ }
+
+ // create target directory if necessary
+ if (!Files.exists(expectedFile)) {
+ try {
+ Files.createDirectories(expectedFile.getParent());
+ } catch (IOException e) {
+ throw new IllegalArgumentException(String.format("Failed to create target directory, the directory path: %s", expectedFile.getParent()), e);
+ }
+ }
+
+ // copy the downloaded jacoco binary file into the target file path
+ try {
+ Files.copy(temporaryFilePath, expectedFile, StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(String.format("Failed to copy file, the source file path: %s, the target file path: %s", temporaryFilePath, expectedFile), e);
+ }
+
+ // checks the jacoco binary file exists or not again
+ if (!checkFile(expectedFile)) {
+ throw new IllegalArgumentException(String.format("The jacoco binary archive file doesn't exist, file path:%s", expectedFile));
+ }
+
+ }
+
+ /**
+ * Download the file with the given url.
+ *
+ * @param targetPath the target path to save the downloaded file.
+ */
+ private static void download(Path targetPath) throws ExecutionException, InterruptedException, IOException, TimeoutException {
+ AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient(
+ new DefaultAsyncHttpClientConfig.Builder()
+ .setConnectTimeout(CONNECT_TIMEOUT)
+ .setRequestTimeout(REQUEST_TIMEOUT)
+ .setMaxRequestRetry(1)
+ .build());
+ Future<Response> responseFuture = asyncHttpClient.prepareGet(JacocoDownloader.JACOCO_BINARY_URL_FORMAT).execute(new AsyncCompletionHandler<Response>() {
+ @Override
+ public Response onCompleted(Response response) {
+ LOGGER.info("Download jacoco binary archive file successfully! download url: " + JacocoDownloader.JACOCO_BINARY_URL_FORMAT);
+ return response;
+ }
+
+ @Override
+ public void onThrowable(Throwable t) {
+ LOGGER.warn("Failed to download the file, download url: " + JacocoDownloader.JACOCO_BINARY_URL_FORMAT);
+ super.onThrowable(t);
+ }
+ });
+ // Future timeout should 2 times as equal as REQUEST_TIMEOUT, because it will retry 1 time.
+ Response response = responseFuture.get(REQUEST_TIMEOUT * 2, TimeUnit.MILLISECONDS);
+ Files.copy(response.getResponseBodyAsStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
+ }
+
+}
diff --git a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ScenarioBuilderMain.java b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ScenarioBuilderMain.java
index 62be59b6..8f9e7263 100644
--- a/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ScenarioBuilderMain.java
+++ b/test/dubbo-scenario-builder/src/main/java/org/apache/dubbo/scenario/builder/ScenarioBuilderMain.java
@@ -22,6 +22,7 @@ public class ScenarioBuilderMain {
public static void main(String[] args) throws Exception {
IConfiguration configuration = new ConfigurationImpl();
configuration.scenarioGenerator().generate(configuration);
+ JacocoDownloader.initialize(configuration);
System.out.println("outputDir: " + configuration.outputDir());
System.exit(0);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org