| // Copyright 2026 The Bazel Authors. All rights reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| package com.google.devtools.build.lib.actions; | |
| import static com.google.common.truth.Truth.assertThat; | |
| import static org.junit.Assert.assertThrows; | |
| import com.google.common.collect.ImmutableMap; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.junit.runners.JUnit4; | |
| /** Tests for {@link ExecutionRequirements}. */ | |
| @RunWith(JUnit4.class) | |
| public class ExecutionRequirementsTest { | |
| @Test | |
| public void parseResources_empty() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of())).isEmpty(); | |
| } | |
| @Test | |
| public void parseResources_ignoresUnrelatedKeys() throws Exception { | |
| assertThat( | |
| ExecutionRequirements.parseResources( | |
| ImmutableMap.of("pool", "default", "no-sandbox", "", "local", ""))) | |
| .isEmpty(); | |
| } | |
| // exec_properties format: key = "resources:name", value = "amount" | |
| @Test | |
| public void parseResources_execProp_cpu() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu", "4"))) | |
| .containsExactly("cpu", 4.0); | |
| } | |
| @Test | |
| public void parseResources_execProp_memory() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("resources:memory", "2000"))) | |
| .containsExactly("memory", 2000.0); | |
| } | |
| @Test | |
| public void parseResources_execProp_multiple() throws Exception { | |
| assertThat( | |
| ExecutionRequirements.parseResources( | |
| ImmutableMap.of("resources:cpu", "8", "resources:memory", "4000"))) | |
| .containsExactly("cpu", 8.0, "memory", 4000.0); | |
| } | |
| @Test | |
| public void parseResources_execProp_customResource() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("resources:gpu", "2"))) | |
| .containsExactly("gpu", 2.0); | |
| } | |
| @Test | |
| public void parseResources_execProp_floatingPoint() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu", "2.5"))) | |
| .containsExactly("cpu", 2.5); | |
| } | |
| @Test | |
| public void parseResources_execProp_mixedKeys() throws Exception { | |
| assertThat( | |
| ExecutionRequirements.parseResources( | |
| ImmutableMap.of( | |
| "pool", "default", | |
| "resources:cpu", "4", | |
| "container-image", "docker://foo", | |
| "resources:gpu", "1"))) | |
| .containsExactly("cpu", 4.0, "gpu", 1.0); | |
| } | |
| // Tag format: key = "resources:name:amount" or "cpu:amount", value = "" | |
| @Test | |
| public void parseResources_tag_resources() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu:4", ""))) | |
| .containsExactly("cpu", 4.0); | |
| } | |
| @Test | |
| public void parseResources_tag_cpu() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("cpu:2", ""))) | |
| .containsExactly("cpu", 2.0); | |
| } | |
| @Test | |
| public void parseResources_tag_customResource() throws Exception { | |
| assertThat(ExecutionRequirements.parseResources(ImmutableMap.of("resources:gpu:3", ""))) | |
| .containsExactly("gpu", 3.0); | |
| } | |
| @Test | |
| public void parseResources_tag_multiple() throws Exception { | |
| assertThat( | |
| ExecutionRequirements.parseResources( | |
| ImmutableMap.of("resources:gpu:2", "", "cpu:4", ""))) | |
| .containsExactly("gpu", 2.0, "cpu", 4.0); | |
| } | |
| // Validation | |
| @Test | |
| public void parseResources_throwsOnTagMissingAmount() { | |
| assertThrows( | |
| UserExecException.class, | |
| () -> ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu:", ""))); | |
| } | |
| @Test | |
| public void parseResources_throwsOnExecPropMissingAmount() { | |
| assertThrows( | |
| UserExecException.class, | |
| () -> ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu", ""))); | |
| } | |
| @Test | |
| public void parseResources_throwsOnInvalidTagValue() { | |
| assertThrows( | |
| UserExecException.class, | |
| () -> | |
| ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu:notanumber", ""))); | |
| } | |
| @Test | |
| public void parseResources_throwsOnInvalidExecPropValue() { | |
| assertThrows( | |
| UserExecException.class, | |
| () -> ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu", "notanumber"))); | |
| } | |
| @Test | |
| public void parseResources_throwsOnNegativeTagValue() { | |
| assertThrows( | |
| UserExecException.class, | |
| () -> ExecutionRequirements.parseResources(ImmutableMap.of("resources:cpu:-1", ""))); | |
| } | |
| @Test | |
| public void parseResources_throwsOnDuplicateResource() { | |
| assertThrows( | |
| UserExecException.class, | |
| () -> | |
| ExecutionRequirements.parseResources( | |
| ImmutableMap.of("resources:cpu:4", "", "cpu:2", ""))); | |
| } | |
| } |