Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ tasks.withType<Test>().configureEach {
!rootProject.providers.gradleProperty("rerun.tests.${project.name}").isPresent
}

// Trick to avoid on CI: "Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock."
// Use a task-specific user prefs directory
systemProperty("java.util.prefs.userRoot", "$buildDir/tmp/userPrefs/${name}")

// Split up tests that want to run forked in their own separate JVM for generated tasks
if (name.startsWith("forkedTest") || name.endsWith("ForkedTest")) {
setExcludes(emptyList())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import datadog.trace.api.config.CiVisibilityConfig
import datadog.trace.api.config.GeneralConfig
import datadog.trace.api.config.TraceInstrumentationConfig
import datadog.trace.api.config.TracerConfig
import java.nio.file.Paths
import spock.lang.Specification
import spock.lang.TempDir
import spock.util.environment.Jvm

import java.nio.file.Path

import static datadog.trace.util.ConfigStrings.propertyNameToSystemPropertyName

abstract class CiVisibilitySmokeTest extends Specification {
Expand All @@ -21,6 +25,9 @@ abstract class CiVisibilitySmokeTest extends Specification {

private static final Map<String,String> DEFAULT_TRACER_CONFIG = defaultJvmArguments()

@TempDir
protected Path prefsDir

protected static String buildJavaHome() {
if (Jvm.current.isJava8()) {
return System.getenv("JAVA_8_HOME")
Expand Down Expand Up @@ -69,6 +76,9 @@ abstract class CiVisibilitySmokeTest extends Specification {

protected List<String> buildJvmArguments(String mockBackendIntakeUrl, String serviceName, Map<String, String> additionalArgs) {
List<String> arguments = []

arguments += preventJulPrefsFileLock()

Map<String, String> argMap = buildJvmArgMap(mockBackendIntakeUrl, serviceName, additionalArgs)

// for convenience when debugging locally
Expand All @@ -85,6 +95,28 @@ abstract class CiVisibilitySmokeTest extends Specification {
return arguments
}

/**
* Trick to prevent jul Prefs file lock issue on forked processes, in particular in CI which
* runs on Linux and have competing processes trying to write to it, including the Gradle daemon.
*
* <pre><code>
* Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.
* </code></pre>
*
* Note, some tests can setup arguments on spec level, so `prefsDir` will be `null` during
* `setupSpec()`.
*/
protected String preventJulPrefsFileLock() {
String prefsPath = (prefsDir ?: tempUserPrefsPath()).toAbsolutePath()
return "-Djava.util.prefs.userRoot=$prefsPath".toString()
}

private static Path tempUserPrefsPath() {
String uniqueId = "${System.currentTimeMillis()}_${System.nanoTime()}_${Thread.currentThread().id}"
Path prefsPath = Paths.get(System.getProperty("java.io.tmpdir"), "gradle-test-userPrefs", uniqueId)
return prefsPath
}

protected verifyEventsAndCoverages(String projectName, String toolchain, String toolchainVersion, List<Map<String, Object>> events, List<Map<String, Object>> coverages, List<String> additionalDynamicTags = []) {
def additionalReplacements = ["content.meta.['test.toolchain']": "$toolchain:$toolchainVersion"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ public static ProcessBuilder createProcessBuilder(
String mainClassName,
String... params) {

// Trick to prevent jul preferences file lock issue on forked processes, in particular in CI
// which runs on Linux and have competing processes trying to write to it, including the
// Gradle daemon.
//
// Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.
String prefsDir =
System.getProperty("java.io.tmpdir")
+ File.separator
+ "userPrefs"
+ File.separator
+ mainClassName
+ "_"
+ System.nanoTime();

List<String> baseCommand =
Arrays.asList(
javaPath(),
Expand All @@ -37,7 +51,8 @@ public static ProcessBuilder createProcessBuilder(
"-javaagent:" + agentShadowJar(),
"-XX:ErrorFile=/tmp/hs_err_pid%p.log",
"-Ddd.env=smoketest",
"-Ddd.version=99");
"-Ddd.version=99",
"-Djava.util.prefs.userRoot=" + prefsDir);

List<String> command = new ArrayList<>();
command.addAll(baseCommand);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ class GradleDaemonSmokeTest extends AbstractGradleTest {
@TempDir
Path testKitFolder

def setupSpec() {
givenGradleProperties()
}

@IgnoreIf(reason = "Jacoco plugin does not work with OpenJ9 in older Gradle versions", value = {
JavaVirtualMachine.isJ9()
})
Expand Down Expand Up @@ -79,6 +75,7 @@ class GradleDaemonSmokeTest extends AbstractGradleTest {
def "test junit4 class ordering v#gradleVersion"() {
givenGradleVersionIsCompatibleWithCurrentJvm(gradleVersion)
givenGradleProjectFiles(projectName)
givenGradleProjectProperties()
ensureDependenciesDownloaded(gradleVersion)

mockBackend.givenKnownTests(true)
Expand Down Expand Up @@ -124,6 +121,7 @@ class GradleDaemonSmokeTest extends AbstractGradleTest {
givenGradleVersionIsCompatibleWithCurrentJvm(gradleVersion)
givenConfigurationCacheIsCompatibleWithCurrentPlatform(configurationCache)
givenGradleProjectFiles(projectName)
givenGradleProjectProperties()
ensureDependenciesDownloaded(gradleVersion)

mockBackend.givenFlakyRetries(flakyRetries)
Expand All @@ -150,7 +148,7 @@ class GradleDaemonSmokeTest extends AbstractGradleTest {
}
}

private void givenGradleProperties() {
private void givenGradleProjectProperties() {
assert new File(AGENT_JAR).isFile()

def ddApiKeyPath = testKitFolder.resolve(".dd.api.key")
Expand All @@ -173,7 +171,9 @@ class GradleDaemonSmokeTest extends AbstractGradleTest {
def arguments = buildJvmArguments(mockBackend.intakeUrl, TEST_SERVICE_NAME, additionalArgs)

def gradleProperties = "org.gradle.jvmargs=${arguments.join(" ")}".toString()
Files.write(testKitFolder.resolve("gradle.properties"), gradleProperties.getBytes())
// Write to projectFolder (per-test) instead of testKitFolder (shared), so each
// Gradle daemon gets its own unique preference directory
Files.write(projectFolder.resolve("gradle.properties"), gradleProperties.getBytes())
}

private BuildResult runGradleTests(String gradleVersion, boolean successExpected = true, boolean configurationCache = false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ abstract class AbstractSmokeTest extends ProcessManager {
def javaProperties() {
def tmpDir = "/tmp"

// Trick to prevent jul preferences file lock issue on forked processes, in particular in CI which
// runs on Linux and have competing processes trying to write to it, including the Gradle daemon.
//
// Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.
def prefsDir = "${tmpDir}/userPrefs/${this.getClass().simpleName}_${System.nanoTime()}"

def ret = [
"${getMaxMemoryArgumentForFork()}",
"${getMinMemoryArgumentForFork()}",
Expand All @@ -204,7 +210,8 @@ abstract class AbstractSmokeTest extends ProcessManager {
"-Ddd.profiling.ddprof.alloc.enabled=${isDdprofSafe()}",
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=${logLevel()}",
"-Dorg.slf4j.simpleLogger.defaultLogLevel=${logLevel()}",
"-Ddd.site="
"-Ddd.site=",
"-Djava.util.prefs.userRoot=${prefsDir}"
]
if (inferServiceName()) {
ret += "-Ddd.service.name=${SERVICE_NAME}"
Expand Down