Skip to content

Commit 993000d

Browse files
SCANMAVEN-237 Test sensor context config, system properties, and environment variables passed to the bootstrapped JRE (#246)
1 parent 52c4e6d commit 993000d

File tree

6 files changed

+149
-15
lines changed

6 files changed

+149
-15
lines changed

its/pom.xml

+14-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,22 @@
2020
</properties>
2121

2222
<dependencies>
23+
<dependency>
24+
<groupId>org.junit.jupiter</groupId>
25+
<artifactId>junit-jupiter-api</artifactId>
26+
<version>5.11.3</version>
27+
<scope>test</scope>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.junit.jupiter</groupId>
31+
<artifactId>junit-jupiter-engine</artifactId>
32+
<version>5.11.3</version>
33+
<scope>test</scope>
34+
</dependency>
2335
<dependency>
2436
<groupId>org.sonarsource.orchestrator</groupId>
2537
<artifactId>sonar-orchestrator-junit5</artifactId>
26-
<version>4.8.0.1898</version>
38+
<version>5.0.0.2065</version>
2739
<scope>test</scope>
2840
</dependency>
2941
<dependency>
@@ -41,7 +53,7 @@
4153
<dependency>
4254
<groupId>org.assertj</groupId>
4355
<artifactId>assertj-core</artifactId>
44-
<version>3.9.0</version>
56+
<version>3.26.3</version>
4557
<scope>test</scope>
4658
</dependency>
4759
<dependency>

its/projects/maven/bootstrap-small-project/pom.xml

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@
88
<properties>
99
<maven.compiler.source>11</maven.compiler.source>
1010
<maven.compiler.target>11</maven.compiler.target>
11+
<sonar.java.fileByFile>true</sonar.java.fileByFile>
12+
<!--
13+
This property will be ignored because:
14+
- We will run sonar:sonar with the SONAR_SCANNER_JAVA_OPTS environment variable that has priority on pom.xml properties
15+
- We will run sonar:sonar with the -Dsonar.scanner.javaOpts command line argument that has priority on everything
16+
-->
17+
<sonar.scanner.javaOpts>-Dhttp.proxyUser=my-custom-user-from-pom-xml</sonar.scanner.javaOpts>
1118
</properties>
1219

20+
<dependencies>
21+
<dependency>
22+
<groupId>com.google.code.findbugs</groupId>
23+
<artifactId>jsr305</artifactId>
24+
<version>3.0.2</version>
25+
<scope>provided</scope>
26+
</dependency>
27+
</dependencies>
28+
1329
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package org.example;
2+
3+
public interface Hello {
4+
}

its/src/test/java/com/sonar/maven/it/suite/BootstrapTest.java

+83-6
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@
2828
import java.nio.file.Files;
2929
import java.nio.file.Path;
3030
import java.util.Properties;
31+
import org.assertj.core.api.SoftAssertions;
32+
import org.assertj.core.api.StringAssert;
3133
import org.junit.jupiter.api.Test;
3234

35+
import static com.sonar.maven.it.ItUtils.locateProjectDir;
3336
import static org.assertj.core.api.Assertions.assertThat;
3437

35-
public class BootstrapTest extends AbstractMavenTest {
38+
class BootstrapTest extends AbstractMavenTest {
3639

3740
@Test
3841
void test_unsupported_platform() {
@@ -65,28 +68,102 @@ void test_supported_arch_to_assert_jre_used() throws IOException {
6568
MavenBuild build = MavenBuild.create(ItUtils.locateProjectPom(projectName))
6669
.setProperty("sonar.login", ORCHESTRATOR.getDefaultAdminToken())
6770
.setProperty("sonar.host.url", ORCHESTRATOR.getServer().getUrl())
71+
.setEnvironmentVariable("DUMP_SENSOR_PROPERTIES", "" +
72+
"any.property.name," +
73+
"sonar.java.fileByFile," +
74+
"sonar.java.file.suffixes," +
75+
"sonar.projectKey," +
76+
"sonar.projectBaseDir," +
77+
"sonar.sources," +
78+
"sonar.working.directory," +
79+
"sonar.java.libraries," +
80+
"sonar.java.source," +
81+
"sonar.java.target," +
82+
"sonar.java.test.libraries," +
83+
"sonar.java.jdkHome")
84+
.setEnvironmentVariable("DUMP_ENV_PROPERTIES", "" +
85+
"ANY_ENV_VAR")
86+
.setEnvironmentVariable("DUMP_SYSTEM_PROPERTIES", "" +
87+
"http.proxyUser,"+
88+
"http.nonProxyHosts," +
89+
"java.home")
90+
.setEnvironmentVariable("ANY_ENV_VAR", "42")
91+
// http.nonProxyHosts will only be present in the maven context and not in the provisioned JRE
92+
.setProperty("http.nonProxyHosts", "localhost|my-custom-non-proxy.server.com")
93+
// Any property will be passed to the sensorContext.config()
94+
.setProperty("any.property.name", "foo42")
95+
// This property will be ignored because of the bellow "sonar.scanner.javaOpts" property that has priority
96+
.setEnvironmentVariable("SONAR_SCANNER_JAVA_OPTS", "-Dhttp.proxyUser=my-custom-user-from-env")
97+
// Set system property on the provisioned JRE
98+
.setProperty("sonar.scanner.javaOpts", "-Dhttp.proxyUser=my-custom-user-from-system-properties")
6899
.setGoals(cleanSonarGoal());
69100

70-
71101
BuildResult result = validateBuildWithCE(runner.runQuietly(null, build));
72102
assertThat(result.isSuccess()).isTrue();
73103
Path propertiesFile = ItUtils.locateProjectDir(projectName).toPath().resolve("target/sonar/dumpSensor.system.properties");
74104
Properties props = new Properties();
75105
props.load(Files.newInputStream(propertiesFile));
76106

107+
Path smallProjectDir = locateProjectDir("maven").getAbsoluteFile().toPath().resolve("bootstrap-small-project");
108+
109+
SoftAssertions softly = new SoftAssertions();
110+
111+
// Environment variables
112+
softly.assertThat(props.getProperty("ANY_ENV_VAR")).isEqualTo( "42");
113+
114+
// User defined in its/projects/maven/bootstrap-small-project/pom.xml properties
115+
softly.assertThat(props.getProperty("sonar.java.fileByFile")).isEqualTo( "true");
116+
117+
// SonarQube properties
118+
softly.assertThat(props.getProperty("sonar.java.file.suffixes")).isEqualTo( ".java,.jav");
119+
120+
// Project properties
121+
softly.assertThat(props.getProperty("sonar.projectKey")).isEqualTo( "org.sonarsource.maven.its:bootstrap-small-project");
122+
softly.assertThat(props.getProperty("sonar.projectBaseDir")).isEqualTo( smallProjectDir.toString());
123+
softly.assertThat(props.getProperty("sonar.sources")).isEqualTo( smallProjectDir.resolve("pom.xml") + "," + smallProjectDir.resolve("src").resolve("main").resolve("java"));
124+
softly.assertThat(props.getProperty("sonar.working.directory")).isEqualTo( smallProjectDir.resolve("target").resolve("sonar").toString());
125+
126+
// Any properties are present in the sensor context
127+
softly.assertThat(props.getProperty("any.property.name")).contains("foo42");
128+
129+
// Java analyzers properties
130+
softly.assertThat(props.getProperty("sonar.java.libraries")).contains("jsr305-3.0.2.jar");
131+
softly.assertThat(props.getProperty("sonar.java.source")).isEqualTo( "11");
132+
softly.assertThat(props.getProperty("sonar.java.target")).isEqualTo( "11");
133+
softly.assertThat(props.getProperty("sonar.java.test.libraries")).contains("jsr305-3.0.2.jar");
134+
// sonar.java.jdkHome should be the one used by "mvn sonar:sonar", by default maven uses JAVA_HOME
135+
String javaHome = System.getenv("JAVA_HOME");
136+
if (javaHome == null) {
137+
javaHome = System.getProperty("java.home");
138+
}
139+
softly.assertThat(props.getProperty("sonar.java.jdkHome")).isEqualTo( new File(javaHome).getCanonicalPath());
140+
141+
StringAssert javaHomeAssertion = softly.assertThat(props.getProperty("java.home")).isNotEmpty();
77142
if (ORCHESTRATOR.getServer().version().isGreaterThanOrEquals(10, 6)) {
78143
//we test that we are actually using the JRE downloaded from SQ
79-
assertThat(props.getProperty("java.home"))
80-
.isNotEmpty()
144+
javaHomeAssertion
81145
.isNotEqualTo(System.getProperty("java.home"))
82146
.contains(".sonar" + File.separator + "cache");
147+
148+
// System properties of the initial JRE are intentionally not set on the provisioned JRE
149+
softly.assertThat(props.getProperty("http.nonProxyHosts"))
150+
.isEmpty();
151+
152+
// System properties defined in "sonar.scanner.javaOpts" are set on the provisioned JRE
153+
softly.assertThat(props.getProperty("http.proxyUser")).isEqualTo("my-custom-user-from-system-properties");
83154
} else {
84155
//we test that we are using the system JRE
85-
assertThat(props.getProperty("java.home"))
86-
.isNotEmpty()
156+
javaHomeAssertion
87157
.isEqualTo(System.getProperty("java.home"))
88158
.doesNotContain(".sonar" + File.separator + "cache");
159+
160+
softly.assertThat(props.getProperty("http.nonProxyHosts"))
161+
.isEqualTo("localhost|my-custom-non-proxy.server.com");
162+
163+
// System properties defined in "sonar.scanner.javaOpts" are ignored outside the provisioned JRE
164+
softly.assertThat(props.getProperty("http.proxyUser")).isEmpty();
89165
}
166+
softly.assertAll();
90167
}
91168

92169
}

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@
172172
<dependency>
173173
<groupId>org.assertj</groupId>
174174
<artifactId>assertj-core</artifactId>
175-
<version>3.24.2</version>
175+
<version>3.26.3</version>
176176
<scope>test</scope>
177177
</dependency>
178178
<dependency>

property-dump-plugin/src/main/java/org/sonar/dump/PropertyDumpPlugin.java

+31-6
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@
2222
import java.io.IOException;
2323
import java.nio.file.Files;
2424
import java.nio.file.Path;
25+
import java.util.Arrays;
26+
import java.util.List;
27+
import java.util.Optional;
28+
import java.util.Properties;
2529
import org.slf4j.Logger;
2630
import org.slf4j.LoggerFactory;
2731
import org.sonar.api.Plugin;
2832
import org.sonar.api.batch.sensor.Sensor;
2933
import org.sonar.api.batch.sensor.SensorContext;
3034
import org.sonar.api.batch.sensor.SensorDescriptor;
35+
import org.sonar.api.config.Configuration;
3136

3237
public class PropertyDumpPlugin implements Plugin, Sensor {
3338

@@ -45,17 +50,37 @@ public void describe(SensorDescriptor sensorDescriptor) {
4550

4651
@Override
4752
public void execute(SensorContext sensorContext) {
48-
var props = System.getProperties();
4953
try {
5054
Path filePath = sensorContext.fileSystem().workDir().toPath().resolve("dumpSensor.system.properties");
51-
LOG.info("Dumping system properties to {}", filePath);
52-
props.stringPropertyNames().stream()
53-
.filter(key -> key.startsWith("java."))
54-
.forEach(key -> LOG.info("{}={}", key, props.getProperty(key)));
55+
LOG.info("Dumping sensorContext properties, environment variables, and system properties to {}", filePath);
56+
var props = new Properties();
57+
Configuration config = sensorContext.config();
58+
getPropertyKeys("DUMP_SENSOR_PROPERTIES").forEach(key -> props.setProperty(key, nonNull(config.get(key))));
59+
getPropertyKeys("DUMP_ENV_PROPERTIES").forEach(key -> props.setProperty(key, nonNull(System.getenv(key))));
60+
getPropertyKeys("DUMP_SYSTEM_PROPERTIES").forEach(key -> props.setProperty(key, nonNull(System.getProperty(key, ""))));
61+
props.stringPropertyNames().forEach(key -> LOG.info("{}={}", key, props.getProperty(key)));
5562
props.store(Files.newOutputStream(filePath), null);
5663
} catch (IOException e) {
57-
throw new RuntimeException(e);
64+
throw new IllegalStateException(e.getClass().getSimpleName() + ": " + e.getMessage(), e);
5865
}
5966
}
6067

68+
private static String nonNull(Object value) {
69+
if (value instanceof Optional<?> opt) {
70+
value = opt.orElse(null);
71+
}
72+
if (value != null) {
73+
return value.toString();
74+
}
75+
return "";
76+
}
77+
78+
private static List<String> getPropertyKeys(String envName) {
79+
String list = System.getenv(envName);
80+
if (list == null) {
81+
return List.of();
82+
}
83+
return Arrays.asList(list.replace(" ", "").split(",", -1));
84+
}
85+
6186
}

0 commit comments

Comments
 (0)