Skip to content

Commit ad74d52

Browse files
Fix checking remote cache for omitted files in buildevent file (#15405)
Enabling both `--noremote_upload_local_results` and `--incompatible_remote_build_event_upload_respect_no_cache` caused ByteStreamBuildEventArtifactuploader not to check if some files already existed remotely because local files were not to be uploaded. When using remote execution some of these files might exist remotely, so we want to check remote cache for those files even if we would not upload them if missing. The test case included depicts this failure case. Closes #15280. PiperOrigin-RevId: 442798312 (cherry picked from commit 317375d) Co-authored-by: Emil Kattainen <[email protected]>
1 parent 2186d15 commit ad74d52

File tree

2 files changed

+74
-20
lines changed

2 files changed

+74
-20
lines changed

src/main/java/com/google/devtools/build/lib/remote/ByteStreamBuildEventArtifactUploader.java

+45-20
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,14 @@ private static final class PathMetadata {
107107
private final Digest digest;
108108
private final boolean directory;
109109
private final boolean remote;
110+
private final boolean omitted;
110111

111-
PathMetadata(Path path, Digest digest, boolean directory, boolean remote) {
112+
PathMetadata(Path path, Digest digest, boolean directory, boolean remote, boolean omitted) {
112113
this.path = path;
113114
this.digest = digest;
114115
this.directory = directory;
115116
this.remote = remote;
117+
this.omitted = omitted;
116118
}
117119

118120
public Path getPath() {
@@ -130,6 +132,10 @@ public boolean isDirectory() {
130132
public boolean isRemote() {
131133
return remote;
132134
}
135+
136+
public boolean isOmitted() {
137+
return omitted;
138+
}
133139
}
134140

135141
/**
@@ -138,22 +144,29 @@ public boolean isRemote() {
138144
*/
139145
private PathMetadata readPathMetadata(Path file) throws IOException {
140146
if (file.isDirectory()) {
141-
return new PathMetadata(file, /* digest= */ null, /* directory= */ true, /* remote= */ false);
142-
}
143-
if (omittedFiles.contains(file)) {
144-
return new PathMetadata(file, /*digest=*/ null, /*directory=*/ false, /*remote=*/ false);
147+
return new PathMetadata(
148+
file,
149+
/* digest= */ null,
150+
/* directory= */ true,
151+
/* remote= */ false,
152+
/* omitted= */ false);
145153
}
146154

147-
for (Path treeRoot : omittedTreeRoots) {
148-
if (file.startsWith(treeRoot)) {
149-
omittedFiles.add(file);
150-
return new PathMetadata(file, /*digest=*/ null, /*directory=*/ false, /*remote=*/ false);
155+
boolean omitted = false;
156+
if (omittedFiles.contains(file)) {
157+
omitted = true;
158+
} else {
159+
for (Path treeRoot : omittedTreeRoots) {
160+
if (file.startsWith(treeRoot)) {
161+
omittedFiles.add(file);
162+
omitted = true;
163+
}
151164
}
152165
}
153166

154167
DigestUtil digestUtil = new DigestUtil(file.getFileSystem().getDigestFunction());
155168
Digest digest = digestUtil.compute(file);
156-
return new PathMetadata(file, digest, /* directory= */ false, isRemoteFile(file));
169+
return new PathMetadata(file, digest, /* directory= */ false, isRemoteFile(file), omitted);
157170
}
158171

159172
private static void processQueryResult(
@@ -166,14 +179,18 @@ private static void processQueryResult(
166179
} else {
167180
PathMetadata remotePathMetadata =
168181
new PathMetadata(
169-
file.getPath(), file.getDigest(), file.isDirectory(), /* remote= */ true);
182+
file.getPath(),
183+
file.getDigest(),
184+
file.isDirectory(),
185+
/* remote= */ true,
186+
file.isOmitted());
170187
knownRemotePaths.add(remotePathMetadata);
171188
}
172189
}
173190
}
174191

175192
private static boolean shouldUpload(PathMetadata path) {
176-
return path.getDigest() != null && !path.isRemote() && !path.isDirectory();
193+
return path.getDigest() != null && !path.isRemote() && !path.isDirectory() && !path.isOmitted();
177194
}
178195

179196
private Single<List<PathMetadata>> queryRemoteCache(
@@ -182,7 +199,8 @@ private Single<List<PathMetadata>> queryRemoteCache(
182199
List<PathMetadata> filesToQuery = new ArrayList<>();
183200
Set<Digest> digestsToQuery = new HashSet<>();
184201
for (PathMetadata path : paths) {
185-
if (shouldUpload(path)) {
202+
// Query remote cache for files even if omitted from uploading
203+
if (shouldUpload(path) || path.isOmitted()) {
186204
filesToQuery.add(path);
187205
digestsToQuery.add(path.getDigest());
188206
} else {
@@ -239,7 +257,8 @@ private Single<List<PathMetadata>> uploadLocalFiles(
239257
path.getPath(),
240258
/*digest=*/ null,
241259
path.isDirectory(),
242-
path.isRemote()));
260+
path.isRemote(),
261+
path.isOmitted()));
243262
});
244263
})
245264
.collect(Collectors.toList());
@@ -265,13 +284,17 @@ private Single<PathConverter> upload(Set<Path> files) {
265284
} catch (IOException e) {
266285
reporterUploadError(e);
267286
return new PathMetadata(
268-
file, /*digest=*/ null, /*directory=*/ false, /*remote=*/ false);
287+
file,
288+
/*digest=*/ null,
289+
/*directory=*/ false,
290+
/*remote=*/ false,
291+
/*omitted=*/ false);
269292
}
270293
})
271294
.collect(Collectors.toList())
272295
.flatMap(paths -> queryRemoteCache(remoteCache, context, paths))
273296
.flatMap(paths -> uploadLocalFiles(remoteCache, context, paths))
274-
.map(paths -> new PathConverterImpl(remoteServerInstanceName, paths, omittedFiles)),
297+
.map(paths -> new PathConverterImpl(remoteServerInstanceName, paths)),
275298
RemoteCache::release);
276299
}
277300

@@ -305,23 +328,25 @@ private static class PathConverterImpl implements PathConverter {
305328
private final Set<Path> skippedPaths;
306329
private final Set<Path> localPaths;
307330

308-
PathConverterImpl(
309-
String remoteServerInstanceName, List<PathMetadata> uploads, Set<Path> localPaths) {
331+
PathConverterImpl(String remoteServerInstanceName, List<PathMetadata> uploads) {
310332
Preconditions.checkNotNull(uploads);
311333
this.remoteServerInstanceName = remoteServerInstanceName;
312334
pathToDigest = new HashMap<>(uploads.size());
313335
ImmutableSet.Builder<Path> skippedPaths = ImmutableSet.builder();
336+
ImmutableSet.Builder<Path> localPaths = ImmutableSet.builder();
314337
for (PathMetadata pair : uploads) {
315338
Path path = pair.getPath();
316339
Digest digest = pair.getDigest();
317-
if (digest != null) {
340+
if (!pair.isRemote() && pair.isOmitted()) {
341+
localPaths.add(path);
342+
} else if (digest != null) {
318343
pathToDigest.put(path, digest);
319344
} else {
320345
skippedPaths.add(path);
321346
}
322347
}
323348
this.skippedPaths = skippedPaths.build();
324-
this.localPaths = localPaths;
349+
this.localPaths = localPaths.build();
325350
}
326351

327352
@Override

src/test/shell/bazel/remote/remote_execution_test.sh

+29
Original file line numberDiff line numberDiff line change
@@ -3498,6 +3498,35 @@ EOF
34983498
[[ "$remote_cas_files" == 1 ]] || fail "Expected 1 remote cas entries, not $remote_cas_files"
34993499
}
35003500

3501+
function test_remote_exec_convert_remote_file() {
3502+
mkdir -p a
3503+
cat > a/BUILD <<'EOF'
3504+
sh_test(
3505+
name = "test",
3506+
srcs = ["test.sh"],
3507+
)
3508+
EOF
3509+
cat > a/test.sh <<'EOF'
3510+
#!/bin/bash
3511+
set -e
3512+
echo \"foo\"
3513+
exit 0
3514+
EOF
3515+
chmod 755 a/test.sh
3516+
3517+
bazel test \
3518+
--remote_executor=grpc://localhost:${worker_port} \
3519+
--build_event_json_file=bep.json \
3520+
--noremote_upload_local_results \
3521+
--incompatible_remote_build_event_upload_respect_no_cache \
3522+
//a:test >& $TEST_log || "Failed to test //a:test"
3523+
3524+
cat bep.json > $TEST_log
3525+
expect_not_log "test\.log.*file://" || fail "remote files generated in remote execution are not converted"
3526+
expect_log "test\.log.*bytestream://" || fail "remote files generated in remote execution are not converted"
3527+
}
3528+
3529+
35013530
function test_uploader_ignore_disk_cache_of_combined_cache() {
35023531
mkdir -p a
35033532
cat > a/BUILD <<EOF

0 commit comments

Comments
 (0)