| // Copyright 2016 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.packages; | |
| import static com.google.common.truth.Truth.assertThat; | |
| import com.google.common.collect.ImmutableSet; | |
| import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; | |
| import com.google.devtools.build.lib.cmdline.Label; | |
| import com.google.devtools.build.lib.cmdline.LabelSyntaxException; | |
| import net.starlark.java.syntax.Location; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.junit.runners.JUnit4; | |
| /** Test for {@link com.google.devtools.build.lib.packages.RequiredProviders} class */ | |
| @RunWith(JUnit4.class) | |
| public class RequiredProvidersTest { | |
| private static final String NO_PROVIDERS_REQUIRED = "no providers required"; | |
| private static final class P1 implements TransitiveInfoProvider {} | |
| private static final class P2 implements TransitiveInfoProvider {} | |
| private static final class P3 implements TransitiveInfoProvider {} | |
| private static final Provider P_NATIVE = | |
| new BuiltinProvider<StructImpl>("p_native", StructImpl.class) {}; | |
| private static final StarlarkProvider P_STARLARK = | |
| StarlarkProvider.builder(Location.BUILTIN).build(); | |
| static { | |
| try { | |
| P_STARLARK.export(ev -> {}, Label.create("foo/bar", "x.bzl"), "p_starlark"); | |
| } catch (LabelSyntaxException e) { | |
| throw new AssertionError(e); | |
| } | |
| } | |
| private static final StarlarkProviderIdentifier ID_NATIVE = | |
| StarlarkProviderIdentifier.forKey(P_NATIVE.getKey()); | |
| private static final StarlarkProviderIdentifier ID_STARLARK = | |
| StarlarkProviderIdentifier.forKey(P_STARLARK.getKey()); | |
| private static final StarlarkProviderIdentifier ID_LEGACY = | |
| StarlarkProviderIdentifier.forLegacy("p_legacy"); | |
| private static boolean satisfies(AdvertisedProviderSet providers, | |
| RequiredProviders requiredProviders) { | |
| boolean result = requiredProviders.isSatisfiedBy(providers); | |
| assertThat( | |
| requiredProviders.isSatisfiedBy( | |
| providers.getBuiltinProviders()::contains, | |
| providers.getStarlarkProviders()::contains)) | |
| .isEqualTo(result); | |
| return result; | |
| } | |
| @Test | |
| public void any() { | |
| assertThat(satisfies(AdvertisedProviderSet.EMPTY, | |
| RequiredProviders.acceptAnyBuilder().build())).isTrue(); | |
| assertThat(satisfies(AdvertisedProviderSet.ANY, | |
| RequiredProviders.acceptAnyBuilder().build())).isTrue(); | |
| assertThat( | |
| satisfies( | |
| AdvertisedProviderSet.builder().addBuiltin(P1.class).build(), | |
| RequiredProviders.acceptAnyBuilder().build())) | |
| .isTrue(); | |
| assertThat( | |
| satisfies( | |
| AdvertisedProviderSet.builder().addStarlark("p1").build(), | |
| RequiredProviders.acceptAnyBuilder().build())) | |
| .isTrue(); | |
| } | |
| @Test | |
| public void none() { | |
| assertThat(satisfies(AdvertisedProviderSet.EMPTY, | |
| RequiredProviders.acceptNoneBuilder().build())).isFalse(); | |
| assertThat(satisfies(AdvertisedProviderSet.ANY, | |
| RequiredProviders.acceptNoneBuilder().build())).isFalse(); | |
| assertThat( | |
| satisfies( | |
| AdvertisedProviderSet.builder().addBuiltin(P1.class).build(), | |
| RequiredProviders.acceptNoneBuilder().build())) | |
| .isFalse(); | |
| assertThat( | |
| satisfies( | |
| AdvertisedProviderSet.builder().addStarlark("p1").build(), | |
| RequiredProviders.acceptNoneBuilder().build())) | |
| .isFalse(); | |
| } | |
| @Test | |
| public void builtinProvidersAllMatch() { | |
| AdvertisedProviderSet providerSet = | |
| AdvertisedProviderSet.builder().addBuiltin(P1.class).addBuiltin(P2.class).build(); | |
| assertThat( | |
| validateNative(providerSet, NO_PROVIDERS_REQUIRED, ImmutableSet.of(P1.class, P2.class))) | |
| .isTrue(); | |
| } | |
| @Test | |
| public void builtinProvidersBranchMatch() { | |
| assertThat( | |
| validateNative( | |
| AdvertisedProviderSet.builder().addBuiltin(P1.class).build(), | |
| NO_PROVIDERS_REQUIRED, | |
| ImmutableSet.of(P1.class), | |
| ImmutableSet.of(P2.class))) | |
| .isTrue(); | |
| } | |
| @Test | |
| public void builtinsProvidersNoMatch() { | |
| assertThat( | |
| validateNative( | |
| AdvertisedProviderSet.builder().addBuiltin(P3.class).build(), | |
| "P1 or P2", | |
| ImmutableSet.of(P1.class), | |
| ImmutableSet.of(P2.class))) | |
| .isFalse(); | |
| } | |
| @Test | |
| public void starlarkProvidersAllMatch() { | |
| AdvertisedProviderSet providerSet = | |
| AdvertisedProviderSet.builder() | |
| .addStarlark(ID_LEGACY) | |
| .addStarlark(ID_NATIVE) | |
| .addStarlark(ID_STARLARK) | |
| .build(); | |
| assertThat( | |
| validateStarlark( | |
| providerSet, | |
| NO_PROVIDERS_REQUIRED, | |
| ImmutableSet.of(ID_LEGACY, ID_STARLARK, ID_NATIVE))) | |
| .isTrue(); | |
| } | |
| @Test | |
| public void starlarkProvidersBranchMatch() { | |
| assertThat( | |
| validateStarlark( | |
| AdvertisedProviderSet.builder().addStarlark(ID_LEGACY).build(), | |
| NO_PROVIDERS_REQUIRED, | |
| ImmutableSet.of(ID_LEGACY), | |
| ImmutableSet.of(ID_NATIVE))) | |
| .isTrue(); | |
| } | |
| @Test | |
| public void starlarkProvidersNoMatch() { | |
| assertThat( | |
| validateStarlark( | |
| AdvertisedProviderSet.builder().addStarlark(ID_STARLARK).build(), | |
| "'p_legacy' or 'p_native'", | |
| ImmutableSet.of(ID_LEGACY), | |
| ImmutableSet.of(ID_NATIVE))) | |
| .isFalse(); | |
| } | |
| @Test | |
| public void checkDescriptions() { | |
| assertThat(RequiredProviders.acceptAnyBuilder().build().getDescription()) | |
| .isEqualTo("no providers required"); | |
| assertThat(RequiredProviders.acceptNoneBuilder().build().getDescription()) | |
| .isEqualTo("no providers accepted"); | |
| assertThat( | |
| RequiredProviders.acceptAnyBuilder() | |
| .addStarlarkSet(ImmutableSet.of(ID_LEGACY, ID_STARLARK)) | |
| .addStarlarkSet(ImmutableSet.of(ID_STARLARK)) | |
| .addBuiltinSet(ImmutableSet.of(P1.class, P2.class)) | |
| .build() | |
| .getDescription()) | |
| .isEqualTo("[P1, P2] or ['p_legacy', 'p_starlark'] or 'p_starlark'"); | |
| } | |
| @SafeVarargs | |
| private static boolean validateNative( | |
| AdvertisedProviderSet providerSet, | |
| String missing, | |
| ImmutableSet<Class<? extends TransitiveInfoProvider>>... sets) { | |
| RequiredProviders.Builder anyBuilder = RequiredProviders.acceptAnyBuilder(); | |
| RequiredProviders.Builder noneBuilder = RequiredProviders.acceptNoneBuilder(); | |
| for (ImmutableSet<Class<? extends TransitiveInfoProvider>> set : sets) { | |
| anyBuilder.addBuiltinSet(set); | |
| noneBuilder.addBuiltinSet(set); | |
| } | |
| RequiredProviders rpStartingFromAny = anyBuilder.build(); | |
| boolean result = satisfies(providerSet, rpStartingFromAny); | |
| assertThat(rpStartingFromAny.getMissing(providerSet).getDescription()).isEqualTo(missing); | |
| RequiredProviders rpStaringFromNone = noneBuilder.build(); | |
| assertThat(satisfies(providerSet, rpStaringFromNone)).isEqualTo(result); | |
| assertThat(rpStaringFromNone.getMissing(providerSet).getDescription()).isEqualTo(missing); | |
| return result; | |
| } | |
| @SafeVarargs | |
| private static boolean validateStarlark( | |
| AdvertisedProviderSet providerSet, | |
| String missing, | |
| ImmutableSet<StarlarkProviderIdentifier>... sets) { | |
| RequiredProviders.Builder anyBuilder = RequiredProviders.acceptAnyBuilder(); | |
| RequiredProviders.Builder noneBuilder = RequiredProviders.acceptNoneBuilder(); | |
| for (ImmutableSet<StarlarkProviderIdentifier> set : sets) { | |
| anyBuilder.addStarlarkSet(set); | |
| noneBuilder.addStarlarkSet(set); | |
| } | |
| RequiredProviders rpStartingFromAny = anyBuilder.build(); | |
| boolean result = satisfies(providerSet, rpStartingFromAny); | |
| assertThat(rpStartingFromAny.getMissing(providerSet).getDescription()).isEqualTo(missing); | |
| RequiredProviders rpStaringFromNone = noneBuilder.build(); | |
| assertThat(satisfies(providerSet, rpStaringFromNone)).isEqualTo(result); | |
| assertThat(rpStaringFromNone.getMissing(providerSet).getDescription()).isEqualTo(missing); | |
| return result; | |
| } | |
| } |