[2.x] Fix scripted cache tests

This commit is contained in:
Adrien Piquerez 2024-09-17 15:57:53 +02:00
parent 733b526ac5
commit f08f272d23
10 changed files with 48 additions and 47 deletions

View File

@ -139,7 +139,7 @@ jobs:
if: ${{ matrix.jobtype == 2 }}
shell: bash
run: |
./sbt -v "scripted actions/* apiinfo/* compiler-project/* ivy-deps-management/* reporter/* tests/* classloader-cache/* package/*"
./sbt -v "scripted actions/* apiinfo/* cache/* compiler-project/* ivy-deps-management/* reporter/* tests/* classloader-cache/* package/*"
# ./sbt -v "scripted watch/*"
- name: Build and test (3)
if: ${{ matrix.jobtype == 3 }}

View File

@ -294,7 +294,7 @@ trait Cont:
).asTerm.changeOwner(sym)
else
val tags = CacheLevelTag.all.toList
callActionCache(outputBuf.toList, cacheConfigExpr, tags)(
callActionCache(outputBuf.toList, modifiedCacheConfigExpr, tags)(
body = modifiedBody,
input = unitExpr,
).asTerm.changeOwner(sym)

View File

@ -254,18 +254,23 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
@cacheLevel(include = Array.empty)
val cacheConfiguration: Initialize[Task[BuildWideCacheConfiguration]] = Def.task {
val state = stateKey.value
val outputDirectory = state.get(BasicKeys.rootOutputDirectory)
val outputDirectory = state
.get(BasicKeys.rootOutputDirectory)
.getOrElse(sys.error("outputDirectory has not been set"))
val fileConverter =
state.get(BasicKeys.fileConverter).getOrElse(sys.error("outputDirectory has not been set"))
val cacheStore = state
.get(BasicKeys.cacheStores)
.collect { case xs if xs.nonEmpty => AggregateActionCacheStore(xs) }
.getOrElse(DiskActionCacheStore(state.baseDir.toPath.resolve("target/bootcache")))
val fileConverter = state.get(BasicKeys.fileConverter)
.getOrElse(
DiskActionCacheStore(state.baseDir.toPath.resolve("target/bootcache"), fileConverter)
)
BuildWideCacheConfiguration(
cacheStore,
outputDirectory.getOrElse(sys.error("outputDirectory has not been set")),
fileConverter.getOrElse(sys.error("outputDirectory has not been set")),
outputDirectory,
fileConverter,
state.log,
cacheEventLog,
cacheEventLog
)
}

View File

@ -89,8 +89,9 @@ object RemoteCache {
.resolve("out")
},
cacheStores := {
val c = fileConverter.value
List(
DiskActionCacheStore(localCacheDirectory.value.toPath())
DiskActionCacheStore(localCacheDirectory.value.toPath, c)
)
},
remoteCache := SysProp.remoteCache,

View File

@ -5,18 +5,18 @@ val pure1 = taskKey[Unit]("")
val map1 = taskKey[String]("")
val mapN1 = taskKey[Unit]("")
Global / localCacheDirectory := new File("/tmp/sbt/diskcache/")
Global / localCacheDirectory := baseDirectory.value / "diskcache"
pure1 := (Def.cachedTask {
val output = StringVirtualFile1("a.txt", "foo")
val output = StringVirtualFile1("target/out/a.txt", "foo")
Def.declareOutput(output)
()
}).value
map1 := (Def.cachedTask {
pure1.value
val output1 = StringVirtualFile1("b1.txt", "foo")
val output2 = StringVirtualFile1("b2.txt", "foo")
val output1 = StringVirtualFile1("target/out/b1.txt", "foo")
val output2 = StringVirtualFile1("target/out/b2.txt", "foo")
Def.declareOutput(output1)
Def.declareOutput(output2)
"something"
@ -25,7 +25,7 @@ map1 := (Def.cachedTask {
mapN1 := (Def.cachedTask {
pure1.value
map1.value
val output = StringVirtualFile1("c.txt", "foo")
val output = StringVirtualFile1("target/out/c.txt", "foo")
Def.declareOutput(output)
()
}).value

View File

@ -2,15 +2,15 @@ import sbt.internal.util.StringVirtualFile1
import sjsonnew.BasicJsonProtocol.*
import CustomKeys.*
Global / localCacheDirectory := new File("/tmp/sbt/diskcache/")
Global / localCacheDirectory := baseDirectory.value / "diskcache"
aa := A()
// This tests that pure1 is opt'ed out from caching
// This tests that aa is opt'ed out from caching
map1 := (Def.cachedTask {
aa.value
val output1 = StringVirtualFile1("b1.txt", "foo")
val output2 = StringVirtualFile1("b2.txt", "foo")
val output1 = StringVirtualFile1("target/out/b1.txt", "foo")
val output2 = StringVirtualFile1("target/out/b2.txt", "foo")
Def.declareOutput(output1)
Def.declareOutput(output2)
"something"
@ -19,7 +19,7 @@ map1 := (Def.cachedTask {
mapN1 := (Def.cachedTask {
aa.value
map1.value
val output = StringVirtualFile1("c.txt", "foo")
val output = StringVirtualFile1("target/out/c.txt", "foo")
Def.declareOutput(output)
()
}).value

View File

@ -241,10 +241,7 @@ class GrpcActionCacheStore(
// per spec, Clients SHOULD NOT populate [contents] when uploading to the cache.
private def toOutputFile(ref: HashedVirtualFileRef): OutputFile =
val b = OutputFile.newBuilder()
val shortPath =
if ref.id.startsWith("${OUT}/") then ref.id.drop(7)
else ref.id
b.setPath(shortPath)
b.setPath(ref.id)
b.setDigest(toXDigest(Digest(ref)))
b.build()

View File

@ -54,7 +54,7 @@ object ActionCache:
throw e
val json = Converter.toJsonUnsafe(result)
val uncacheableOutputs =
outputs.filter(f => !fileConverter.toPath(f).startsWith(outputDirectory))
outputs.filter(f => !fileConverter.toPath(f).toAbsolutePath.startsWith(outputDirectory))
if uncacheableOutputs.nonEmpty then
cacheEventLog.append(ActionCacheEvent.Error)
logger.error(
@ -64,8 +64,8 @@ object ActionCache:
result
else
cacheEventLog.append(ActionCacheEvent.OnsiteTask)
val input = mkInput(key, codeContentHash, extraHash)
val valueFile = StringVirtualFile1(s"value/${input}.json", CompactPrinter(json))
val (input, valuePath) = mkInput(key, codeContentHash, extraHash, config)
val valueFile = StringVirtualFile1(valuePath, CompactPrinter(json))
val newOutputs = Vector(valueFile) ++ outputs.toVector
store.put(UpdateActionResultRequest(input, newOutputs, exitCode = 0)) match
case Right(cachedResult) =>
@ -126,8 +126,7 @@ object ActionCache:
extraHash: Digest,
config: BuildWideCacheConfiguration,
): Either[Throwable, ActionResult] =
val input = mkInput(key, codeContentHash, extraHash)
val valuePath = s"value/${input}.json"
val (input, valuePath) = mkInput(key, codeContentHash, extraHash, config)
val getRequest =
GetActionResultRequest(input, inlineStdout = false, inlineStderr = false, Vector(valuePath))
config.store.get(getRequest)
@ -135,9 +134,12 @@ object ActionCache:
private inline def mkInput[I: HashWriter](
key: I,
codeContentHash: Digest,
extraHash: Digest
): Digest =
Digest.sha256Hash(codeContentHash, extraHash, Digest.dummy(Hasher.hashUnsafe[I](key)))
extraHash: Digest,
config: BuildWideCacheConfiguration
): (Digest, String) =
val input =
Digest.sha256Hash(codeContentHash, extraHash, Digest.dummy(Hasher.hashUnsafe[I](key)))
(input, s"${config.outputDirectory}/value/$input.json")
def manifestFromFile(manifest: Path): Manifest =
import sbt.internal.util.codec.ManifestCodec.given

View File

@ -17,7 +17,7 @@ import sbt.nio.file.{ **, FileTreeView }
import sbt.nio.file.syntax.*
import sbt.internal.util.{ StringVirtualFile1, Util }
import sbt.internal.util.codec.ActionResultCodec.given
import xsbti.{ HashedVirtualFileRef, PathBasedFile, VirtualFile }
import xsbti.{ FileConverter, HashedVirtualFileRef, PathBasedFile, VirtualFile }
import java.io.InputStream
/**
@ -170,7 +170,7 @@ class InMemoryActionCacheStore extends AbstractActionCacheStore:
underlying.toString()
end InMemoryActionCacheStore
class DiskActionCacheStore(base: Path) extends AbstractActionCacheStore:
class DiskActionCacheStore(base: Path, converter: FileConverter) extends AbstractActionCacheStore:
lazy val casBase: Path = {
val dir = base.resolve("cas")
IO.createDirectory(dir.toFile)
@ -262,9 +262,6 @@ class DiskActionCacheStore(base: Path) extends AbstractActionCacheStore:
else None
def syncFile(ref: HashedVirtualFileRef, casFile: Path, outputDirectory: Path): Path =
val shortPath =
if ref.id.startsWith("${OUT}/") then ref.id.drop(7)
else ref.id
val d = Digest(ref)
def copyFile(outPath: Path): Path =
Files.copy(
@ -293,7 +290,7 @@ class DiskActionCacheStore(base: Path) extends AbstractActionCacheStore:
else copyFile(outPath)
afterFileWrite(ref, result, outputDirectory)
result
outputDirectory.resolve(shortPath) match
converter.toPath(ref) match
case p if !Files.exists(p) =>
// println(s"- syncFile: $p does not exist")
writeFileAndNotify(p)
@ -335,18 +332,17 @@ class DiskActionCacheStore(base: Path) extends AbstractActionCacheStore:
// manifest contains the list of files in the dirzip, and their hashes
val m = ActionCache.manifestFromFile(mPath)
m.outputFiles.foreach: ref =>
val shortPath =
if ref.id.startsWith("${OUT}/") then ref.id.drop(7)
else ref.id
val currentItem = outputDirectory.resolve(shortPath)
val currentItem = converter.toPath(ref)
val shortPath = outputDirectory.relativize(currentItem).toString
allPaths.remove(currentItem)
val d = Digest(ref)
def tempPath = tempDir.toPath.resolve(shortPath)
currentItem match
case p if !Files.exists(p) => doSync(ref, tempDir.toPath().resolve(shortPath))
case p if !Files.exists(p) => doSync(ref, tempPath)
case p if Digest.sameDigest(p, d) => ()
case p =>
IO.delete(p.toFile())
doSync(ref, tempDir.toPath().resolve(shortPath))
doSync(ref, tempPath)
// sync deleted files
allPaths.foreach: path =>
IO.delete(path.toFile())

View File

@ -20,10 +20,10 @@ object ActionCacheTest extends BasicTestSuite:
withDiskCache(testHoldBlob)
def testHoldBlob(cache: ActionCacheStore): Unit =
val in = StringVirtualFile1("a.txt", "foo")
val hashRefs = cache.putBlobs(in :: Nil)
assert(hashRefs.size == 1)
IO.withTemporaryDirectory: tempDir =>
val in = StringVirtualFile1(s"$tempDir/a.txt", "foo")
val hashRefs = cache.putBlobs(in :: Nil)
assert(hashRefs.size == 1)
val actual = cache.syncBlobs(hashRefs, tempDir.toPath()).head
assert(actual.getFileName().toString() == "a.txt")
@ -88,7 +88,7 @@ object ActionCacheTest extends BasicTestSuite:
IO.withTemporaryDirectory(
{ tempDir0 =>
val tempDir = tempDir0.toPath
val cache = DiskActionCacheStore(tempDir)
val cache = DiskActionCacheStore(tempDir, fileConverter)
f(cache)
},
keepDirectory = false