From 9f97319b3c7e31ceadd85c0f6b7ac1d342434d16 Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Thu, 18 Jul 2019 10:00:19 +0300 Subject: [PATCH] Detect process third party audit being killed by OOM (#44269) * Detect process third party audit being killed by OOM It's very common for the third party audit to be killed by the OOM killer when the system is running low on memory. Since the forbidden APIs call is expected to fail, we were ignoring these and incorrectly interpreting the partial output. With this change we detect and provide a proper error message when this happens. --- .../gradle/precommit/ThirdPartyAuditTask.java | 20 ++++++++++++++++- .../precommit/ThirdPartyAuditTaskIT.java | 22 +------------------ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java index 7ddec2b887e..4ed1543df1b 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTask.java @@ -18,8 +18,10 @@ */ package org.elasticsearch.gradle.precommit; +import de.thetaphi.forbiddenapis.cli.CliMain; import org.apache.commons.io.output.NullOutputStream; import org.elasticsearch.gradle.JdkJarHellCheck; +import org.elasticsearch.gradle.OS; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.JavaVersion; @@ -51,6 +53,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; @@ -69,6 +72,12 @@ public class ThirdPartyAuditTask extends DefaultTask { private static final Pattern VIOLATION_PATTERN = Pattern.compile( "\\s\\sin ([a-zA-Z0-9$.]+) \\(.*\\)" ); + private static final int SIG_KILL_EXIT_VALUE = 137; + private static final List EXPECTED_EXIT_CODES = Arrays.asList( + CliMain.EXIT_SUCCESS, + CliMain.EXIT_VIOLATION, + CliMain.EXIT_UNSUPPORTED_JDK + ); private Set missingClassExcludes = new TreeSet<>(); @@ -327,7 +336,7 @@ public class ThirdPartyAuditTask extends DefaultTask { private String runForbiddenAPIsCli() throws IOException { ByteArrayOutputStream errorOut = new ByteArrayOutputStream(); - getProject().javaexec(spec -> { + ExecResult result = getProject().javaexec(spec -> { if (javaHome != null) { spec.setExecutable(javaHome + "/bin/java"); } @@ -336,6 +345,7 @@ public class ThirdPartyAuditTask extends DefaultTask { getRuntimeConfiguration(), getProject().getConfigurations().getByName("compileOnly") ); + spec.jvmArgs("-Xmx1g"); spec.setMain("de.thetaphi.forbiddenapis.cli.CliMain"); spec.args( "-f", getSignatureFile().getAbsolutePath(), @@ -348,10 +358,18 @@ public class ThirdPartyAuditTask extends DefaultTask { } spec.setIgnoreExitValue(true); }); + if (OS.current().equals(OS.LINUX) && result.getExitValue() == SIG_KILL_EXIT_VALUE) { + throw new IllegalStateException( + "Third party audit was killed buy SIGKILL, could be a victim of the Linux OOM killer" + ); + } final String forbiddenApisOutput; try (ByteArrayOutputStream outputStream = errorOut) { forbiddenApisOutput = outputStream.toString(StandardCharsets.UTF_8.name()); } + if (EXPECTED_EXIT_CODES.contains(result.getExitValue()) == false) { + throw new IllegalStateException("Forbidden APIs cli failed: " + forbiddenApisOutput); + } return forbiddenApisOutput; } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTaskIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTaskIT.java index b14b3538fc2..a57d6da0365 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTaskIT.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/ThirdPartyAuditTaskIT.java @@ -48,27 +48,7 @@ public class ThirdPartyAuditTaskIT extends GradleIntegrationTestCase { "-PcompileOnlyGroup=other.gradle:broken-log4j", "-PcompileOnlyVersion=0.0.1", "-PcompileGroup=other.gradle:dummy-io", "-PcompileVersion=0.0.1" ) - .build(); - - assertTaskSuccessful(result, ":empty"); - - result = getGradleRunner("thirdPartyAudit") - .withArguments("empty", "-s", - "-PcompileOnlyGroup=other.gradle:broken-log4j", "-PcompileOnlyVersion=0.0.1", - "-PcompileGroup=other.gradle:dummy-io", "-PcompileVersion=0.0.1" - ) - .build(); - - assertTaskUpToDate(result, ":empty"); - - result = getGradleRunner("thirdPartyAudit") - .withArguments("empty", "-s", - "-PcompileOnlyGroup=other.gradle:broken-log4j", "-PcompileOnlyVersion=0.0.1", - "-PcompileGroup=other.gradle:dummy-io", "-PcompileVersion=0.0.2" - ) - .build(); - - assertTaskSuccessful(result, ":empty"); + .buildAndFail(); } public void testViolationFoundAndCompileOnlyIgnored() {