Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into installer_windows
Browse files Browse the repository at this point in the history
  • Loading branch information
karottenreibe committed Mar 12, 2024
2 parents 94c15ac + f045760 commit 407b5b1
Show file tree
Hide file tree
Showing 31 changed files with 1,425 additions and 91 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,8 +6,18 @@ We use [semantic versioning](http://semver.org/):

# Next Release
- [feature] add installer for Windows

# 33.1.2
- [fix] _teamscale-maven-plugin_: Revision and end commit could not be set via command line (user property)

# 33.1.1
- [fix] _agent_: NPE during agent startup probably due to missing read permissions in a shared folder

# 33.1.0
- [feature] _teamscale-maven-plugin_: Add new execution goal to batch convert .exec files into testwise coverage report.
- [feature] _agent_: Extended list of packages excluded by default
- [maintenance] _agent_: Removed HTTP upload (i.e. `upload-url` option)
- [feature] _agent_: New option `proxy-password-file` allows users to provide a file containing a proxy password

# 33.0.0
- [feature] add installer for system-wide installation (see agent/MIGRATION.md for a migration guide)
Expand Down
1 change: 1 addition & 0 deletions agent/README.md
Expand Up @@ -61,6 +61,7 @@ The following options are available:
Use this to change the logging behaviour of the agent. Some sample configurations are provided with the agent in the
`logging` folder, e.g. to enable debug logging or log directly to the console. (For details see path format section
below)
- `proxy-password-file` (optional): path to a file that contains the password for a proxy server authentication. This file may only contain the password and nothing else.
- `mode` (optional): which coverage collection mode to use. Can be either `normal` or `testwise` (Default is `normal`)
- `debug` (optional): `true`, `false` or a path to which the logs should be written to. `true` if no explicit value given.
This option turns on debug mode. The logs will be written to console and the given file path. If no file path is given,
Expand Down
11 changes: 9 additions & 2 deletions agent/src/main/java/com/teamscale/jacoco/agent/Agent.java
Expand Up @@ -19,7 +19,7 @@
import java.util.List;
import java.util.Properties;

import org.conqat.lib.commons.filesystem.FileSystemUtils;
import com.teamscale.jacoco.agent.util.FileSystemUtilsClone;
import org.conqat.lib.commons.string.StringUtils;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
Expand Down Expand Up @@ -84,7 +84,14 @@ private void retryUnsuccessfulUploads(AgentOptions options, IUploader uploader)
// Default fallback
outputPath = AgentUtils.getAgentDirectory().resolve("coverage");
}
List<File> reuploadCandidates = FileSystemUtils.listFilesRecursively(outputPath.getParent().toFile(),

Path parentPath = outputPath.getParent();
if (parentPath == null) {
logger.error("The output path '{}' does not have a parent path. Canceling upload retry.", outputPath.toAbsolutePath());
return;
}

List<File> reuploadCandidates = FileSystemUtilsClone.listFilesRecursively(parentPath.toFile(),
filepath -> filepath.getName().endsWith(RETRY_UPLOAD_FILE_SUFFIX));
for (File file : reuploadCandidates) {
reuploadCoverageFromPropertiesFile(file, uploader);
Expand Down
22 changes: 22 additions & 0 deletions agent/src/main/java/com/teamscale/jacoco/agent/AgentBase.java
@@ -1,7 +1,9 @@
package com.teamscale.jacoco.agent;

import com.teamscale.client.ProxySystemProperties;
import com.teamscale.jacoco.agent.options.AgentOptions;
import com.teamscale.jacoco.agent.util.LoggingUtils;
import org.conqat.lib.commons.filesystem.FileSystemUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
Expand All @@ -12,7 +14,9 @@
import org.jacoco.agent.rt.RT;
import org.slf4j.Logger;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Path;

/**
* Base class for agent implementations. Handles logger shutdown, store creation and instantiation of the
Expand All @@ -36,6 +40,7 @@ public abstract class AgentBase {
/** Constructor. */
public AgentBase(AgentOptions options) throws IllegalStateException {
this.options = options;
setProxyPasswordFromFile(options.getProxyPasswordPath());
try {
controller = new JacocoRuntimeController(RT.getAgent());
} catch (IllegalStateException e) {
Expand All @@ -55,6 +60,23 @@ public AgentBase(AgentOptions options) throws IllegalStateException {
}
}

/** Sets the proxy password JVM property from a file for both http and https. */
private void setProxyPasswordFromFile(Path proxyPasswordFilePath) {
if (proxyPasswordFilePath == null) {
return;
}
try {
String proxyPassword = FileSystemUtils.readFileUTF8(proxyPasswordFilePath.toFile()).trim();
new ProxySystemProperties(ProxySystemProperties.Protocol.HTTP).setProxyPassword(proxyPassword);
new ProxySystemProperties(ProxySystemProperties.Protocol.HTTPS).setProxyPassword(proxyPassword);
} catch (IOException e) {
logger.error(
"Unable to open file containing proxy password. Please make sure the file exists and the user has the permissions to read the file.",
e);
}

}

/**
* Lazily generated string representation of the command line arguments to print to the log.
*/
Expand Down
Expand Up @@ -108,7 +108,10 @@ public class AgentOptions {
* The directory to write the XML traces to.
*/
private Path outputDirectory;

/**
* A path to the file that contains the password for the proxy authentication.
*/
/* package */ Path proxyPasswordPath;
/**
* Additional meta data files to upload together with the coverage XML.
*/
Expand Down Expand Up @@ -226,6 +229,10 @@ public String getOriginalOptionsString() {
return originalOptionsString;
}

public Path getProxyPasswordPath() {
return proxyPasswordPath;
}

/**
* Remove parts of the API key for security reasons from the options string. String is used for logging purposes.
* <p>
Expand Down
Expand Up @@ -193,6 +193,9 @@ private boolean handleAgentOptions(AgentOptions options, String key, String valu
case LOGGING_CONFIG_OPTION:
options.loggingConfig = filePatternResolver.parsePath(key, value);
return true;
case "proxy-password-file":
options.proxyPasswordPath = filePatternResolver.parsePath(key, value);
return true;
case "interval":
options.dumpIntervalInMinutes = parseInt(key, value);
return true;
Expand Down
@@ -0,0 +1,51 @@
package com.teamscale.jacoco.agent.util;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
* Clone of the file system utilities.
* <p>
* This shall be removed with TS-37964.
*/
public class FileSystemUtilsClone {

/**
* Clone of {@link com.teamscale.client.FileSystemUtils#listFilesRecursively(File, FileFilter)}
*/
public static List<File> listFilesRecursively(File directory, FileFilter filter) {
if (directory == null || !directory.isDirectory()) {
return Collections.emptyList();
}
List<File> result = new ArrayList<>();
listFilesRecursively(directory, result, filter);
return result;
}

/**
* Clone of {@link com.teamscale.client.FileSystemUtils#listFilesRecursively(File, Collection, FileFilter)}
*/
private static void listFilesRecursively(File directory, Collection<File> result, FileFilter filter) {
File[] files = directory.listFiles();
if (files == null) {
// From the docs of `listFiles`:
// "If this abstract pathname does not denote a directory, then this method returns null."
// Based on this, it seems to be ok to just return here without throwing an exception.
return;
}

for (File file : files) {
if (file.isDirectory()) {
listFilesRecursively(file, result, filter);
}
if (filter == null || filter.accept(file)) {
result.add(file);
}
}
}

}
2 changes: 1 addition & 1 deletion build.gradle.kts
Expand Up @@ -5,7 +5,7 @@ plugins {

group = "com.teamscale"

val appVersion by extra("33.0.0")
val appVersion by extra("33.1.2")

val snapshotVersion = appVersion + if (VersionUtils.isTaggedRelease()) "" else "-SNAPSHOT"

Expand Down
16 changes: 8 additions & 8 deletions gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
jetty = "9.4.53.v20231009"
jetty = "9.4.54.v20240208"
jersey = "2.41"
jackson = "2.16.0"
# When upgrading JaCoCo to a newer version make sure to
Expand All @@ -9,8 +9,8 @@ jacoco = "0.8.11"
# We need to stay on the 1.3.x release line as 1.4.x requires Java 11
logback = "1.3.14"
retrofit = "2.9.0"
junit = "5.10.1"
junitPlatform = "1.10.1"
junit = "5.10.2"
junitPlatform = "1.10.2"
okhttp = "4.12.0"
mockito = "4.11.0"
picocli = "4.7.5"
Expand Down Expand Up @@ -49,12 +49,12 @@ okhttp-mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.
spark = { module = "com.sparkjava:spark-core", version = "2.9.4" }
jcommander = { module = "com.beust:jcommander", version = "1.82" }
teamscaleLibCommons = { module = "com.teamscale:teamscale-lib-commons", version = "9.4.1" }
commonsCodec = { module = "commons-codec:commons-codec", version = "1.16.0" }
commonsCodec = { module = "commons-codec:commons-codec", version = "1.16.1" }
commonsLang = { module="org.apache.commons:commons-lang3", version="3.14.0" }
commonsIo = { module="commons-io:commons-io", version="2.15.1" }
slf4j-api = { module = "org.slf4j:slf4j-api", version = "2.0.11" }
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.8.0.202311291450-r" }
okio = { module = "com.squareup.okio:okio", version = "3.7.0" }
slf4j-api = { module = "org.slf4j:slf4j-api", version = "2.0.12" }
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "6.9.0.202403050737-r" }
okio = { module = "com.squareup.okio:okio", version = "3.8.0" }

picocli-core = { module = "info.picocli:picocli", version.ref = "picocli" }
picocli-codegen = { module = "info.picocli:picocli-codegen", version.ref = "picocli" }
Expand All @@ -67,7 +67,7 @@ junit-platform-engine = { module = "org.junit.platform:junit-platform-engine", v
junit-platform-commons = { module = "org.junit.platform:junit-platform-commons", version.ref = "junitPlatform" }

junit4 = { module = "junit:junit", version = "4.13.2" }
assertj = { module = "org.assertj:assertj-core", version = "3.25.2" }
assertj = { module = "org.assertj:assertj-core", version = "3.25.3" }
jsonassert = { module = "org.skyscreamer:jsonassert", version = "1.5.1" }

mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 2 additions & 0 deletions system-tests/tia-maven/maven-exec-file-project/.gitignore
@@ -0,0 +1,2 @@
target
.idea
@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

0 comments on commit 407b5b1

Please sign in to comment.