PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/fixture/ToolingApiCompatibilitySuiteRunner.groovy

http://github.com/gradle/gradle
Groovy | 171 lines | 121 code | 21 blank | 29 comment | 18 complexity | 1db682ad670376da00acc556db52abfa MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. /*
  2. * Copyright 2011 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.gradle.integtests.tooling.fixture
  17. import org.gradle.integtests.fixtures.AbstractCompatibilityTestRunner
  18. import org.gradle.integtests.fixtures.AbstractMultiTestRunner
  19. import org.gradle.integtests.fixtures.BasicGradleDistribution
  20. import org.gradle.internal.os.OperatingSystem
  21. import org.gradle.util.*
  22. /**
  23. * Executes instances of {@link ToolingApiSpecification} against all compatible versions of tooling API consumer
  24. * and provider, including the current Gradle version under test.
  25. *
  26. * <p>A test can be annotated with {@link MinToolingApiVersion} and {@link MinTargetGradleVersion} to indicate the
  27. * minimum tooling API or Gradle versions required for the test.
  28. */
  29. class ToolingApiCompatibilitySuiteRunner extends AbstractCompatibilityTestRunner {
  30. private static final Map<String, ClassLoader> TEST_CLASS_LOADERS = [:]
  31. ToolingApiCompatibilitySuiteRunner(Class<? extends ToolingApiSpecification> target) {
  32. super(target, includesAllPermutations(target))
  33. }
  34. static String includesAllPermutations(Class target) {
  35. if (target.getAnnotation(IncludeAllPermutations)) {
  36. return "all";
  37. } else {
  38. return null; //just use whatever is the default
  39. }
  40. }
  41. @Override
  42. protected void createExecutions() {
  43. ToolingApiDistributionResolver resolver = new ToolingApiDistributionResolver().withDefaultRepository()
  44. add(new Permutation(resolver.resolve(current.version), current))
  45. previous.each {
  46. if (it.toolingApiSupported) {
  47. add(new Permutation(resolver.resolve(current.version), it))
  48. add(new Permutation(resolver.resolve(it.version), current))
  49. }
  50. }
  51. }
  52. private class Permutation extends AbstractMultiTestRunner.Execution {
  53. final ToolingApiDistribution toolingApi
  54. final BasicGradleDistribution gradle
  55. Permutation(ToolingApiDistribution toolingApi, BasicGradleDistribution gradle) {
  56. this.toolingApi = toolingApi
  57. this.gradle = gradle
  58. }
  59. @Override
  60. protected String getDisplayName() {
  61. return "${displayName(toolingApi)} -> ${displayName(gradle)}"
  62. }
  63. private String displayName(dist) {
  64. if (dist.version == GradleVersion.current().version) {
  65. return "current"
  66. }
  67. return dist.version
  68. }
  69. @Override
  70. protected boolean isEnabled() {
  71. if (!gradle.daemonSupported) {
  72. return false
  73. }
  74. if (!gradle.daemonIdleTimeoutConfigurable && OperatingSystem.current().isWindows()) {
  75. //Older daemon don't have configurable ttl and they hung for 3 hours afterwards.
  76. // This is a real problem on windows due to eager file locking and continuous CI failures.
  77. // On linux it's a lesser problem - long-lived daemons hung and steal resources but don't lock files.
  78. // So, for windows we'll only run tests against target gradle that supports ttl
  79. return false
  80. }
  81. MinToolingApiVersion minToolingApiVersion = target.getAnnotation(MinToolingApiVersion)
  82. if (minToolingApiVersion && GradleVersion.version(toolingApi.version) < extractVersion(minToolingApiVersion)) {
  83. return false
  84. }
  85. MinTargetGradleVersion minTargetGradleVersion = target.getAnnotation(MinTargetGradleVersion)
  86. if (minTargetGradleVersion && GradleVersion.version(gradle.version) < extractVersion(minTargetGradleVersion)) {
  87. return false
  88. }
  89. MaxTargetGradleVersion maxTargetGradleVersion = target.getAnnotation(MaxTargetGradleVersion)
  90. if (maxTargetGradleVersion && GradleVersion.version(gradle.version) > extractVersion(maxTargetGradleVersion)) {
  91. return false
  92. }
  93. return true
  94. }
  95. private GradleVersion extractVersion(annotation) {
  96. if (GradleVersion.current().isSnapshot() && GradleVersion.current().version.startsWith(annotation.value())) {
  97. //so that one can use an unreleased version in the annotation value
  98. return GradleVersion.current()
  99. }
  100. if ("current".equals(annotation.value())) {
  101. //so that one can use 'current' literal in the annotation value
  102. //(useful if you don't know if the feature makes its way to the upcoming release)
  103. return GradleVersion.current()
  104. }
  105. return GradleVersion.version(annotation.value())
  106. }
  107. @Override
  108. protected List<? extends Class<?>> loadTargetClasses() {
  109. def testClassLoader = getTestClassLoader()
  110. return [testClassLoader.loadClass(target.name)]
  111. }
  112. private ClassLoader getTestClassLoader() {
  113. synchronized(ToolingApiCompatibilitySuiteRunner) {
  114. def classLoader = TEST_CLASS_LOADERS.get(toolingApi.version)
  115. if (!classLoader) {
  116. classLoader = createTestClassLoader()
  117. TEST_CLASS_LOADERS.put(toolingApi.version, classLoader)
  118. }
  119. return classLoader
  120. }
  121. }
  122. private ClassLoader createTestClassLoader() {
  123. def classLoaderFactory = new DefaultClassLoaderFactory()
  124. def sharedClassLoader = classLoaderFactory.createFilteringClassLoader(getClass().classLoader)
  125. sharedClassLoader.allowPackage('org.junit')
  126. sharedClassLoader.allowPackage('org.hamcrest')
  127. sharedClassLoader.allowPackage('junit.framework')
  128. sharedClassLoader.allowPackage('groovy')
  129. sharedClassLoader.allowPackage('org.codehaus.groovy')
  130. sharedClassLoader.allowPackage('spock')
  131. sharedClassLoader.allowPackage('org.spockframework')
  132. sharedClassLoader.allowClass(TestFile)
  133. sharedClassLoader.allowClass(SetSystemProperties)
  134. sharedClassLoader.allowPackage('org.gradle.integtests.fixtures')
  135. sharedClassLoader.allowPackage('org.gradle.test.fixtures')
  136. sharedClassLoader.allowClass(OperatingSystem)
  137. sharedClassLoader.allowClass(Requires)
  138. sharedClassLoader.allowClass(TestPrecondition)
  139. sharedClassLoader.allowResources(target.name.replace('.', '/'))
  140. def parentClassLoader = new MultiParentClassLoader(toolingApi.classLoader, sharedClassLoader)
  141. def testClassPath = []
  142. testClassPath << ClasspathUtil.getClasspathForClass(target)
  143. return new MutableURLClassLoader(parentClassLoader, testClassPath.collect { it.toURI().toURL() })
  144. }
  145. @Override
  146. protected void before() {
  147. testClassLoader.loadClass(ToolingApiSpecification.name).selectTargetDist(gradle)
  148. }
  149. }
  150. }