org.gradle.internal.fingerprint.classpath.impl.DefaultClasspathFingerprinterTest.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 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.internal.fingerprint.classpath.impl
import org.gradle.api.internal.cache.StringInterner
import org.gradle.api.internal.changedetection.state.DefaultResourceSnapshotterCacheService
import org.gradle.api.internal.changedetection.state.ResourceFilter
import org.gradle.api.internal.file.TestFiles
import org.gradle.api.internal.file.collections.ImmutableFileCollection
import org.gradle.internal.fingerprint.FileSystemLocationFingerprint
import org.gradle.internal.hash.HashCode
import org.gradle.internal.hash.TestFileHasher
import org.gradle.internal.serialize.HashCodeSerializer
import org.gradle.internal.snapshot.WellKnownFileLocations
import org.gradle.internal.snapshot.impl.DefaultFileSystemMirror
import org.gradle.internal.snapshot.impl.DefaultFileSystemSnapshotter
import org.gradle.test.fixtures.file.CleanupTestDirectory
import org.gradle.test.fixtures.file.TestFile
import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider
import org.gradle.testfixtures.internal.InMemoryIndexedCache
import org.gradle.util.UsesNativeServices
import org.junit.Rule
import spock.lang.Specification
@CleanupTestDirectory(fieldName = "tmpDir")
@UsesNativeServices
class DefaultClasspathFingerprinterTest extends Specification {
@Rule
public final TestNameTestDirectoryProvider tmpDir = new TestNameTestDirectoryProvider()
def stringInterner = Stub(StringInterner) {
intern(_) >> { String s -> s }
}
def fileSystem = TestFiles.fileSystem()
def fileSystemMirror = new DefaultFileSystemMirror(Stub(WellKnownFileLocations))
def fileHasher = new TestFileHasher()
def fileSystemSnapshotter = new DefaultFileSystemSnapshotter(fileHasher, stringInterner, fileSystem, fileSystemMirror)
InMemoryIndexedCache resourceHashesCache = new InMemoryIndexedCache<>(new HashCodeSerializer())
def cacheService = new DefaultResourceSnapshotterCacheService(resourceHashesCache)
def fingerprinter = new DefaultClasspathFingerprinter(
cacheService,
fileSystemSnapshotter,
ResourceFilter.FILTER_NOTHING,
stringInterner)
def "directories and missing files are ignored"() {
def emptyDir = file('root/emptyDir').createDir()
def missingFile = file('some').createDir().file('does-not-exist')
def missingRootFile = file('missing-root')
when:
def fileCollectionFingerprint = fingerprint(emptyDir.parentFile, missingFile.parentFile, missingRootFile)
then:
fileCollectionFingerprint.empty
}
def "root elements are unsorted, non-root elements are sorted amongst themselves"() {
def rootFile1 = file("root1.txt") << "root1"
def rootDir = file("dir").createDir()
rootDir.file("file1.txt") << "file1"
rootDir.file("file2.txt") << "file2"
def rootFile2 = file("root2.txt") << "root2"
when:
def fileCollectionFingerprint = fingerprint(rootFile1, rootDir, rootFile2)
then:
fileCollectionFingerprint == [
['root1.txt', '', 'e5d9dee0892c9f474a174d3bfffb7810'],
['file1.txt', 'file1.txt', '826e8142e6baabe8af779f5f490cf5f5'],
['file2.txt', 'file2.txt', '1c1c96fd2cf8330db0bfa936ce82f3b9'],
['root2.txt', '', '9b70d6dbfb1457d05e4e2c2fbb42d7db'],
]
when:
fileCollectionFingerprint = fingerprint(rootFile2, rootFile1, rootDir)
then:
fileCollectionFingerprint == [
['root2.txt', '', '9b70d6dbfb1457d05e4e2c2fbb42d7db'],
['root1.txt', '', 'e5d9dee0892c9f474a174d3bfffb7810'],
['file1.txt', 'file1.txt', '826e8142e6baabe8af779f5f490cf5f5'],
['file2.txt', 'file2.txt', '1c1c96fd2cf8330db0bfa936ce82f3b9'],
]
}
def "fingerprints runtime classpath files"() {
def zipFile = file('library.jar')
file('zipContents').create {
file('firstFile.txt').text = "Some text"
file('secondFile.txt').text = "Second File"
subdir {
file('someOtherFile.log').text = "File in subdir"
}
}.zipTo(zipFile)
def classes = file('classes').create {
file('thirdFile.txt').text = "Third file"
file('fourthFile.txt').text = "Fourth file"
subdir {
file('build.log').text = "File in subdir"
}
}
when:
def fileCollectionFingerprint = fingerprint(zipFile, classes)
then:
fileCollectionFingerprint == [
['library.jar', '', 'f31495fd1bb4b8c3b8fb1f46a68adf9e'],
['fourthFile.txt', 'fourthFile.txt', '6c99cb370b82c9c527320b35524213e6'],
['build.log', 'subdir/build.log', 'a9cca315f4b8650dccfa3d93284998ef'],
['thirdFile.txt', 'thirdFile.txt', '3f1d3e7fb9620156f8e911fb90d89c42'],
]
resourceHashesCache.keySet().size() == 1
def key = resourceHashesCache.keySet().iterator().next()
resourceHashesCache.get(key).toString() == 'f31495fd1bb4b8c3b8fb1f46a68adf9e'
}
def "detects moving of files in jars and directories"() {
def zipFile = file('library.jar')
file('zipContents').create {
file('firstFile.txt').text = "Some text"
subdir {}
}.zipTo(zipFile)
def classes = file('classes').create {
file('thirdFile.txt').text = "Third file"
subdir {}
}
when:
def fileCollectionFingerprint = fingerprint(zipFile, classes)
then:
fileCollectionFingerprint == [
['library.jar', '', '9caa94545d5150c01cf20881f31c4fb2'],
['thirdFile.txt', 'thirdFile.txt', '3f1d3e7fb9620156f8e911fb90d89c42'],
]
when:
file('zipContents/firstFile.txt').moveToDirectory(file('zipContents/subdir'))
file('classes/thirdFile.txt').moveToDirectory(file('classes/subdir'))
file('zipContents').zipTo(zipFile)
fileCollectionFingerprint = fingerprint(zipFile, classes)
then:
fileCollectionFingerprint == [
['library.jar', '', '63d04b00e1c9d80e20d881a820b228a1'],
['thirdFile.txt', 'subdir/thirdFile.txt', '3f1d3e7fb9620156f8e911fb90d89c42'],
]
}
def "cache hashes for jar files"() {
def zipFile = file('library.jar')
file('zipContents').create {
file('firstFile.txt').text = "Some text"
file('secondFile.txt').text = "Second File"
subdir {
file('someOtherFile.log').text = "File in subdir"
}
}.zipTo(zipFile)
def zipFile2 = file('another-library.jar')
file('anotherZipContents').create {
file('thirdFile.txt').text = "third file"
file('forthFile.txt').text = "forth file"
subdir {
file('someEvenOtherFile.log').text = "another file in subdir"
}
}.zipTo(zipFile2)
when:
def fileCollectionFingerprint = fingerprint(zipFile, zipFile2)
then:
fileCollectionFingerprint == [
['library.jar', '', 'f31495fd1bb4b8c3b8fb1f46a68adf9e'],
['another-library.jar', '', '4c54ecab47d005e6862ced54627c6208']
]
resourceHashesCache.keySet().size() == 2
def values = resourceHashesCache.keySet().collect { resourceHashesCache.get(it).toString() } as Set
values == ['f31495fd1bb4b8c3b8fb1f46a68adf9e', '4c54ecab47d005e6862ced54627c6208'] as Set
when:
fileCollectionFingerprint = fingerprint(zipFile, zipFile2)
values = resourceHashesCache.keySet().collect { resourceHashesCache.get(it).toString() } as Set
then:
fileCollectionFingerprint == [
['library.jar', '', 'f31495fd1bb4b8c3b8fb1f46a68adf9e'],
['another-library.jar', '', '4c54ecab47d005e6862ced54627c6208']
]
resourceHashesCache.keySet().size() == 2
values == ['f31495fd1bb4b8c3b8fb1f46a68adf9e', '4c54ecab47d005e6862ced54627c6208'] as Set
}
def fingerprint(TestFile... classpath) {
fileSystemMirror.beforeOutputChange()
def fileCollectionFingerprint = fingerprinter.fingerprint(files(classpath))
return fileCollectionFingerprint.fingerprints.collect { String path, FileSystemLocationFingerprint fingerprint ->
[new File(path).getName(), fingerprint.normalizedPath, fingerprint.normalizedContentHash.toString()]
}
}
def files(File... files) {
return ImmutableFileCollection.of(files)
}
def file(Object... path) {
tmpDir.file(path)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy