Unshare FileArtifactValues associated with constant-metadata Artifacts: they can't really be used across servers.

PiperOrigin-RevId: 236567498
diff --git a/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java b/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java
index 5813d73..591227b 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/FileArtifactValue.java
@@ -182,7 +182,8 @@
         isFile,
         isFile ? fileValue.getSize() : 0,
         proxy,
-        isFile ? fileValue.getDigest() : null);
+        isFile ? fileValue.getDigest() : null,
+        !artifact.isConstantMetadata());
   }
 
   public static FileArtifactValue create(Artifact artifact, ArtifactFileMetadata metadata)
@@ -194,7 +195,8 @@
         isFile,
         isFile ? metadata.getSize() : 0,
         proxy,
-        isFile ? metadata.getDigest() : null);
+        isFile ? metadata.getDigest() : null,
+        !artifact.isConstantMetadata());
   }
 
   public static FileArtifactValue create(
@@ -206,27 +208,43 @@
     boolean isFile = fileValue.isFile();
     FileContentsProxy proxy = getProxyFromFileStateValue(fileValue.realFileStateValue());
     return create(
-        resolver.toPath(artifact), isFile, isFile ? fileValue.getSize() : 0, proxy, injectedDigest);
+        resolver.toPath(artifact),
+        isFile,
+        isFile ? fileValue.getSize() : 0,
+        proxy,
+        injectedDigest,
+        !artifact.isConstantMetadata());
   }
 
   @VisibleForTesting
   public static FileArtifactValue create(Artifact artifact) throws IOException {
-    return create(artifact.getPath());
+    return create(artifact.getPath(), !artifact.isConstantMetadata());
   }
 
-  public static FileArtifactValue create(Path path) throws IOException {
+  public static FileArtifactValue createShareable(Path path) throws IOException {
+    return create(path, /*isShareable=*/ true);
+  }
+
+  public static FileArtifactValue create(Path path, boolean isShareable) throws IOException {
     // Caution: there's a race condition between stating the file and computing the
     // digest. We need to stat first, since we're using the stat to detect changes.
     // We follow symlinks here to be consistent with getDigest.
-    return create(path, path.stat(Symlinks.FOLLOW));
+    return create(path, path.stat(Symlinks.FOLLOW), isShareable);
   }
 
-  public static FileArtifactValue create(Path path, FileStatus stat) throws IOException {
-    return create(path, stat.isFile(), stat.getSize(), FileContentsProxy.create(stat), null);
+  public static FileArtifactValue create(Path path, FileStatus stat, boolean isShareable)
+      throws IOException {
+    return create(
+        path, stat.isFile(), stat.getSize(), FileContentsProxy.create(stat), null, isShareable);
   }
 
   private static FileArtifactValue create(
-      Path path, boolean isFile, long size, FileContentsProxy proxy, @Nullable byte[] digest)
+      Path path,
+      boolean isFile,
+      long size,
+      FileContentsProxy proxy,
+      @Nullable byte[] digest,
+      boolean isShareable)
       throws IOException {
     if (!isFile) {
       // In this case, we need to store the mtime because the action cache uses mtime for
@@ -238,27 +256,26 @@
       digest = DigestUtils.getDigestOrFail(path, size);
     }
     Preconditions.checkState(digest != null, path);
-    return new RegularFileArtifactValue(digest, proxy, size);
+    return createNormalFile(digest, proxy, size, isShareable);
   }
 
   public static FileArtifactValue createForVirtualActionInput(byte[] digest, long size) {
     return new RegularFileArtifactValue(digest, /*proxy=*/ null, size);
   }
 
-  public static FileArtifactValue createNormalFile(
-      byte[] digest, @Nullable FileContentsProxy proxy, long size) {
-    return new RegularFileArtifactValue(digest, proxy, size);
-  }
-
-  public static FileArtifactValue createNormalFile(ArtifactFileMetadata artifactMetadata) {
-    FileContentsProxy proxy = getProxyFromFileStateValue(artifactMetadata.realFileStateValue());
-    return new RegularFileArtifactValue(
-        artifactMetadata.getDigest(), proxy, artifactMetadata.getSize());
-  }
-
   @VisibleForTesting
-  public static FileArtifactValue createNormalFile(byte[] digest, long size) {
-    return createNormalFile(digest, /*proxy=*/ null, size);
+  public static FileArtifactValue createNormalFile(
+      byte[] digest, @Nullable FileContentsProxy proxy, long size, boolean isShareable) {
+    return isShareable
+        ? new RegularFileArtifactValue(digest, proxy, size)
+        : new UnshareableRegularFileArtifactValue(digest, proxy, size);
+  }
+
+  public static FileArtifactValue createNormalFile(
+      ArtifactFileMetadata artifactMetadata, boolean isShareable) {
+    FileContentsProxy proxy = getProxyFromFileStateValue(artifactMetadata.realFileStateValue());
+    return createNormalFile(
+        artifactMetadata.getDigest(), proxy, artifactMetadata.getSize(), isShareable);
   }
 
   public static FileArtifactValue createDirectoryWithHash(byte[] digest) {
@@ -275,7 +292,7 @@
    */
   public static FileArtifactValue createProxy(byte[] digest) {
     Preconditions.checkNotNull(digest);
-    return createNormalFile(digest, /*proxy=*/ null, /*size=*/ 0);
+    return createNormalFile(digest, /*proxy=*/ null, /*size=*/ 0, /*isShareable=*/ true);
   }
 
   private static final class DirectoryArtifactValue extends FileArtifactValue {
@@ -384,7 +401,7 @@
     }
   }
 
-  private static final class RegularFileArtifactValue extends FileArtifactValue {
+  private static class RegularFileArtifactValue extends FileArtifactValue {
     private final byte[] digest;
     @Nullable private final FileContentsProxy proxy;
     private final long size;
@@ -442,7 +459,10 @@
         return false;
       }
       RegularFileArtifactValue r = (RegularFileArtifactValue) o;
-      return Arrays.equals(digest, r.digest) && Objects.equals(proxy, r.proxy) && size == r.size;
+      return Arrays.equals(digest, r.digest)
+          && Objects.equals(proxy, r.proxy)
+          && size == r.size
+          && dataIsShareable() == r.dataIsShareable();
     }
 
     @Override
@@ -452,6 +472,18 @@
     }
   }
 
+  private static final class UnshareableRegularFileArtifactValue extends RegularFileArtifactValue {
+    private UnshareableRegularFileArtifactValue(
+        byte[] digest, @Nullable FileContentsProxy proxy, long size) {
+      super(digest, proxy, size);
+    }
+
+    @Override
+    public boolean dataIsShareable() {
+      return false;
+    }
+  }
+
   /** Metadata for remotely stored files. */
   public static final class RemoteFileArtifactValue extends FileArtifactValue {
     private final byte[] digest;
@@ -510,20 +542,26 @@
   }
 
   /** File stored inline in metadata. */
-  public static final class InlineFileArtifactValue extends FileArtifactValue {
+  public static class InlineFileArtifactValue extends FileArtifactValue {
     private final byte[] data;
     private final byte[] digest;
 
-    public InlineFileArtifactValue(byte[] data, byte[] digest) {
+    private InlineFileArtifactValue(byte[] data, byte[] digest) {
       this.data = Preconditions.checkNotNull(data);
       this.digest = Preconditions.checkNotNull(digest);
     }
 
-    public InlineFileArtifactValue(byte[] bytes) {
+    private InlineFileArtifactValue(byte[] bytes) {
       this(bytes,
           DigestHashFunction.getDefaultUnchecked().getHashFunction().hashBytes(bytes).asBytes());
     }
 
+    public static InlineFileArtifactValue create(byte[] bytes, boolean shareable) {
+      return shareable
+          ? new InlineFileArtifactValue(bytes)
+          : new UnshareableInlineFileArtifactValue(bytes);
+    }
+
     public ByteArrayInputStream getInputStream() {
       return new ByteArrayInputStream(data);
     }
@@ -554,6 +592,17 @@
     }
   }
 
+  private static final class UnshareableInlineFileArtifactValue extends InlineFileArtifactValue {
+    UnshareableInlineFileArtifactValue(byte[] bytes) {
+      super(bytes);
+    }
+
+    @Override
+    public boolean dataIsShareable() {
+      return false;
+    }
+  }
+
   /**
    * Used to resolve source symlinks when diskless.
    *
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java b/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java
index d1e7bf5..4f60575 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/SingleBuildFileCache.java
@@ -62,7 +62,7 @@
               () -> {
                 Path path = ActionInputHelper.toInputPath(input, execRoot);
                 try {
-                  FileArtifactValue metadata = FileArtifactValue.create(path);
+                  FileArtifactValue metadata = FileArtifactValue.createShareable(path);
                   if (metadata.getType().isDirectory()) {
                     throw new DigestOfDirectoryException(
                         "Input is a directory: " + input.getExecPathString());
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
index 67931c7..cab7241 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
@@ -229,7 +229,7 @@
       if (!fileMetadata.exists()) {
         throw new FileNotFoundException(artifact.prettyPrint() + " does not exist");
       }
-      return FileArtifactValue.createNormalFile(fileMetadata);
+      return FileArtifactValue.createNormalFile(fileMetadata, !artifact.isConstantMetadata());
     }
 
     // No existing metadata; this can happen if the output metadata is not injected after a spawn
@@ -269,7 +269,7 @@
     if (isFile && !artifact.hasParent() && data.getDigest() != null) {
       // We do not need to store the FileArtifactValue separately -- the digest is in the file value
       // and that is all that is needed for this file's metadata.
-      return FileArtifactValue.createNormalFile(data);
+      return FileArtifactValue.createNormalFile(data, !artifact.isConstantMetadata());
     }
     // Unfortunately, the ArtifactFileMetadata does not contain enough information for us to
     // calculate the corresponding FileArtifactValue -- either the metadata must use the modified
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
index 395d70e..71de21a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
@@ -312,7 +312,7 @@
     // Directories are special-cased because their mtimes are used, so should have been constructed
     // during execution of the action (in ActionMetadataHandler#maybeStoreAdditionalData).
     Preconditions.checkState(data.isFile(), "Unexpected not file %s (%s)", artifact, data);
-    return FileArtifactValue.createNormalFile(data);
+    return FileArtifactValue.createNormalFile(data, !artifact.isConstantMetadata());
   }
 
   @Nullable
diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
index b2f3384..f82e696 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/exec/SpawnInputExpanderTest.java
@@ -89,7 +89,10 @@
     Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
-    mockCache.put(artifact, FileArtifactValue.createNormalFile(FAKE_DIGEST, 0));
+    mockCache.put(
+        artifact,
+        FileArtifactValue.createNormalFile(
+            FAKE_DIGEST, /*proxy=*/ null, 0L, /*isShareable=*/ true));
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER,
         ArtifactPathResolver.IDENTITY, true);
@@ -151,8 +154,14 @@
         new Runfiles.Builder("workspace").addArtifact(artifact1).addArtifact(artifact2).build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
-    mockCache.put(artifact1, FileArtifactValue.createNormalFile(FAKE_DIGEST, 1));
-    mockCache.put(artifact2, FileArtifactValue.createNormalFile(FAKE_DIGEST, 2));
+    mockCache.put(
+        artifact1,
+        FileArtifactValue.createNormalFile(
+            FAKE_DIGEST, /*proxy=*/ null, 1L, /*isShareable=*/ true));
+    mockCache.put(
+        artifact2,
+        FileArtifactValue.createNormalFile(
+            FAKE_DIGEST, /*proxy=*/ null, 12L, /*isShareable=*/ true));
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER,
         ArtifactPathResolver.IDENTITY, true);
@@ -175,7 +184,10 @@
             .build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
-    mockCache.put(artifact, FileArtifactValue.createNormalFile(FAKE_DIGEST, 1));
+    mockCache.put(
+        artifact,
+        FileArtifactValue.createNormalFile(
+            FAKE_DIGEST, /*proxy=*/ null, 1L, /*isShareable=*/ true));
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER,
         ArtifactPathResolver.IDENTITY, true);
@@ -196,7 +208,10 @@
             .build();
     RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
     FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
-    mockCache.put(artifact, FileArtifactValue.createNormalFile(FAKE_DIGEST, 1));
+    mockCache.put(
+        artifact,
+        FileArtifactValue.createNormalFile(
+            FAKE_DIGEST, /*proxy=*/ null, 1L, /*isShareable=*/ true));
 
     expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER,
         ArtifactPathResolver.IDENTITY, true);
diff --git a/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java b/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java
index 3d21a51..a746131 100644
--- a/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java
+++ b/src/test/java/com/google/devtools/build/lib/remote/FakeActionInputFileCache.java
@@ -47,7 +47,10 @@
     Path path = execRoot.getRelative(input.getExecPath());
     FileStatus stat = path.stat(Symlinks.FOLLOW);
     return FileArtifactValue.createNormalFile(
-        HashCode.fromString(hexDigest).asBytes(), FileContentsProxy.create(stat), stat.getSize());
+        HashCode.fromString(hexDigest).asBytes(),
+        FileContentsProxy.create(stat),
+        stat.getSize(),
+        /*isShareable=*/ true);
   }
 
   @Override
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java
index eab3acf..d373868 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java
@@ -54,7 +54,9 @@
   @Test
   public void withNonArtifactInput() throws Exception {
     ActionInput input = ActionInputHelper.fromPath("foo/bar");
-    FileArtifactValue metadata = FileArtifactValue.createNormalFile(new byte[] {1,  2, 3}, 10);
+    FileArtifactValue metadata =
+        FileArtifactValue.createNormalFile(
+            new byte[] {1, 2, 3}, /*proxy=*/ null, 10L, /*isShareable=*/ true);
     ActionInputMap map = new ActionInputMap(1);
     map.putWithNoDepOwner(input, metadata);
     assertThat(map.getMetadata(input)).isEqualTo(metadata);
@@ -72,7 +74,9 @@
   public void withArtifactInput() throws Exception {
     PathFragment path = PathFragment.create("src/a");
     Artifact artifact = new Artifact(path, sourceRoot);
-    FileArtifactValue metadata = FileArtifactValue.createNormalFile(new byte[] {1,  2, 3}, 10);
+    FileArtifactValue metadata =
+        FileArtifactValue.createNormalFile(
+            new byte[] {1, 2, 3}, /*proxy=*/ null, 10L, /*isShareable=*/ true);
     ActionInputMap map = new ActionInputMap(1);
     map.putWithNoDepOwner(artifact, metadata);
     ActionMetadataHandler handler = new ActionMetadataHandler(
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java
index fbad99e..d689928 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileArtifactValueTest.java
@@ -14,7 +14,7 @@
 package com.google.devtools.build.lib.skyframe;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.devtools.build.lib.actions.FileArtifactValue.create;
+import static com.google.devtools.build.lib.actions.FileArtifactValue.createShareable;
 import static org.junit.Assert.fail;
 
 import com.google.common.io.BaseEncoding;
@@ -60,16 +60,37 @@
     // and inequality with members of other equality groups.
     new EqualsTester()
         .addEqualityGroup(
-            FileArtifactValue.createNormalFile(toBytes("00112233445566778899AABBCCDDEEFF"), 1),
-            FileArtifactValue.createNormalFile(toBytes("00112233445566778899AABBCCDDEEFF"), 1))
+            FileArtifactValue.createNormalFile(
+                toBytes("00112233445566778899AABBCCDDEEFF"),
+                /*proxy=*/ null,
+                1L,
+                /*isShareable=*/ true),
+            FileArtifactValue.createNormalFile(
+                toBytes("00112233445566778899AABBCCDDEEFF"),
+                /*proxy=*/ null,
+                1L,
+                /*isShareable=*/ true))
         .addEqualityGroup(
-            FileArtifactValue.createNormalFile(toBytes("00112233445566778899AABBCCDDEEFF"), 2))
+            FileArtifactValue.createNormalFile(
+                toBytes("00112233445566778899AABBCCDDEEFF"),
+                /*proxy=*/ null,
+                2L,
+                /*isShareable=*/ true))
         .addEqualityGroup(FileArtifactValue.createDirectory(1))
         .addEqualityGroup(
-            FileArtifactValue.createNormalFile(toBytes("FFFFFF00000000000000000000000000"), 1))
+            FileArtifactValue.createNormalFile(
+                toBytes("FFFFFF00000000000000000000000000"),
+                /*proxy=*/ null,
+                1L,
+                /*isShareable=*/ true))
         .addEqualityGroup(
-            FileArtifactValue.createDirectory(2),
-            FileArtifactValue.createDirectory(2))
+            FileArtifactValue.createNormalFile(
+                toBytes("FFFFFF00000000000000000000000000"),
+                /*proxy=*/ null,
+                1L,
+                /*isShareable=*/ false))
+        .addEqualityGroup(
+            FileArtifactValue.createDirectory(2), FileArtifactValue.createDirectory(2))
         .addEqualityGroup(FileArtifactValue.OMITTED_FILE_MARKER)
         .addEqualityGroup(FileArtifactValue.MISSING_FILE_MARKER)
         .addEqualityGroup(FileArtifactValue.DEFAULT_MIDDLEMAN)
@@ -94,33 +115,33 @@
 
     new EqualsTester()
         // We check for ctime and inode equality for paths.
-        .addEqualityGroup(create(path1))
-        .addEqualityGroup(create(path2))
-        .addEqualityGroup(create(mtimePath))
-        .addEqualityGroup(create(digestPath))
-        .addEqualityGroup(create(empty1))
-        .addEqualityGroup(create(empty2))
-        .addEqualityGroup(create(empty3))
+        .addEqualityGroup(createShareable(path1))
+        .addEqualityGroup(createShareable(path2))
+        .addEqualityGroup(createShareable(mtimePath))
+        .addEqualityGroup(createShareable(digestPath))
+        .addEqualityGroup(createShareable(empty1))
+        .addEqualityGroup(createShareable(empty2))
+        .addEqualityGroup(createShareable(empty3))
         // We check for mtime equality for directories.
-        .addEqualityGroup(create(dir1))
-        .addEqualityGroup(create(dir2), create(dir3))
+        .addEqualityGroup(createShareable(dir1))
+        .addEqualityGroup(createShareable(dir2), createShareable(dir3))
         .testEquals();
   }
 
   @Test
   public void testCtimeInEquality() throws Exception {
     Path path = scratchFile("/dir/artifact1", 0L, "content");
-    FileArtifactValue before = create(path);
+    FileArtifactValue before = createShareable(path);
     clock.advanceMillis(1);
     path.chmod(0777);
-    FileArtifactValue after = create(path);
+    FileArtifactValue after = createShareable(path);
     assertThat(before).isNotEqualTo(after);
   }
 
   @Test
   public void testNoMtimeIfNonemptyFile() throws Exception {
     Path path = scratchFile("/root/non-empty", 1L, "abc");
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     assertThat(value.getDigest()).isEqualTo(path.getDigest());
     assertThat(value.getSize()).isEqualTo(3L);
     try {
@@ -134,7 +155,7 @@
   @Test
   public void testDirectory() throws Exception {
     Path path = scratchDir("/dir", /*mtime=*/ 1L);
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     assertThat(value.getDigest()).isNull();
     assertThat(value.getModifiedTime()).isEqualTo(1L);
   }
@@ -144,7 +165,7 @@
   public void testEmptyFile() throws Exception {
     Path path = scratchFile("/root/empty", 1L, "");
     path.setLastModifiedTime(1L);
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     assertThat(value.getDigest()).isEqualTo(path.getDigest());
     assertThat(value.getSize()).isEqualTo(0L);
     try {
@@ -174,7 +195,7 @@
     path.getParentDirectory().createDirectoryAndParents();
     FileSystemUtils.writeContentAsLatin1(path, "content");
     try {
-      create(path);
+      createShareable(path);
       fail();
     } catch (IOException e) {
       assertThat(e).isSameAs(exception);
@@ -184,7 +205,7 @@
   @Test
   public void testUptodateCheck() throws Exception {
     Path path = scratchFile("/dir/artifact1", 0L, "content");
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     clock.advanceMillis(1);
     assertThat(value.wasModifiedSinceDigest(path)).isFalse();
     clock.advanceMillis(1);
@@ -199,7 +220,7 @@
   @Test
   public void testUptodateCheckDeleteFile() throws Exception {
     Path path = scratchFile("/dir/artifact1", 0L, "content");
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     assertThat(value.wasModifiedSinceDigest(path)).isFalse();
     path.delete();
     assertThat(value.wasModifiedSinceDigest(path)).isTrue();
@@ -209,7 +230,7 @@
   public void testUptodateCheckDirectory() throws Exception {
     // For now, we don't attempt to detect changes to directories.
     Path path = scratchDir("/dir", 0L);
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     assertThat(value.wasModifiedSinceDigest(path)).isFalse();
     path.delete();
     clock.advanceMillis(1);
@@ -220,7 +241,7 @@
   public void testUptodateChangeFileToDirectory() throws Exception {
     // For now, we don't attempt to detect changes to directories.
     Path path = scratchFile("/dir/file", 0L, "");
-    FileArtifactValue value = create(path);
+    FileArtifactValue value = createShareable(path);
     assertThat(value.wasModifiedSinceDigest(path)).isFalse();
     // If we only check ctime, then we need to change the clock here, or we get a ctime match on the
     // stat.
@@ -239,7 +260,7 @@
 
   @Test
   public void testIsMarkerValue_notMarker() throws Exception {
-    FileArtifactValue value = create(scratchFile("/dir/artifact1", 0L, "content"));
+    FileArtifactValue value = createShareable(scratchFile("/dir/artifact1", 0L, "content"));
     assertThat(value.isMarkerValue()).isFalse();
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
index 4b55ffc..4ff3220 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunctionTest.java
@@ -1003,7 +1003,7 @@
             && ((Artifact) skyKey.argument()).isTreeArtifact()) {
           return TreeArtifactValue.create(allTreeFiles);
         }
-        return FileArtifactValue.create(
+        return FileArtifactValue.createShareable(
             ArtifactSkyKey.artifact((SkyKey) skyKey.argument()).getPath());
       } catch (IOException e) {
         throw new SkyFunctionException(e, Transience.PERSISTENT){};
@@ -1017,8 +1017,7 @@
     }
 
     public void addNewTreeFileArtifact(TreeFileArtifact input) throws IOException {
-      allTreeFiles.put(input,
-          FileArtifactValue.create(input.getPath()));
+      allTreeFiles.put(input, FileArtifactValue.createShareable(input.getPath()));
     }
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
index d7dcdcd..04b3211 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
@@ -106,7 +106,8 @@
     // breaking changes.
     Map<String, FileArtifactValue> digestBuilder = new HashMap<>();
     for (PathFragment child : children) {
-      FileArtifactValue subdigest = FileArtifactValue.create(tree.getPath().getRelative(child));
+      FileArtifactValue subdigest =
+          FileArtifactValue.createShareable(tree.getPath().getRelative(child));
       digestBuilder.put(child.getPathString(), subdigest);
     }
     assertThat(DigestUtils.fromMetadata(digestBuilder).getDigestBytesUnsafe())