org.gradle.api.internal.tasks.execution.SkipCachedTaskExecuterTest.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 6.9.1 API redistribution.
/*
* Copyright 2016 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.api.internal.tasks.execution
import com.google.common.collect.ImmutableSortedSet
import org.gradle.api.Project
import org.gradle.api.internal.TaskInternal
import org.gradle.api.internal.TaskOutputCachingState
import org.gradle.api.internal.changedetection.TaskArtifactState
import org.gradle.api.internal.tasks.OriginTaskExecutionMetadata
import org.gradle.api.internal.tasks.TaskExecuter
import org.gradle.api.internal.tasks.TaskExecutionContext
import org.gradle.api.internal.tasks.TaskExecutionOutcome
import org.gradle.api.internal.tasks.TaskStateInternal
import org.gradle.caching.internal.controller.BuildCacheController
import org.gradle.caching.internal.controller.BuildCacheLoadCommand
import org.gradle.caching.internal.controller.BuildCacheStoreCommand
import org.gradle.caching.internal.tasks.TaskOutputCacheCommandFactory
import org.gradle.caching.internal.tasks.TaskOutputCachingBuildCacheKey
import org.gradle.caching.internal.tasks.UnrecoverableTaskOutputUnpackingException
import org.gradle.internal.id.UniqueId
import spock.lang.Specification
class SkipCachedTaskExecuterTest extends Specification {
def delegate = Mock(TaskExecuter)
def project = Mock(Project)
def projectDir = Mock(File)
def taskOutputCaching = Mock(TaskOutputCachingState)
def taskProperties = Mock(TaskProperties)
def task = Stub(TaskInternal)
def taskState = Mock(TaskStateInternal)
def taskContext = Mock(TaskExecutionContext)
def taskArtifactState = Mock(TaskArtifactState)
def buildCacheController = Mock(BuildCacheController)
def cacheKey = Mock(TaskOutputCachingBuildCacheKey)
def taskOutputGenerationListener = Mock(TaskOutputChangesListener)
def loadCommand = Mock(BuildCacheLoadCommand)
def storeCommand = Mock(BuildCacheStoreCommand)
def buildCacheCommandFactory = Mock(TaskOutputCacheCommandFactory)
def outputFingerprints = [:]
def executer = new SkipCachedTaskExecuter(buildCacheController, taskOutputGenerationListener, buildCacheCommandFactory, delegate)
def "skip task when cached results exist"() {
def originId = UniqueId.generate()
def originalExecutionTime = 1234L
def metadata = new OriginTaskExecutionMetadata(originId, originalExecutionTime)
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.getTaskProperties() >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.isAllowedToUseCachedResults() >> true
1 * cacheKey.isValid() >> true
then:
1 * buildCacheCommandFactory.createLoad(cacheKey, _, task, taskProperties, taskOutputGenerationListener, _) >> loadCommand
then:
1 * buildCacheController.load(loadCommand) >> metadata
then:
1 * taskState.setOutcome(TaskExecutionOutcome.FROM_CACHE)
1 * taskContext.setOriginExecutionMetadata(metadata)
0 * _
}
def "executes task and stores result when no cached result is available"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.isAllowedToUseCachedResults() >> true
1 * cacheKey.isValid() >> true
then:
1 * buildCacheCommandFactory.createLoad(cacheKey, _, task, taskProperties, taskOutputGenerationListener, _) >> loadCommand
then:
1 * buildCacheController.load(loadCommand) >> null
then:
1 * delegate.execute(task, taskState, taskContext)
1 * taskState.getFailure() >> null
1 * cacheKey.isValid() >> true
then:
1 * taskContext.getExecutionTime() >> 1
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.getOutputFingerprints() >> outputFingerprints
1 * buildCacheCommandFactory.createStore(cacheKey, _, outputFingerprints, task, 1) >> storeCommand
then:
1 * buildCacheController.store(storeCommand)
0 * _
}
def "executes task and stores result when use of cached result is not allowed"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.isAllowedToUseCachedResults() >> false
1 * cacheKey.isValid() >> true
then:
1 * delegate.execute(task, taskState, taskContext)
then:
1 * taskState.getFailure() >> null
1 * cacheKey.isValid() >> true
then:
1 * taskContext.getExecutionTime() >> 1
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.getOutputFingerprints() >> outputFingerprints
1 * buildCacheCommandFactory.createStore(cacheKey, _, outputFingerprints, task, 1) >> storeCommand
then:
1 * buildCacheController.store(storeCommand)
0 * _
}
def "does not cache results when executed task fails"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.isAllowedToUseCachedResults() >> true
1 * cacheKey.isValid() >> true
then:
1 * buildCacheCommandFactory.createLoad(*_)
1 * buildCacheController.load(_)
then:
1 * delegate.execute(task, taskState, taskContext)
then:
1 * cacheKey.isValid() >> true
1 * taskState.getFailure() >> new RuntimeException()
0 * _
}
def "does not cache results when cache key is invalid"() {
when:
executer.execute(task, taskState, taskContext)
then:
interaction { cachingEnabled() }
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
then:
1 * cacheKey.isValid() >> false
then:
1 * delegate.execute(task, taskState, taskContext)
1 * cacheKey.isValid() >> false
0 * _
}
def "executes task and does not cache results when cacheIf is false"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingDisabled() }
then:
1 * delegate.execute(task, taskState, taskContext)
0 * _
}
def "stores result when cache backend throws recoverable exception while loading result"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * cacheKey.isValid() >> true
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.isAllowedToUseCachedResults() >> true
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
then:
1 * buildCacheCommandFactory.createLoad(*_)
1 * buildCacheController.load(_) >> { throw new RuntimeException("unknown error") }
then:
1 * delegate.execute(task, taskState, taskContext)
then:
1 * taskState.getFailure() >> null
1 * cacheKey.isValid() >> true
then:
1 * taskContext.getExecutionTime() >> 1
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.getOutputFingerprints() >> outputFingerprints
1 * buildCacheCommandFactory.createStore(cacheKey, _, outputFingerprints, task, 1) >> storeCommand
then:
1 * buildCacheController.store(storeCommand)
0 * _
}
def "fails when cache backend throws unrecoverable exception while finding result"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * cacheKey.isValid() >> true
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.isAllowedToUseCachedResults() >> true
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
then:
1 * buildCacheCommandFactory.createLoad(*_)
1 * buildCacheController.load(_) >> { throw new UnrecoverableTaskOutputUnpackingException("unknown error") }
then:
0 * _
then:
def e = thrown UnrecoverableTaskOutputUnpackingException
e.message == "unknown error"
}
def "does not fail when cache backend throws exception while storing cached result"() {
when:
executer.execute(task, taskState, taskContext)
then:
1 * taskContext.taskProperties >> taskProperties
1 * taskContext.buildCacheKey >> cacheKey
interaction { cachingEnabled() }
then:
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskProperties.getOutputFileProperties() >> ImmutableSortedSet.of()
1 * cacheKey.isValid() >> true
1 * taskArtifactState.isAllowedToUseCachedResults() >> true
then:
1 * buildCacheCommandFactory.createLoad(*_)
1 * buildCacheController.load(_)
then:
1 * delegate.execute(task, taskState, taskContext)
then:
1 * cacheKey.isValid() >> true
1 * taskState.getFailure() >> null
then:
1 * taskContext.getExecutionTime() >> 1
1 * cacheKey.getDisplayName() >> "cache key"
1 * taskContext.getTaskArtifactState() >> taskArtifactState
1 * taskArtifactState.getOutputFingerprints()
1 * buildCacheCommandFactory.createStore(*_)
1 * buildCacheController.store(_) >> { throw new RuntimeException("unknown error") }
then:
0 * _
}
private void cachingEnabled() {
1 * taskState.getTaskOutputCaching() >> taskOutputCaching
1 * taskOutputCaching.isEnabled() >> true
}
private void cachingDisabled() {
1 * taskState.getTaskOutputCaching() >> taskOutputCaching
1 * taskOutputCaching.isEnabled() >> false
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy