Fix extractjar task ci (#33272)

Remove tasks to check license and notice and add build integration test instead.

Closes #33201
This commit is contained in:
Alpar Torok 2018-09-03 10:18:34 +03:00 committed by GitHub
parent 3a1dad1050
commit 3c367a2c46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 202 additions and 121 deletions

View File

@ -20,16 +20,12 @@
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import org.apache.tools.ant.taskdefs.condition.Os import org.apache.tools.ant.taskdefs.condition.Os
import org.elasticsearch.gradle.BuildPlugin import org.elasticsearch.gradle.BuildPlugin
import org.elasticsearch.gradle.LoggedExec
import org.elasticsearch.gradle.Version import org.elasticsearch.gradle.Version
import org.elasticsearch.gradle.VersionCollection import org.elasticsearch.gradle.VersionCollection
import org.elasticsearch.gradle.VersionProperties import org.elasticsearch.gradle.VersionProperties
import org.elasticsearch.gradle.plugin.PluginBuildPlugin import org.elasticsearch.gradle.plugin.PluginBuildPlugin
import org.gradle.plugins.ide.eclipse.model.SourceFolder import org.gradle.plugins.ide.eclipse.model.SourceFolder
import java.nio.file.Files
import java.nio.file.Path
plugins { plugins {
id 'com.gradle.build-scan' version '1.13.2' id 'com.gradle.build-scan' version '1.13.2'
} }
@ -576,62 +572,6 @@ wrapper {
} }
} }
static void assertLinesInFile(final Path path, final List<String> expectedLines) {
final List<String> actualLines = Files.readAllLines(path)
int line = 0
for (final String expectedLine : expectedLines) {
final String actualLine = actualLines.get(line)
if (expectedLine != actualLine) {
throw new GradleException("expected line [${line + 1}] in [${path}] to be [${expectedLine}] but was [${actualLine}]")
}
line++
}
}
/*
* Check that all generated JARs have our NOTICE.txt and an appropriate
* LICENSE.txt in them. We configurate this in gradle but we'd like to
* be extra paranoid.
*/
subprojects { project ->
project.tasks.withType(Jar).whenTaskAdded { jarTask ->
final Task extract = project.task("extract${jarTask.name.capitalize()}", type: LoggedExec) {
dependsOn jarTask
ext.destination = project.buildDir.toPath().resolve("jar-extracted/${jarTask.name}")
commandLine "${->new File(rootProject.compilerJavaHome, 'bin/jar')}",
'xf', "${-> jarTask.outputs.files.singleFile}", 'META-INF/LICENSE.txt', 'META-INF/NOTICE.txt'
workingDir destination
onlyIf {jarTask.enabled}
doFirst {
project.delete(destination)
Files.createDirectories(destination)
}
}
final Task checkNotice = project.task("verify${jarTask.name.capitalize()}Notice") {
dependsOn extract
onlyIf {jarTask.enabled}
doLast {
final List<String> noticeLines = Files.readAllLines(project.noticeFile.toPath())
final Path noticePath = extract.destination.resolve('META-INF/NOTICE.txt')
assertLinesInFile(noticePath, noticeLines)
}
}
project.check.dependsOn checkNotice
final Task checkLicense = project.task("verify${jarTask.name.capitalize()}License") {
dependsOn extract
onlyIf {jarTask.enabled}
doLast {
final List<String> licenseLines = Files.readAllLines(project.licenseFile.toPath())
final Path licensePath = extract.destination.resolve('META-INF/LICENSE.txt')
assertLinesInFile(licensePath, licenseLines)
}
}
project.check.dependsOn checkLicense
}
}
/* Remove assemble/dependenciesInfo on all qa projects because we don't need to publish /* Remove assemble/dependenciesInfo on all qa projects because we don't need to publish
* artifacts for them. */ * artifacts for them. */
gradle.projectsEvaluated { gradle.projectsEvaluated {

View File

@ -56,6 +56,7 @@ import org.gradle.util.GradleVersion
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.time.ZoneOffset import java.time.ZoneOffset
import java.time.ZonedDateTime import java.time.ZonedDateTime
/** /**
* Encapsulates build configuration for elasticsearch projects. * Encapsulates build configuration for elasticsearch projects.
*/ */
@ -739,6 +740,7 @@ class BuildPlugin implements Plugin<Project> {
} }
from(project.noticeFile.parent) { from(project.noticeFile.parent) {
include project.noticeFile.name include project.noticeFile.name
rename { 'NOTICE.txt' }
} }
} }
} }

View File

@ -0,0 +1,76 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.gradle;
import org.apache.commons.io.IOUtils;
import org.elasticsearch.gradle.test.GradleIntegrationTestCase;
import org.gradle.testkit.runner.BuildResult;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class BuildPluginIT extends GradleIntegrationTestCase {
public void testPluginCanBeApplied() {
BuildResult result = getGradleRunner("elasticsearch.build")
.withArguments("hello", "-s")
.build();
assertTaskSuccessful(result, ":hello");
assertOutputContains("build plugin can be applied");
}
public void testCheckTask() {
BuildResult result = getGradleRunner("elasticsearch.build")
.withArguments("check", "assemble", "-s", "-Dlocal.repo.path=" + getLocalTestRepoPath())
.build();
assertTaskSuccessful(result, ":check");
}
public void testLicenseAndNotice() throws IOException {
BuildResult result = getGradleRunner("elasticsearch.build")
.withArguments("clean", "assemble", "-s", "-Dlocal.repo.path=" + getLocalTestRepoPath())
.build();
assertTaskSuccessful(result, ":assemble");
assertBuildFileExists(result, "elasticsearch.build", "distributions/elasticsearch.build.jar");
try (ZipFile zipFile = new ZipFile(new File(
getBuildDir("elasticsearch.build"), "distributions/elasticsearch.build.jar"
))) {
ZipEntry licenseEntry = zipFile.getEntry("META-INF/LICENSE.txt");
ZipEntry noticeEntry = zipFile.getEntry("META-INF/NOTICE.txt");
assertNotNull("Jar does not have META-INF/LICENSE.txt", licenseEntry);
assertNotNull("Jar does not have META-INF/NOTICE.txt", noticeEntry);
try (
InputStream license = zipFile.getInputStream(licenseEntry);
InputStream notice = zipFile.getInputStream(noticeEntry)
) {
assertEquals("this is a test license file", IOUtils.toString(license, StandardCharsets.UTF_8.name()));
assertEquals("this is a test notice file", IOUtils.toString(notice, StandardCharsets.UTF_8.name()));
}
}
}
}

View File

@ -2,74 +2,57 @@ package org.elasticsearch.gradle.precommit;
import org.elasticsearch.gradle.test.GradleIntegrationTestCase; import org.elasticsearch.gradle.test.GradleIntegrationTestCase;
import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
public class NamingConventionsTaskIT extends GradleIntegrationTestCase { public class NamingConventionsTaskIT extends GradleIntegrationTestCase {
public void testPluginCanBeApplied() {
BuildResult result = GradleRunner.create()
.withProjectDir(getProjectDir("namingConventionsSelfTest"))
.withArguments("hello", "-s", "-PcheckForTestsInMain=false")
.withPluginClasspath()
.build();
assertEquals(TaskOutcome.SUCCESS, result.task(":hello").getOutcome());
String output = result.getOutput();
assertTrue(output, output.contains("build plugin can be applied"));
}
public void testNameCheckFailsAsItShould() { public void testNameCheckFailsAsItShould() {
BuildResult result = GradleRunner.create() BuildResult result = getGradleRunner("namingConventionsSelfTest")
.withProjectDir(getProjectDir("namingConventionsSelfTest"))
.withArguments("namingConventions", "-s", "-PcheckForTestsInMain=false") .withArguments("namingConventions", "-s", "-PcheckForTestsInMain=false")
.withPluginClasspath()
.buildAndFail(); .buildAndFail();
assertNotNull("task did not run", result.task(":namingConventions")); assertTaskFailed(result, ":namingConventions");
assertEquals(TaskOutcome.FAILED, result.task(":namingConventions").getOutcome()); assertOutputContains(
String output = result.getOutput(); result.getOutput(),
for (String line : Arrays.asList( // TODO: java9 Set.of
new HashSet<>(
Arrays.asList(
"Not all subclasses of UnitTestCase match the naming convention. Concrete classes must end with [Tests]:",
"* org.elasticsearch.test.WrongName",
"Found inner classes that are tests, which are excluded from the test runner:", "Found inner classes that are tests, which are excluded from the test runner:",
"* org.elasticsearch.test.NamingConventionsCheckInMainIT$InternalInvalidTests", "* org.elasticsearch.test.NamingConventionsCheckInMainIT$InternalInvalidTests",
"Classes ending with [Tests] must subclass [UnitTestCase]:", "Classes ending with [Tests] must subclass [UnitTestCase]:",
"* org.elasticsearch.test.NamingConventionsCheckInMainTests", "* org.elasticsearch.test.NamingConventionsCheckInMainTests",
"* org.elasticsearch.test.NamingConventionsCheckInMainIT", "* org.elasticsearch.test.NamingConventionsCheckInMainIT"
"Not all subclasses of UnitTestCase match the naming convention. Concrete classes must end with [Tests]:", )
"* org.elasticsearch.test.WrongName")) { )
assertTrue(
"expected: '" + line + "' but it was not found in the output:\n" + output,
output.contains(line)
); );
} }
}
public void testNameCheckFailsAsItShouldWithMain() { public void testNameCheckFailsAsItShouldWithMain() {
BuildResult result = GradleRunner.create() BuildResult result = getGradleRunner("namingConventionsSelfTest")
.withProjectDir(getProjectDir("namingConventionsSelfTest"))
.withArguments("namingConventions", "-s", "-PcheckForTestsInMain=true") .withArguments("namingConventions", "-s", "-PcheckForTestsInMain=true")
.withPluginClasspath()
.buildAndFail(); .buildAndFail();
assertNotNull("task did not run", result.task(":namingConventions")); assertTaskFailed(result, ":namingConventions");
assertEquals(TaskOutcome.FAILED, result.task(":namingConventions").getOutcome()); assertOutputContains(
result.getOutput(),
String output = result.getOutput(); // TODO: java9 Set.of
for (String line : Arrays.asList( new HashSet<>(
Arrays.asList(
"Classes ending with [Tests] or [IT] or extending [UnitTestCase] must be in src/test/java:", "Classes ending with [Tests] or [IT] or extending [UnitTestCase] must be in src/test/java:",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$DummyInterfaceTests", "* org.elasticsearch.test.NamingConventionsCheckBadClasses$DummyInterfaceTests",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$DummyInterfaceTests",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$DummyAbstractTests", "* org.elasticsearch.test.NamingConventionsCheckBadClasses$DummyAbstractTests",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$InnerTests", "* org.elasticsearch.test.NamingConventionsCheckBadClasses$InnerTests",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$NotImplementingTests", "* org.elasticsearch.test.NamingConventionsCheckBadClasses$NotImplementingTests",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$WrongNameTheSecond", "* org.elasticsearch.test.NamingConventionsCheckBadClasses$WrongNameTheSecond",
"* org.elasticsearch.test.NamingConventionsCheckBadClasses$WrongName")) { "* org.elasticsearch.test.NamingConventionsCheckBadClasses$WrongName"
assertTrue( )
"expected: '" + line + "' but it was not found in the output:\n"+output, )
output.contains(line)
); );
} }
}
} }

View File

@ -10,6 +10,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -47,6 +48,12 @@ public abstract class GradleIntegrationTestCase extends GradleUnitTestCase {
} }
} }
protected void assertOutputContains(String output, Set<String> lines) {
for (String line : lines) {
assertOutputContains(output, line);
}
}
protected void assertOutputContains(String output, String line) { protected void assertOutputContains(String output, String line) {
assertTrue( assertTrue(
"Expected the following line in output:\n\n" + line + "\n\nOutput is:\n" + output, "Expected the following line in output:\n\n" + line + "\n\nOutput is:\n" + output,
@ -82,7 +89,7 @@ public abstract class GradleIntegrationTestCase extends GradleUnitTestCase {
"\n\nOutput is:\n" + result.getOutput()); "\n\nOutput is:\n" + result.getOutput());
} }
assertEquals( assertEquals(
"Expected task to be successful but it was: " + task.getOutcome() + "Expected task `" + taskName +"` to be successful but it was: " + task.getOutcome() +
taskOutcome + "\n\nOutput is:\n" + result.getOutput() , taskOutcome + "\n\nOutput is:\n" + result.getOutput() ,
taskOutcome, taskOutcome,
task.getOutcome() task.getOutcome()

View File

@ -0,0 +1 @@
this is a test license file

View File

@ -0,0 +1 @@
this is a test notice file

View File

@ -0,0 +1,36 @@
plugins {
id 'java'
id 'elasticsearch.build'
}
ext.licenseFile = file("LICENSE")
ext.noticeFile = file("NOTICE")
dependencies {
compile "junit:junit:${versions.junit}"
// missing classes in thirdparty audit
compile 'org.hamcrest:hamcrest-core:1.3'
}
repositories {
mavenCentral()
repositories {
maven {
url System.getProperty("local.repo.path")
}
}
}
// todo remove offending rules
forbiddenApisMain.enabled = false
forbiddenApisTest.enabled = false
// requires dependency on testing fw
jarHell.enabled = false
// we don't have tests for now
test.enabled = false
task hello {
doFirst {
println "build plugin can be applied"
}
}

View File

@ -0,0 +1 @@
42a25dc3219429f0e5d060061f71acb49bf010a0

View File

@ -0,0 +1 @@
2973d150c0dc1fefe998f834810d68f278ea58ec

View File

@ -0,0 +1,26 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch;
/**
* This is just a test class
*/
public class SampleClass {
}

View File

@ -13,14 +13,8 @@ thirdPartyAudit.enabled = false
ext.licenseFile = file("$buildDir/dummy/license") ext.licenseFile = file("$buildDir/dummy/license")
ext.noticeFile = file("$buildDir/dummy/notice") ext.noticeFile = file("$buildDir/dummy/notice")
task hello {
doFirst {
println "build plugin can be applied"
}
}
dependencies { dependencies {
compile "junit:junit:${versions.junit}" compile "junit:junit:4.12"
} }
namingConventions { namingConventions {

View File

@ -23,6 +23,7 @@ import org.elasticsearch.gradle.NoticeTask
import org.elasticsearch.gradle.test.RunTask import org.elasticsearch.gradle.test.RunTask
import org.apache.tools.ant.filters.FixCrLfFilter import org.apache.tools.ant.filters.FixCrLfFilter
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
Collection distributions = project('archives').subprojects + project('packages').subprojects Collection distributions = project('archives').subprojects + project('packages').subprojects
@ -504,4 +505,16 @@ subprojects {
} }
return result return result
} }
ext.assertLinesInFile = { Path path, List<String> expectedLines ->
final List<String> actualLines = Files.readAllLines(path)
int line = 0
for (final String expectedLine : expectedLines) {
final String actualLine = actualLines.get(line)
if (expectedLine != actualLine) {
throw new GradleException("expected line [${line + 1}] in [${path}] to be [${expectedLine}] but was [${actualLine}]")
}
line++
}
}
} }