Skip to content

Commit 317375d

Browse files
exosoncopybara-github
authored andcommitted
Fix checking remote cache for omitted files in buildevent file
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
1 parent cc89e16 commit 317375d

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
@@ -112,12 +112,14 @@ private static final class PathMetadata {
112112
private final Digest digest;
113113
private final boolean directory;
114114
private final boolean remote;
115+
private final boolean omitted;
115116

116-
PathMetadata(Path path, Digest digest, boolean directory, boolean remote) {
117+
PathMetadata(Path path, Digest digest, boolean directory, boolean remote, boolean omitted) {
117118
this.path = path;
118119
this.digest = digest;
119120
this.directory = directory;
120121
this.remote = remote;
122+
this.omitted = omitted;
121123
}
122124

123125
public Path getPath() {
@@ -135,6 +137,10 @@ public boolean isDirectory() {
135137
public boolean isRemote() {
136138
return remote;
137139
}
140+
141+
public boolean isOmitted() {
142+
return omitted;
143+
}
138144
}
139145

140146
/**
@@ -143,22 +149,29 @@ public boolean isRemote() {
143149
*/
144150
private PathMetadata readPathMetadata(Path file) throws IOException {
145151
if (file.isDirectory()) {
146-
return new PathMetadata(file, /* digest= */ null, /* directory= */ true, /* remote= */ false);
147-
}
148-
if (omittedFiles.contains(file)) {
149-
return new PathMetadata(file, /*digest=*/ null, /*directory=*/ false, /*remote=*/ false);
152+
return new PathMetadata(
153+
file,
154+
/* digest= */ null,
155+
/* directory= */ true,
156+
/* remote= */ false,
157+
/* omitted= */ false);
150158
}
151159

152-
for (Path treeRoot : omittedTreeRoots) {
153-
if (file.startsWith(treeRoot)) {
154-
omittedFiles.add(file);
155-
return new PathMetadata(file, /*digest=*/ null, /*directory=*/ false, /*remote=*/ false);
160+
boolean omitted = false;
161+
if (omittedFiles.contains(file)) {
162+
omitted = true;
163+
} else {
164+
for (Path treeRoot : omittedTreeRoots) {
165+
if (file.startsWith(treeRoot)) {
166+
omittedFiles.add(file);
167+
omitted = true;
168+
}
156169
}
157170
}
158171

159172
DigestUtil digestUtil = new DigestUtil(xattrProvider, file.getFileSystem().getDigestFunction());
160173
Digest digest = digestUtil.compute(file);
161-
return new PathMetadata(file, digest, /* directory= */ false, isRemoteFile(file));
174+
return new PathMetadata(file, digest, /* directory= */ false, isRemoteFile(file), omitted);
162175
}
163176

164177
private static void processQueryResult(
@@ -171,14 +184,18 @@ private static void processQueryResult(
171184
} else {
172185
PathMetadata remotePathMetadata =
173186
new PathMetadata(
174-
file.getPath(), file.getDigest(), file.isDirectory(), /* remote= */ true);
187+
file.getPath(),
188+
file.getDigest(),
189+
file.isDirectory(),
190+
/* remote= */ true,
191+
file.isOmitted());
175192
knownRemotePaths.add(remotePathMetadata);
176193
}
177194
}
178195
}
179196

180197
private static boolean shouldUpload(PathMetadata path) {
181-
return path.getDigest() != null && !path.isRemote() && !path.isDirectory();
198+
return path.getDigest() != null && !path.isRemote() && !path.isDirectory() && !path.isOmitted();
182199
}
183200

184201
private Single<List<PathMetadata>> queryRemoteCache(
@@ -187,7 +204,8 @@ private Single<List<PathMetadata>> queryRemoteCache(
187204
List<PathMetadata> filesToQuery = new ArrayList<>();
188205
Set<Digest> digestsToQuery = new HashSet<>();
189206
for (PathMetadata path : paths) {
190-
if (shouldUpload(path)) {
207+
// Query remote cache for files even if omitted from uploading
208+
if (shouldUpload(path) || path.isOmitted()) {
191209
filesToQuery.add(path);
192210
digestsToQuery.add(path.getDigest());
193211
} else {
@@ -244,7 +262,8 @@ private Single<List<PathMetadata>> uploadLocalFiles(
244262
path.getPath(),
245263
/*digest=*/ null,
246264
path.isDirectory(),
247-
path.isRemote()));
265+
path.isRemote(),
266+
path.isOmitted()));
248267
});
249268
})
250269
.collect(Collectors.toList());
@@ -271,13 +290,17 @@ private Single<PathConverter> upload(Set<Path> files) {
271290
} catch (IOException e) {
272291
reporterUploadError(e);
273292
return new PathMetadata(
274-
file, /*digest=*/ null, /*directory=*/ false, /*remote=*/ false);
293+
file,
294+
/*digest=*/ null,
295+
/*directory=*/ false,
296+
/*remote=*/ false,
297+
/*omitted=*/ false);
275298
}
276299
})
277300
.collect(Collectors.toList())
278301
.flatMap(paths -> queryRemoteCache(remoteCache, context, paths))
279302
.flatMap(paths -> uploadLocalFiles(remoteCache, context, paths))
280-
.map(paths -> new PathConverterImpl(remoteServerInstanceName, paths, omittedFiles)),
303+
.map(paths -> new PathConverterImpl(remoteServerInstanceName, paths)),
281304
RemoteCache::release);
282305
}
283306

@@ -311,23 +334,25 @@ private static class PathConverterImpl implements PathConverter {
311334
private final Set<Path> skippedPaths;
312335
private final Set<Path> localPaths;
313336

314-
PathConverterImpl(
315-
String remoteServerInstanceName, List<PathMetadata> uploads, Set<Path> localPaths) {
337+
PathConverterImpl(String remoteServerInstanceName, List<PathMetadata> uploads) {
316338
Preconditions.checkNotNull(uploads);
317339
this.remoteServerInstanceName = remoteServerInstanceName;
318340
pathToDigest = new HashMap<>(uploads.size());
319341
ImmutableSet.Builder<Path> skippedPaths = ImmutableSet.builder();
342+
ImmutableSet.Builder<Path> localPaths = ImmutableSet.builder();
320343
for (PathMetadata pair : uploads) {
321344
Path path = pair.getPath();
322345
Digest digest = pair.getDigest();
323-
if (digest != null) {
346+
if (!pair.isRemote() && pair.isOmitted()) {
347+
localPaths.add(path);
348+
} else if (digest != null) {
324349
pathToDigest.put(path, digest);
325350
} else {
326351
skippedPaths.add(path);
327352
}
328353
}
329354
this.skippedPaths = skippedPaths.build();
330-
this.localPaths = localPaths;
355+
this.localPaths = localPaths.build();
331356
}
332357

333358
@Override

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

+29
Original file line numberDiff line numberDiff line change
@@ -3606,6 +3606,35 @@ EOF
36063606
[[ "$remote_cas_files" == 1 ]] || fail "Expected 1 remote cas entries, not $remote_cas_files"
36073607
}
36083608

3609+
function test_remote_exec_convert_remote_file() {
3610+
mkdir -p a
3611+
cat > a/BUILD <<'EOF'
3612+
sh_test(
3613+
name = "test",
3614+
srcs = ["test.sh"],
3615+
)
3616+
EOF
3617+
cat > a/test.sh <<'EOF'
3618+
#!/bin/bash
3619+
set -e
3620+
echo \"foo\"
3621+
exit 0
3622+
EOF
3623+
chmod 755 a/test.sh
3624+
3625+
bazel test \
3626+
--remote_executor=grpc://localhost:${worker_port} \
3627+
--build_event_json_file=bep.json \
3628+
--noremote_upload_local_results \
3629+
--incompatible_remote_build_event_upload_respect_no_cache \
3630+
//a:test >& $TEST_log || "Failed to test //a:test"
3631+
3632+
cat bep.json > $TEST_log
3633+
expect_not_log "test\.log.*file://" || fail "remote files generated in remote execution are not converted"
3634+
expect_log "test\.log.*bytestream://" || fail "remote files generated in remote execution are not converted"
3635+
}
3636+
3637+
36093638
function test_uploader_ignore_disk_cache_of_combined_cache() {
36103639
mkdir -p a
36113640
cat > a/BUILD <<EOF

0 commit comments

Comments
 (0)