-
Notifications
You must be signed in to change notification settings - Fork 546
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Regression test to certify legacy Ivy publication behavior (#560)
Adds a Gradle int test: Grandparent -> parent -> child pattern certifies that child project can transitively resolve references to schemas contained in grandparent's data-template jar.
- Loading branch information
Showing
4 changed files
with
488 additions
and
0 deletions.
There are no files selected for viewing
270 changes: 270 additions & 0 deletions
270
...om/linkedin/pegasus/gradle/publishing/PegasusPluginLegacyIvyPublishIntegrationTest.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,270 @@ | ||
package com.linkedin.pegasus.gradle.publishing | ||
|
||
import org.gradle.testkit.runner.GradleRunner | ||
import org.gradle.testkit.runner.TaskOutcome | ||
import org.junit.Rule | ||
import org.junit.rules.TemporaryFolder | ||
import spock.lang.Specification | ||
|
||
import java.util.zip.ZipFile | ||
|
||
/** | ||
* Regression test to certify legacy Ivy publication behavior | ||
* | ||
* <p>Grandparent -> parent -> child pattern certifies that the child project can transitively resolve references | ||
* to schemas contained in grandparent's data-template jar | ||
*/ | ||
class PegasusPluginLegacyIvyPublishIntegrationTest extends Specification { | ||
|
||
@Rule | ||
TemporaryFolder grandparentProject | ||
|
||
@Rule | ||
TemporaryFolder parentProject | ||
|
||
@Rule | ||
TemporaryFolder childProject | ||
|
||
@Rule | ||
TemporaryFolder localRepo | ||
|
||
URL localIvyRepo | ||
|
||
def setup() { | ||
localIvyRepo = localRepo.newFolder('local-ivy-repo').toURI().toURL() | ||
} | ||
|
||
def 'publishes and consumes dataTemplate configurations'() { | ||
given: | ||
def gradlePropertiesFile = grandparentProject.newFile('gradle.properties') | ||
gradlePropertiesFile << ''' | ||
|group=com.linkedin.pegasus-grandparent-demo | ||
|version=1.0.0 | ||
|'''.stripMargin() | ||
|
||
def settingsFile = grandparentProject.newFile('settings.gradle') | ||
settingsFile << "rootProject.name = 'grandparent'" | ||
|
||
grandparentProject.newFile('build.gradle') << """ | ||
|plugins { | ||
| id 'pegasus' | ||
|} | ||
| | ||
|repositories { | ||
| mavenCentral() | ||
|} | ||
| | ||
|dependencies { | ||
| dataTemplateCompile files(${System.getProperty('integTest.dataTemplateCompileDependencies')}) | ||
| pegasusPlugin files(${System.getProperty('integTest.pegasusPluginDependencies')}) | ||
|} | ||
| | ||
|//legacy publishing configuration | ||
|tasks.withType(Upload) { | ||
| repositories { | ||
| ivy { url '$localIvyRepo' } | ||
| } | ||
|}""".stripMargin() | ||
|
||
// Create a simple pdl schema, borrowed from restli-example-api | ||
def schemaFilename = 'LatLong.pdl' | ||
def grandparentPegasusDir = grandparentProject.newFolder('src', 'main', 'pegasus', 'com', 'linkedin', 'grandparent') | ||
def grandparentPdlFile = new File("$grandparentPegasusDir.path$File.separator$schemaFilename") | ||
grandparentPdlFile << '''namespace com.linkedin.grandparent | ||
| | ||
|record LatLong { | ||
| latitude: optional float | ||
| longitude: optional float | ||
|}'''.stripMargin() | ||
|
||
when: | ||
def grandparentRunner = GradleRunner.create() | ||
.withProjectDir(grandparentProject.root) | ||
.withPluginClasspath() | ||
.withArguments('uploadDataTemplate', 'uploadTestDataTemplate', 'uploadAvroSchema', 'uploadTestAvroSchema', 'uploadArchives', '-is') | ||
//.forwardOutput() | ||
//.withDebug(true) | ||
|
||
def grandparentResult = grandparentRunner.build() | ||
|
||
then: | ||
grandparentResult.task(':compileMainGeneratedDataTemplateJava').outcome == TaskOutcome.SUCCESS | ||
grandparentResult.task(':uploadDataTemplate').outcome == TaskOutcome.SUCCESS | ||
grandparentResult.task(':uploadArchives').outcome == TaskOutcome.SUCCESS | ||
|
||
def grandparentProjectIvyDescriptor = new File(localIvyRepo.path, 'com.linkedin.pegasus-grandparent-demo/grandparent/1.0.0/ivy-1.0.0.xml') | ||
grandparentProjectIvyDescriptor.exists() | ||
def grandparentProjectIvyDescriptorContents = grandparentProjectIvyDescriptor.text | ||
def expectedGrandparentContents = new File(Thread.currentThread().contextClassLoader.getResource('ivy/legacy/expectedGrandparentIvyDescriptorContents.txt').toURI()).text | ||
grandparentProjectIvyDescriptorContents.contains expectedGrandparentContents | ||
|
||
def grandparentProjectPrimaryArtifact = new File(localIvyRepo.path, 'com.linkedin.pegasus-grandparent-demo/grandparent/1.0.0/grandparent-1.0.0.jar') | ||
grandparentProjectPrimaryArtifact.exists() | ||
def grandparentProjectDataTemplateArtifact = new File(localIvyRepo.path, 'com.linkedin.pegasus-grandparent-demo/grandparent/1.0.0/grandparent-data-template-1.0.0.jar') | ||
grandparentProjectDataTemplateArtifact.exists() | ||
|
||
assertZipContains(grandparentProjectDataTemplateArtifact, 'com/linkedin/grandparent/LatLong.class') | ||
assertZipContains(grandparentProjectDataTemplateArtifact, 'pegasus/com/linkedin/grandparent/LatLong.pdl') | ||
|
||
when: 'a parent project consumes the grandparent project data-template jar' | ||
|
||
gradlePropertiesFile = parentProject.newFile('gradle.properties') | ||
gradlePropertiesFile << ''' | ||
|group=com.linkedin.pegasus-parent-demo | ||
|version=1.0.0 | ||
|'''.stripMargin() | ||
|
||
settingsFile = parentProject.newFile('settings.gradle') | ||
settingsFile << "rootProject.name = 'parent'" | ||
|
||
parentProject.newFile('build.gradle') << """ | ||
|plugins { | ||
| id 'pegasus' | ||
|} | ||
| | ||
|repositories { | ||
| ivy { url '$localIvyRepo' } | ||
| mavenCentral() | ||
|} | ||
| | ||
|dependencies { | ||
| dataTemplateCompile files(${System.getProperty('integTest.dataTemplateCompileDependencies')}) | ||
| pegasusPlugin files(${System.getProperty('integTest.pegasusPluginDependencies')}) | ||
| | ||
| dataModel group: 'com.linkedin.pegasus-grandparent-demo', name: 'grandparent', version: '1.0.0', configuration: 'dataTemplate' | ||
|} | ||
| | ||
|//legacy publishing configuration | ||
|tasks.withType(Upload) { | ||
| repositories { | ||
| ivy { url '$localIvyRepo' } | ||
| } | ||
|}""".stripMargin() | ||
|
||
// Create a simple pdl schema which references a grandparent type | ||
schemaFilename = 'EXIF.pdl' | ||
def parentPegasusDir = parentProject.newFolder('src', 'main', 'pegasus', 'com', 'linkedin', 'parent') | ||
def parentPdlFile = new File("$parentPegasusDir.path$File.separator$schemaFilename") | ||
parentPdlFile << '''namespace com.linkedin.parent | ||
| | ||
|import com.linkedin.grandparent.LatLong | ||
| | ||
|record EXIF { | ||
| isFlash: optional boolean = true | ||
| location: optional LatLong | ||
|}'''.stripMargin() | ||
|
||
def parentRunner = GradleRunner.create() | ||
.withProjectDir(parentProject.root) | ||
.withPluginClasspath() | ||
.withArguments('uploadDataTemplate', 'uploadTestDataTemplate', 'uploadAvroSchema', 'uploadTestAvroSchema', 'uploadArchives', '-is') | ||
//.forwardOutput() | ||
//.withDebug(true) | ||
|
||
def parentResult = parentRunner.build() | ||
|
||
then: | ||
parentResult.task(':compileMainGeneratedDataTemplateJava').outcome == TaskOutcome.SUCCESS | ||
parentResult.task(':uploadDataTemplate').outcome == TaskOutcome.SUCCESS | ||
parentResult.task(':uploadArchives').outcome == TaskOutcome.SUCCESS | ||
|
||
def parentProjectIvyDescriptor = new File(localIvyRepo.path, 'com.linkedin.pegasus-parent-demo/parent/1.0.0/ivy-1.0.0.xml') | ||
parentProjectIvyDescriptor.exists() | ||
def parentProjectIvyDescriptorContents = parentProjectIvyDescriptor.text | ||
def expectedParentContents = new File(Thread.currentThread().contextClassLoader.getResource('ivy/legacy/expectedParentIvyDescriptorContents.txt').toURI()).text | ||
parentProjectIvyDescriptorContents.contains expectedParentContents | ||
|
||
def parentProjectPrimaryArtifact = new File(localIvyRepo.path, 'com.linkedin.pegasus-parent-demo/parent/1.0.0/parent-1.0.0.jar') | ||
parentProjectPrimaryArtifact.exists() | ||
def parentProjectDataTemplateArtifact = new File(localIvyRepo.path, 'com.linkedin.pegasus-parent-demo/parent/1.0.0/parent-data-template-1.0.0.jar') | ||
parentProjectDataTemplateArtifact.exists() | ||
|
||
assertZipContains(parentProjectDataTemplateArtifact, 'com/linkedin/parent/EXIF.class') | ||
assertZipContains(parentProjectDataTemplateArtifact, 'pegasus/com/linkedin/parent/EXIF.pdl') | ||
|
||
when: 'a child project transitively consumes the grandparent project data-template jar' | ||
|
||
gradlePropertiesFile = childProject.newFile('gradle.properties') | ||
gradlePropertiesFile << ''' | ||
|group=com.linkedin.pegasus-child-demo | ||
|version=1.0.0 | ||
|'''.stripMargin() | ||
|
||
settingsFile = childProject.newFile('settings.gradle') | ||
settingsFile << "rootProject.name = 'child'" | ||
|
||
childProject.newFile('build.gradle') << """ | ||
|plugins { | ||
| id 'pegasus' | ||
|} | ||
| | ||
|repositories { | ||
| ivy { url '$localIvyRepo' } | ||
| mavenCentral() | ||
|} | ||
| | ||
|dependencies { | ||
| dataTemplateCompile files(${System.getProperty('integTest.dataTemplateCompileDependencies')}) | ||
| pegasusPlugin files(${System.getProperty('integTest.pegasusPluginDependencies')}) | ||
| | ||
| dataModel group: 'com.linkedin.pegasus-parent-demo', name: 'parent', version: '1.0.0', configuration: 'dataTemplate' | ||
|} | ||
| | ||
|//legacy publishing configuration | ||
|tasks.withType(Upload) { | ||
| repositories { | ||
| ivy { url '$localIvyRepo' } | ||
| } | ||
|}""".stripMargin() | ||
|
||
// Create a simple pdl schema which references parent and grandparent types | ||
schemaFilename = 'Photo.pdl' | ||
def childPegasusDir = childProject.newFolder('src', 'main', 'pegasus', 'com', 'linkedin', 'child') | ||
def childPdlFile = new File("$childPegasusDir.path$File.separator$schemaFilename") | ||
childPdlFile << '''namespace com.linkedin.child | ||
| | ||
|import com.linkedin.grandparent.LatLong | ||
|import com.linkedin.parent.EXIF | ||
| | ||
|record Photo { | ||
| id: long | ||
| urn: string | ||
| title: string | ||
| exif: EXIF | ||
| backupLocation: optional LatLong | ||
|}'''.stripMargin() | ||
|
||
def childRunner = GradleRunner.create() | ||
.withProjectDir(childProject.root) | ||
.withPluginClasspath() | ||
.withArguments('uploadDataTemplate', 'uploadTestDataTemplate', 'uploadAvroSchema', 'uploadTestAvroSchema', 'uploadArchives', '-is') | ||
//.forwardOutput() | ||
//.withDebug(true) | ||
|
||
def childResult = childRunner.build() | ||
|
||
then: | ||
childResult.task(':compileMainGeneratedDataTemplateJava').outcome == TaskOutcome.SUCCESS | ||
childResult.task(':uploadDataTemplate').outcome == TaskOutcome.SUCCESS | ||
childResult.task(':uploadArchives').outcome == TaskOutcome.SUCCESS | ||
|
||
def childProjectIvyDescriptor = new File(localIvyRepo.path, 'com.linkedin.pegasus-child-demo/child/1.0.0/ivy-1.0.0.xml') | ||
childProjectIvyDescriptor.exists() | ||
def childProjectIvyDescriptorContents = childProjectIvyDescriptor.text | ||
def expectedChildContents = new File(Thread.currentThread().contextClassLoader.getResource('ivy/legacy/expectedChildIvyDescriptorContents.txt').toURI()).text | ||
childProjectIvyDescriptorContents.contains expectedChildContents | ||
|
||
def childProjectPrimaryArtifact = new File(localIvyRepo.path, 'com.linkedin.pegasus-child-demo/child/1.0.0/child-1.0.0.jar') | ||
childProjectPrimaryArtifact.exists() | ||
def childProjectDataTemplateArtifact = new File(localIvyRepo.path, 'com.linkedin.pegasus-child-demo/child/1.0.0/child-data-template-1.0.0.jar') | ||
childProjectDataTemplateArtifact.exists() | ||
|
||
assertZipContains(childProjectDataTemplateArtifact, 'com/linkedin/child/Photo.class') | ||
assertZipContains(childProjectDataTemplateArtifact, 'pegasus/com/linkedin/child/Photo.pdl') | ||
} | ||
|
||
private static boolean assertZipContains(File zip, String path) { | ||
return new ZipFile(zip).getEntry(path) | ||
} | ||
|
||
} |
73 changes: 73 additions & 0 deletions
73
gradle-plugins/src/integTest/resources/ivy/legacy/expectedChildIvyDescriptorContents.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<configurations> | ||
<conf name="annotationProcessor" visibility="private"/> | ||
<conf name="apiElements" visibility="private" extends="runtime"/> | ||
<conf name="archives" visibility="public"/> | ||
<conf name="avroSchema" visibility="public"/> | ||
<conf name="avroSchemaGenerator" visibility="private"/> | ||
<conf name="compile" visibility="private" extends="dataModel,dataTemplateCompile"/> | ||
<conf name="compileClasspath" visibility="private" extends="compileOnly,implementation"/> | ||
<conf name="compileOnly" visibility="private"/> | ||
<conf name="dataModel" visibility="public"/> | ||
<conf name="dataTemplate" visibility="public" extends="dataModel,dataTemplateCompile"/> | ||
<conf name="dataTemplateCompile" visibility="private"/> | ||
<conf name="dataTemplateGenerator" visibility="private"/> | ||
<conf name="default" visibility="public" extends="runtimeElements"/> | ||
<conf name="generatedJavadoc" visibility="public"/> | ||
<conf name="generatedSources" visibility="public"/> | ||
<conf name="implementation" visibility="private" extends="compile"/> | ||
<conf name="mainGeneratedDataTemplateAnnotationProcessor" visibility="private"/> | ||
<conf name="mainGeneratedDataTemplateCompile" visibility="private"/> | ||
<conf name="mainGeneratedDataTemplateCompileClasspath" visibility="private" extends="mainGeneratedDataTemplateCompileOnly,mainGeneratedDataTemplateImplementation"/> | ||
<conf name="mainGeneratedDataTemplateCompileOnly" visibility="private"/> | ||
<conf name="mainGeneratedDataTemplateImplementation" visibility="private" extends="mainGeneratedDataTemplateCompile"/> | ||
<conf name="mainGeneratedDataTemplateRuntime" visibility="private" extends="mainGeneratedDataTemplateCompile"/> | ||
<conf name="mainGeneratedDataTemplateRuntimeClasspath" visibility="private" extends="mainGeneratedDataTemplateImplementation,mainGeneratedDataTemplateRuntime,mainGeneratedDataTemplateRuntimeOnly"/> | ||
<conf name="mainGeneratedDataTemplateRuntimeOnly" visibility="private"/> | ||
<conf name="pegasusPlugin" visibility="public"/> | ||
<conf name="restClient" visibility="public" extends="dataTemplate,restClientCompile"/> | ||
<conf name="restClientCompile" visibility="private"/> | ||
<conf name="restModel" visibility="public"/> | ||
<conf name="restTools" visibility="private"/> | ||
<conf name="runtime" visibility="private" extends="compile"/> | ||
<conf name="runtimeClasspath" visibility="private" extends="implementation,runtime,runtimeOnly"/> | ||
<conf name="runtimeElements" visibility="private" extends="implementation,runtime,runtimeOnly"/> | ||
<conf name="runtimeOnly" visibility="private"/> | ||
<conf name="schemaAnnotationHandler" visibility="public"/> | ||
<conf name="testAnnotationProcessor" visibility="private"/> | ||
<conf name="testAvroSchema" visibility="public" extends="avroSchema"/> | ||
<conf name="testCompile" visibility="private" extends="compile,dataTemplateCompile,testDataModel"/> | ||
<conf name="testCompileClasspath" visibility="private" extends="testCompileOnly,testImplementation"/> | ||
<conf name="testCompileOnly" visibility="private"/> | ||
<conf name="testDataModel" visibility="public" extends="dataModel"/> | ||
<conf name="testDataTemplate" visibility="public" extends="dataTemplate,testDataModel"/> | ||
<conf name="testGeneratedDataTemplateAnnotationProcessor" visibility="private"/> | ||
<conf name="testGeneratedDataTemplateCompile" visibility="private"/> | ||
<conf name="testGeneratedDataTemplateCompileClasspath" visibility="private" extends="testGeneratedDataTemplateCompileOnly,testGeneratedDataTemplateImplementation"/> | ||
<conf name="testGeneratedDataTemplateCompileOnly" visibility="private"/> | ||
<conf name="testGeneratedDataTemplateImplementation" visibility="private" extends="testGeneratedDataTemplateCompile"/> | ||
<conf name="testGeneratedDataTemplateRuntime" visibility="private" extends="testGeneratedDataTemplateCompile"/> | ||
<conf name="testGeneratedDataTemplateRuntimeClasspath" visibility="private" extends="testGeneratedDataTemplateImplementation,testGeneratedDataTemplateRuntime,testGeneratedDataTemplateRuntimeOnly"/> | ||
<conf name="testGeneratedDataTemplateRuntimeOnly" visibility="private"/> | ||
<conf name="testGeneratedJavadoc" visibility="public" extends="generatedJavadoc"/> | ||
<conf name="testGeneratedSources" visibility="public" extends="generatedSources"/> | ||
<conf name="testImplementation" visibility="private" extends="implementation,testCompile"/> | ||
<conf name="testRestClient" visibility="public" extends="restClient,testDataTemplate"/> | ||
<conf name="testRestModel" visibility="public" extends="restModel"/> | ||
<conf name="testRuntime" visibility="private" extends="runtime,testCompile"/> | ||
<conf name="testRuntimeClasspath" visibility="private" extends="testImplementation,testRuntime,testRuntimeOnly"/> | ||
<conf name="testRuntimeOnly" visibility="private" extends="runtimeOnly"/> | ||
</configurations> | ||
<publications> | ||
<artifact name="child" type="jar" ext="jar" conf="apiElements,archives,runtime,runtimeElements"/> | ||
<artifact name="child-avro-schema" type="jar" ext="jar" conf="avroSchema"/> | ||
<artifact name="child-data-template" type="jar" ext="jar" conf="dataTemplate"/> | ||
<artifact name="child" type="jar" ext="jar" conf="generatedJavadoc" m:classifier="javadoc"/> | ||
<artifact name="child" type="jar" ext="jar" conf="generatedSources" m:classifier="sources"/> | ||
<artifact name="child-test-avro-schema" type="jar" ext="jar" conf="testAvroSchema"/> | ||
<artifact name="child-test-data-template" type="jar" ext="jar" conf="testDataTemplate"/> | ||
</publications> | ||
<dependencies> | ||
<dependency org="com.linkedin.pegasus-parent-demo" name="parent" rev="1.0.0" conf="dataModel->dataTemplate"/> | ||
<dependency org="com.google.code.findbugs" name="jsr305" rev="3.0.2" conf="dataTemplateCompile->default"/> | ||
<dependency org="org.slf4j" name="slf4j-simple" rev="1.7.2" conf="pegasusPlugin->default"/> | ||
</dependencies> |
Oops, something went wrong.