【发布时间】:2015-03-26 16:58:43
【问题描述】:
我有一个自定义 Gradle 插件的工作版本。我有几个单元测试,现在我正在尝试使用 nebula-test 进行集成测试。
我在集成测试中遇到了一个令人困惑的测试错误。我在使用 nebula-test 的方式上一定做错了。
我将展示完整的代码,但我将首先描述基本要素。
插件定义了一个扩展块,其中包含一些属性,其中一个是可以找到特定文件的文件路径。对于上下文,该属性名称称为“yangFilesRootDir”。
插件创建一个名为“YangGenerate”的自定义任务的实例。该任务有一个名为“yangFilesRootDir”的 File 类型的实例变量,该实例变量上有一个 @InputDirectory 注释。该任务还有其他实例变量,其中一些带有“@Input...”注释。
任务有一个“init”方法,在项目评估后从插件中调用。这会根据扩展块中的值初始化任务实例变量。在“init”方法中,如果扩展块中没有设置“yangFilesRootDir”属性,我使用默认值“src/main/yang”。
在进行此集成测试之前,我设置了一个引用该插件的独立项目。该项目的“build.gradle”指定了扩展块,并且我已经使用属性设置和不使用属性设置对其进行了测试(我将文件存储在默认位置),它工作正常。
这就是我的规范现在的样子:
class YangPluginIntegSpec extends IntegrationSpec {
def 'simple'() {
createFile("src/main/yang/dummy")
writeHelloWorld("com.example")
buildFile << applyPlugin(YangPlugin)
buildFile << '''
yang {
yangFilesRootDir 'src/main/yang'
}
'''.stripIndent()
when:
ExecutionResult result = runTasksSuccessfully('build')
then:
println result
}
}
我在有和没有“yang”块的情况下都试过了,但这个堆栈跟踪测试失败了:
org.gradle.api.GradleException: Build aborted because of an internal error.
at nebula.test.functional.internal.DefaultExecutionResult.rethrowFailure(DefaultExecutionResult.groovy:95)
at nebula.test.IntegrationSpec.runTasksSuccessfully(IntegrationSpec.groovy:234)
at com.att.opnfv.yang.gradle.YangPluginIntegSpec.simple(YangPluginIntegSpec.groovy:18)
Caused by: org.gradle.internal.exceptions.LocationAwareException: A problem was found with the configuration of task ':yangGenerate'.
at org.gradle.initialization.DefaultExceptionAnalyser.transform(DefaultExceptionAnalyser.java:77)
at org.gradle.initialization.MultipleBuildFailuresExceptionAnalyser.transform(MultipleBuildFailuresExceptionAnalyser.java:47)
at org.gradle.initialization.StackTraceSanitizingExceptionAnalyser.transform(StackTraceSanitizingExceptionAnalyser.java:30)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:108)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:43)
at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:30)
at org.gradle.tooling.internal.provider.ConfiguringBuildAction.run(ConfiguringBuildAction.java:119)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.tooling.internal.provider.DaemonBuildActionExecuter.execute(DaemonBuildActionExecuter.java:42)
at org.gradle.tooling.internal.provider.DaemonBuildActionExecuter.execute(DaemonBuildActionExecuter.java:29)
at org.gradle.tooling.internal.provider.LoggingBridgingBuildActionExecuter.execute(LoggingBridgingBuildActionExecuter.java:62)
at org.gradle.tooling.internal.provider.LoggingBridgingBuildActionExecuter.execute(LoggingBridgingBuildActionExecuter.java:34)
at org.gradle.tooling.internal.provider.ProviderConnection.run(ProviderConnection.java:107)
at org.gradle.tooling.internal.provider.ProviderConnection.run(ProviderConnection.java:94)
at org.gradle.tooling.internal.provider.DefaultConnection.getModel(DefaultConnection.java:149)
at org.gradle.tooling.internal.consumer.connection.CancellableModelBuilderBackedModelProducer.produceModel(CancellableModelBuilderBackedModelProducer.java:58)
at org.gradle.tooling.internal.consumer.connection.AbstractConsumerConnection.run(AbstractConsumerConnection.java:56)
at org.gradle.tooling.internal.consumer.DefaultBuildLauncher$1.run(DefaultBuildLauncher.java:82)
at org.gradle.tooling.internal.consumer.DefaultBuildLauncher$1.run(DefaultBuildLauncher.java:76)
at org.gradle.tooling.internal.consumer.connection.LazyConsumerActionExecutor.run(LazyConsumerActionExecutor.java:83)
at org.gradle.tooling.internal.consumer.connection.ProgressLoggingConsumerActionExecutor.run(ProgressLoggingConsumerActionExecutor.java:58)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor$1$1.run(DefaultAsyncConsumerActionExecutor.java:55)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: org.gradle.api.tasks.TaskValidationException: A problem was found with the configuration of task ':yangGenerate'.
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:306)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
... 22 more
Caused by: org.gradle.api.InvalidUserDataException: Directory 'src\main\yang' specified for property 'yangFilesRootDir' does not exist.
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:47)
... 41 more
我还用“-i”运行了它,以便获得更多信息,它向我显示了用于测试的临时构建目录的路径,并且在测试失败后我验证了“src/main/yang/dummy " 存在于测试项目目录中。
插件类的相关代码如下:
class YangPlugin implements Plugin<Project> {
public void apply(Project project) {
YangExtension yang = project.extensions.create(YANG_EXT, YangExtension, project)
YangGenerateTask task = project.task(YANG_GENERATE_TASK, type: YangGenerateTask)
project.afterEvaluate {
task.init(project, yang)
project.compileJava.dependsOn task
if (task.yangFilesRootDir && task.yangFilesRootDir.exists()) {
Jar jarTask = project.jar
if (task.yangFilesRootDir.getPath().startsWith(FilenameUtils.normalize(SRC_MAIN_RESOURCES))) {
jarTask.exclude(task.yangFilesRootDir.getPath() - FilenameUtils.normalize(SRC_MAIN_RESOURCES))
}
jarTask.from(task.yangFilesRootDir) { into(META_INF_YANG) }
}
}
}
}
以及YangGenerate任务的相关部分:
class YangGenerateTask extends DefaultTask {
private static final String DEFAULT_YANG_FILES_ROOT_DIR = "src/main/yang"
Project project
Collection<CodeGeneratorConfig> generators
boolean inspectDependencies
Collection<String> excludeFiles
String yangFilesConfiguration
String generatorsConfiguration
Pattern yangFilePattern = Pattern.compile("META-INF/yang/.*\\.yang\$")
@InputDirectory
File yangFilesRootDir
@Input
def getGeneratorClasses() {
...
}
@InputFiles
def getOptionalYangClasspath() {
...
}
@OutputDirectories
def getOutputDirectories() {
...
}
@TaskAction
void generate() {
...
}
public void init(Project project, YangExtension yang) {
this.yangFilesRootDir = new File(yang.yangFilesRootDir ?: DEFAULT_YANG_FILES_ROOT_DIR)
...
}
}
更新:
终于想到在调试器中运行这个测试,发现找不到路径的原因是“当前目录”不是测试项目的基目录,而是主目录的基目录插件项目,肯定没有“src/main/yang”目录。
【问题讨论】:
标签: groovy gradle nebula-test