diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteServerCapabilities.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteServerCapabilities.java index 0afb9894217f3c..4904cff546cd53 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/RemoteServerCapabilities.java +++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteServerCapabilities.java @@ -201,17 +201,23 @@ public static ClientServerCompatibilityStatus checkClientServerCompatibility( return result.build(); // No point checking other execution fields. } - // Check execution digest function. - if (execCap.getDigestFunction() == DigestFunction.Value.UNKNOWN) { - // Server side error -- this is not supposed to happen. - result.addError("Remote server error: UNKNOWN execution digest function."); - } - if (execCap.getDigestFunction() != digestFunction) { + // Check execution digest function. The protocol only later added + // support for multiple digest functions for remote execution, so + // check both the singular and repeated field. + if (execCap.getDigestFunctionsList().isEmpty() && + execCap.getDigestFunction() != DigestFunction.Value.UNKNOWN && + execCap.getDigestFunction() != digestFunction) { result.addError( String.format( "Cannot use hash function %s with remote execution. " + "Server supported function is %s", digestFunction, execCap.getDigestFunction())); + } else if (!execCap.getDigestFunctionsList().contains(digestFunction)) { + result.addError( + String.format( + "Cannot use hash function %s with remote execution. " + + "Server supported functions are: %s", + digestFunction, execCap.getDigestFunctionsList())); } // Check execution priority is in the supported range. diff --git a/src/test/java/com/google/devtools/build/lib/remote/RemoteServerCapabilitiesTest.java b/src/test/java/com/google/devtools/build/lib/remote/RemoteServerCapabilitiesTest.java index a91bd7833e5b0c..27d74a09891e80 100644 --- a/src/test/java/com/google/devtools/build/lib/remote/RemoteServerCapabilitiesTest.java +++ b/src/test/java/com/google/devtools/build/lib/remote/RemoteServerCapabilitiesTest.java @@ -582,6 +582,30 @@ public void testCheckClientServerCompatibility_executionCapsOnly() throws Except assertThat(st.isOk()).isTrue(); } + @Test + public void testCheckClientServerCompatibility_executionCapsDigestFunctionsList() throws Exception { + ServerCapabilities caps = + ServerCapabilities.newBuilder() + .setLowApiVersion(ApiVersion.current.toSemVer()) + .setHighApiVersion(ApiVersion.current.toSemVer()) + .setExecutionCapabilities( + ExecutionCapabilities.newBuilder() + .addDigestFunctions(DigestFunction.Value.MD5) + .addDigestFunctions(DigestFunction.Value.SHA256) + .setExecEnabled(true) + .build()) + .build(); + RemoteOptions remoteOptions = Options.getDefaults(RemoteOptions.class); + remoteOptions.remoteExecutor = "server:port"; + RemoteServerCapabilities.ClientServerCompatibilityStatus st = + RemoteServerCapabilities.checkClientServerCompatibility( + caps, + remoteOptions, + DigestFunction.Value.SHA256, + ServerCapabilitiesRequirement.EXECUTION); + assertThat(st.isOk()).isTrue(); + } + @Test public void testCheckClientServerCompatibility_cacheCapsOnly() throws Exception { ServerCapabilities caps = diff --git a/third_party/remoteapis/build/bazel/remote/execution/v2/remote_execution.proto b/third_party/remoteapis/build/bazel/remote/execution/v2/remote_execution.proto index 60753f78ab59a5..b21baaebb32ccc 100644 --- a/third_party/remoteapis/build/bazel/remote/execution/v2/remote_execution.proto +++ b/third_party/remoteapis/build/bazel/remote/execution/v2/remote_execution.proto @@ -1843,7 +1843,10 @@ message CacheCapabilities { // Capabilities of the remote execution system. message ExecutionCapabilities { - // Remote execution may only support a single digest function. + // Legacy field for indicating which digest function is supported by + // the remote execution system. Implementations should consider the + // repeated digest_functions field first, falling back to this + // singular field if unset. DigestFunction.Value digest_function = 1; // Whether remote execution is enabled for the particular server/instance. @@ -1854,6 +1857,10 @@ message ExecutionCapabilities { // Supported node properties. repeated string supported_node_properties = 4; + + // All the digest functions supported by the remote execution system. + // If this field is set, it MUST also contain digest_function. + repeated DigestFunction.Value digest_functions = 5; } // Details for the tool used to call the API.