
org.gradle.integtests.tooling.r40.ProjectConfigurationChildrenProgressCrossVersionSpec.groovy Maven / Gradle / Ivy
/*
* Copyright 2018 the original author or authors.
*
* Licensed 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.gradle.integtests.tooling.r40
import org.gradle.integtests.fixtures.timeout.IntegrationTestTimeout
import org.gradle.integtests.tooling.fixture.ProgressEvents
import org.gradle.integtests.tooling.fixture.TargetGradleVersion
import org.gradle.integtests.tooling.fixture.TextUtil
import org.gradle.integtests.tooling.fixture.ToolingApiSpecification
import org.gradle.test.fixtures.maven.MavenFileRepository
import org.gradle.test.fixtures.server.http.MavenHttpRepository
import org.gradle.test.fixtures.server.http.RepositoryHttpServer
import org.gradle.tooling.ProjectConnection
import org.gradle.util.Requires
import org.junit.Rule
import static org.gradle.util.TestPrecondition.KOTLIN_SCRIPT
@IntegrationTestTimeout(300)
@TargetGradleVersion('>=4.0 <5.1')
class ProjectConfigurationChildrenProgressCrossVersionSpec extends ToolingApiSpecification {
@Rule
public final RepositoryHttpServer server = new RepositoryHttpServer(temporaryFolder, targetDist.version.version)
def "generates events for worker actions executed in-process and forked"() {
given:
settingsFile << "rootProject.name = 'single'"
buildFile << """
import org.gradle.workers.*
import java.net.URLClassLoader
import java.net.URL
import org.gradle.internal.classloader.ClasspathUtil
class TestRunnable implements Runnable {
@Override public void run() {
// Do nothing
}
}
// Set up a simpler classloader that only contains what TestRunnable needs.
// This can be removed when the issues with long classpaths have been resolved.
// See https://github.com/gradle/gradle-private/issues/1486
ClassLoader cl = new URLClassLoader(
ClasspathUtil.getClasspath(TestRunnable.class.classLoader).asURLs.findAll { url ->
["scripts-remapped", "groovy-all"].any { url.toString().contains(it) }
} as URL[]
)
def testRunnable = cl.loadClass("TestRunnable")
task runInProcess {
doLast {
def workerExecutor = services.get(WorkerExecutor)
workerExecutor.submit(testRunnable) { config ->
config.isolationMode = IsolationMode.NONE
config.displayName = 'My in-process worker action'
}
}
}
task runForked {
doLast {
def workerExecutor = services.get(WorkerExecutor)
workerExecutor.submit(testRunnable) { config ->
config.isolationMode = IsolationMode.PROCESS
config.displayName = 'My forked worker action'
}
}
}
""".stripIndent()
when:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.setStandardOutput(System.out)
.forTasks('runInProcess', 'runForked')
.addProgressListener(events)
.run()
}
then:
events.assertIsABuild()
and:
events.operation('Task :runInProcess').descendant('My in-process worker action')
events.operation('Task :runForked').descendant('My forked worker action')
}
def "does not generate events for non-existing build scripts"() {
when:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.addProgressListener(events)
.run()
}
then:
events.assertIsABuild()
and:
events.operation('Configure project :').children.size() <= 5 //only 'Apply plugin org.gradle.help-tasks', maybe before/afterEvaluated and 2 delayed task registrations
}
def "generates events for applied build scripts"() {
given:
settingsFile << '''
rootProject.name = 'multi'
include 'a', 'b'
'''.stripIndent()
def buildSrcFile = file('buildSrc/build.gradle')
def aBuildFile = file('a/build.gradle')
def bBuildFile = file('b/build.gradle')
[buildSrcFile, buildFile, aBuildFile, bBuildFile].each { it << '' }
when:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.addProgressListener(events)
.run()
}
then:
events.assertIsABuild()
and:
events.operation('Configure project :buildSrc').child "Apply script build.gradle to project ':buildSrc'"
events.operation('Configure project :').child "Apply script build.gradle to root project 'multi'"
events.operation('Configure project :a').child "Apply script build.gradle to project ':a'"
events.operation('Configure project :b').child "Apply script build.gradle to project ':b'"
}
def "generates events for applied script plugins"() {
given:
def scriptPlugin1 = file('scriptPlugin1.gradle')
def scriptPlugin2 = file('scriptPlugin2.gradle')
[scriptPlugin1, scriptPlugin2].each { it << '' }
and:
def initScript = file('init.gradle')
def buildSrcScript = file('buildSrc/build.gradle')
settingsFile << '''
rootProject.name = 'multi'
include 'a', 'b'
'''.stripIndent()
def aBuildFile = file('a/build.gradle')
def bBuildFile = file('b/build.gradle')
[initScript, buildSrcScript, settingsFile, buildFile, aBuildFile, bBuildFile].each {
it << """
apply from: '${TextUtil.normaliseFileSeparators(scriptPlugin1.absolutePath)}'
apply from: '${TextUtil.normaliseFileSeparators(scriptPlugin2.absolutePath)}'
""".stripIndent()
}
when:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.withArguments('--init-script', initScript.toString())
.addProgressListener(events)
.run()
}
then:
events.assertIsABuild()
and:
println events.describeOperationsTree()
events.operation("Apply script ${initScript.name} to build").with { applyInitScript ->
applyInitScript.child "Apply script ${scriptPlugin1.name} to build"
applyInitScript.child "Apply script ${scriptPlugin2.name} to build"
}
events.operation("Apply script ${buildSrcScript.name} to project ':buildSrc'").with { applyBuildSrc ->
applyBuildSrc.child "Apply script ${scriptPlugin1.name} to project ':buildSrc'"
applyBuildSrc.child "Apply script ${scriptPlugin2.name} to project ':buildSrc'"
}
events.operation("Apply script ${settingsFile.name} to settings '${settingsFile.parentFile.name}'").with { applySettings ->
applySettings.child "Apply script ${scriptPlugin1.name} to settings 'multi'"
applySettings.child "Apply script ${scriptPlugin2.name} to settings 'multi'"
}
events.operation("Apply script ${buildFile.name} to root project 'multi'").with { applyRootProject ->
applyRootProject.child "Apply script ${scriptPlugin1.name} to root project 'multi'"
applyRootProject.child "Apply script ${scriptPlugin2.name} to root project 'multi'"
}
events.operation("Apply script ${aBuildFile.name} to project ':a'").with { applyProjectA ->
applyProjectA.child "Apply script ${scriptPlugin1.name} to project ':a'"
applyProjectA.child "Apply script ${scriptPlugin2.name} to project ':a'"
}
events.operation("Apply script ${bBuildFile.name} to project ':b'").with { applyProjectB ->
applyProjectB.child "Apply script ${scriptPlugin1.name} to project ':b'"
applyProjectB.child "Apply script ${scriptPlugin2.name} to project ':b'"
}
}
def "generates events for downloading artifacts"() {
given:
toolingApi.requireIsolatedUserHome()
def projectB = mavenHttpRepo.module('group', 'projectB', '1.0').publish()
def projectC = mavenHttpRepo.module('group', 'projectC', '1.5').publish()
def projectD = mavenHttpRepo.module('group', 'projectD', '2.0-SNAPSHOT').publish()
settingsFile << """
rootProject.name = 'root'
include 'a'
""".stripIndent()
buildFile << """
allprojects {
apply plugin:'java'
}
repositories {
maven { url '${mavenHttpRepo.uri}' }
}
dependencies {
compile project(':a')
compile "group:projectB:1.0"
compile "group:projectC:1.+"
compile "group:projectD:2.0-SNAPSHOT"
}
configurations.compile.each { println it }
""".stripIndent()
when:
projectB.pom.expectGet()
projectB.artifact.expectGet()
projectC.rootMetaData.expectGet()
projectC.pom.expectGet()
projectC.artifact.expectGet()
projectD.pom.expectGet()
projectD.metaData.expectGet()
projectD.artifact.expectGet()
and:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.addProgressListener(events).run()
}
then:
events.assertIsABuild()
def applyBuildScript = events.operation "Apply script build.gradle to root project 'root'"
applyBuildScript.child("Resolve dependencies of :compile").with {
it.child "Configure project :a"
it.descendant "Download http://localhost:${server.port}${projectB.pomPath}"
it.descendant "Download http://localhost:${server.port}/repo/group/projectC/maven-metadata.xml"
it.descendant "Download http://localhost:${server.port}${projectC.pomPath}"
it.descendant "Download http://localhost:${server.port}${projectD.metaDataPath}"
it.descendant "Download http://localhost:${server.port}${projectD.pomPath}"
}
def resolveArtifacts = applyBuildScript.child("Resolve files of :compile")
resolveArtifacts.child("Resolve projectB.jar (group:projectB:1.0)")
.child "Download http://localhost:${server.port}${projectB.artifactPath}"
resolveArtifacts.child("Resolve projectC.jar (group:projectC:1.5)")
.child "Download http://localhost:${server.port}${projectC.artifactPath}"
resolveArtifacts.child("Resolve projectD.jar (group:projectD:2.0-SNAPSHOT)", "Resolve projectD.jar (group:projectD:2.0-SNAPSHOT:${projectD.uniqueSnapshotVersion})")
.child "Download http://localhost:${server.port}${projectD.artifactPath}"
}
def "generates events for interleaved project configuration and dependency resolution"() {
given:
settingsFile << """
rootProject.name = 'multi'
include 'a', 'b'
"""
buildFile << """
allprojects { apply plugin: 'java' }
dependencies {
compile project(':a')
}
// Triggers configuration of a due to the dependency
configurations.compile.each { println it }
"""
file("a/build.gradle") << """
dependencies {
compile project(':b')
}
// Triggers configuration of a due to the dependency
configurations.compile.each { println it }
"""
when:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.addProgressListener(events)
.run()
}
then:
events.assertIsABuild()
def configureRoot = events.operation("Configure project :")
def applyRootBuildScript = configureRoot.child("Apply script build.gradle to root project 'multi'")
def resolveCompile = applyRootBuildScript.child("Resolve dependencies of :compile")
applyRootBuildScript.child("Resolve files of :compile")
def applyProjectABuildScript = resolveCompile.child("Configure project :a").child("Apply script build.gradle to project ':a'")
def resolveCompileA = applyProjectABuildScript.child("Resolve dependencies of :a:compile")
applyProjectABuildScript.child("Resolve files of :a:compile")
resolveCompileA.child("Configure project :b")
}
@Requires([KOTLIN_SCRIPT])
def "generates events for nested script plugin applications of different types"() {
given:
def scriptPluginGroovy1 = file('scriptPluginGroovy1.gradle')
def scriptPluginKotlin = file('scriptPluginKotlin.gradle.kts')
def scriptPluginGroovy2 = file('scriptPluginGroovy2.build') //defaults to Groovy script plugin factory
settingsFile << "rootProject.name = 'root'"
buildFile << "apply from: '${scriptPluginGroovy1.name}'"
scriptPluginGroovy1 << "apply from: '${scriptPluginKotlin.name}'"
scriptPluginKotlin << "apply { from(\"$scriptPluginGroovy2.name\") }"
scriptPluginGroovy2 << ""
when:
def events = ProgressEvents.create()
withConnection {
ProjectConnection connection ->
connection.newBuild()
.addProgressListener(events)
.run()
}
then:
events.assertIsABuild()
events.operation("Apply script ${buildFile.name} to root project 'root'").with { applyRoot ->
applyRoot.child("Apply script ${scriptPluginGroovy1.name} to root project 'root'").with { applyGroovy1 ->
applyGroovy1.child("Apply script ${scriptPluginKotlin.name} to root project 'root'").with { applyKotlin ->
applyKotlin.child("Apply script ${scriptPluginGroovy2.name} to root project 'root'")
}
}
}
}
MavenHttpRepository getMavenHttpRepo() {
return new MavenHttpRepository(server, "/repo", mavenRepo)
}
MavenFileRepository getMavenRepo(String name = "repo") {
return new MavenFileRepository(file(name))
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy