// Copyright 2015 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.analysis; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.testing.EqualsTester; import com.google.common.testing.NullPointerTester; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.analysis.config.transitions.NoTransition; import com.google.devtools.build.lib.analysis.util.AnalysisTestCase; import com.google.devtools.build.lib.analysis.util.TestAspects; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.AspectDescriptor; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for {@link Dependency}. * *

Although this is just a data class, we need a way to create a configuration. */ @RunWith(JUnit4.class) public class DependencyTest extends AnalysisTestCase { @Test public void withNullConfiguration_BasicAccessors() throws Exception { Dependency nullDep = Dependency.withNullConfiguration(Label.parseAbsolute("//a", ImmutableMap.of())); assertThat(nullDep.getLabel()).isEqualTo(Label.parseAbsolute("//a", ImmutableMap.of())); assertThat(nullDep.hasExplicitConfiguration()).isTrue(); assertThat(nullDep.getConfiguration()).isNull(); assertThat(nullDep.getAspects().getAllAspects()).isEmpty(); try { nullDep.getTransition(); fail("withNullConfiguration-created Dependencies should throw ISE on getTransition()"); } catch (IllegalStateException ex) { // good. expected. } } @Test public void withConfiguration_BasicAccessors() throws Exception { update(); Dependency targetDep = Dependency.withConfiguration( Label.parseAbsolute("//a", ImmutableMap.of()), getTargetConfiguration()); assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a", ImmutableMap.of())); assertThat(targetDep.hasExplicitConfiguration()).isTrue(); assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration()); assertThat(targetDep.getAspects().getAllAspects()).isEmpty(); try { targetDep.getTransition(); fail("withConfiguration-created Dependencies should throw ISE on getTransition()"); } catch (IllegalStateException ex) { // good. expected. } } @Test public void withConfigurationAndAspects_BasicAccessors() throws Exception { update(); AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT); AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT); AspectCollection twoAspects = AspectCollection.createForTests( ImmutableSet.of(simpleAspect, attributeAspect)); Dependency targetDep = Dependency.withConfigurationAndAspects( Label.parseAbsolute("//a", ImmutableMap.of()), getTargetConfiguration(), twoAspects); assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a", ImmutableMap.of())); assertThat(targetDep.hasExplicitConfiguration()).isTrue(); assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration()); assertThat(targetDep.getAspects()).isEqualTo(twoAspects); assertThat(targetDep.getAspectConfiguration(simpleAspect)).isEqualTo(getTargetConfiguration()); assertThat(targetDep.getAspectConfiguration(attributeAspect)) .isEqualTo(getTargetConfiguration()); try { targetDep.getTransition(); fail("withConfigurationAndAspects-created Dependencies should throw ISE on getTransition()"); } catch (IllegalStateException ex) { // good. that's what I WANTED to happen. } } @Test public void withConfigurationAndAspects_RejectsNullConfigWithNPE() throws Exception { // Although the NullPointerTester should check this, this test invokes a different code path, // because it includes aspects (which the NPT test will not). AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT); AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT); AspectCollection twoAspects = AspectCollection.createForTests(simpleAspect, attributeAspect); try { Dependency.withConfigurationAndAspects( Label.parseAbsolute("//a", ImmutableMap.of()), null, twoAspects); fail("should not be allowed to create a dependency with a null configuration"); } catch (NullPointerException expected) { // good. you fell rrrrright into my trap. } } @Test public void withConfigurationAndAspects_AllowsEmptyAspectSet() throws Exception { update(); Dependency dep = Dependency.withConfigurationAndAspects( Label.parseAbsolute("//a", ImmutableMap.of()), getTargetConfiguration(), AspectCollection.EMPTY); // Here we're also checking that this doesn't throw an exception. No boom? OK. Good. assertThat(dep.getAspects().getAllAspects()).isEmpty(); } @Test public void withConfiguredAspects_BasicAccessors() throws Exception { update(); AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT); AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT); AspectCollection aspects = AspectCollection.createForTests(ImmutableSet.of(simpleAspect, attributeAspect)); ImmutableMap twoAspectMap = ImmutableMap.of( simpleAspect, getTargetConfiguration(), attributeAspect, getHostConfiguration()); Dependency targetDep = Dependency.withConfiguredAspects( Label.parseAbsolute("//a", ImmutableMap.of()), getTargetConfiguration(), aspects, twoAspectMap); assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a", ImmutableMap.of())); assertThat(targetDep.hasExplicitConfiguration()).isTrue(); assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration()); assertThat(targetDep.getAspects().getAllAspects()) .containsExactly(simpleAspect, attributeAspect); assertThat(targetDep.getAspectConfiguration(simpleAspect)).isEqualTo(getTargetConfiguration()); assertThat(targetDep.getAspectConfiguration(attributeAspect)) .isEqualTo(getHostConfiguration()); try { targetDep.getTransition(); fail("withConfiguredAspects-created Dependencies should throw ISE on getTransition()"); } catch (IllegalStateException ex) { // good. all according to keikaku. (TL note: keikaku means plan) } } @Test public void withConfiguredAspects_AllowsEmptyAspectMap() throws Exception { update(); Dependency dep = Dependency.withConfiguredAspects( Label.parseAbsolute("//a", ImmutableMap.of()), getTargetConfiguration(), AspectCollection.EMPTY, ImmutableMap.of()); // Here we're also checking that this doesn't throw an exception. No boom? OK. Good. assertThat(dep.getAspects().getAllAspects()).isEmpty(); } @Test public void withTransitionAndAspects_BasicAccessors() throws Exception { AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT); AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT); AspectCollection twoAspects = AspectCollection.createForTests( ImmutableSet.of(simpleAspect, attributeAspect)); Dependency hostDep = Dependency.withTransitionAndAspects( Label.parseAbsolute("//a", ImmutableMap.of()), HostTransition.INSTANCE, twoAspects); assertThat(hostDep.getLabel()).isEqualTo(Label.parseAbsolute("//a", ImmutableMap.of())); assertThat(hostDep.hasExplicitConfiguration()).isFalse(); assertThat(hostDep.getAspects().getAllAspects()) .containsExactlyElementsIn(twoAspects.getAllAspects()); assertThat(hostDep.getTransition().isHostTransition()).isTrue(); try { hostDep.getConfiguration(); fail("withTransitionAndAspects-created Dependencies should throw ISE on getConfiguration()"); } catch (IllegalStateException ex) { // good. I knew you would do that. } try { hostDep.getAspectConfiguration(simpleAspect); fail("withTransitionAndAspects-created Dependencies should throw ISE on " + "getAspectConfiguration()"); } catch (IllegalStateException ex) { // good. you're so predictable. } try { hostDep.getAspectConfiguration(attributeAspect); fail("withTransitionAndAspects-created Dependencies should throw ISE on " + "getAspectConfiguration()"); } catch (IllegalStateException ex) { // good. you're so predictable. } } @Test public void withTransitionAndAspects_AllowsEmptyAspectSet() throws Exception { update(); Dependency dep = Dependency.withTransitionAndAspects( Label.parseAbsolute("//a", ImmutableMap.of()), HostTransition.INSTANCE, AspectCollection.EMPTY); // Here we're also checking that this doesn't throw an exception. No boom? OK. Good. assertThat(dep.getAspects().getAllAspects()).isEmpty(); } @Test public void factoriesPassNullableTester() throws Exception { update(); new NullPointerTester() .setDefault(Label.class, Label.parseAbsolute("//a", ImmutableMap.of())) .setDefault(BuildConfiguration.class, getTargetConfiguration()) .testAllPublicStaticMethods(Dependency.class); } @Test public void equalsPassesEqualsTester() throws Exception { update(); Label a = Label.parseAbsolute("//a", ImmutableMap.of()); Label aExplicit = Label.parseAbsolute("//a:a", ImmutableMap.of()); Label b = Label.parseAbsolute("//b", ImmutableMap.of()); BuildConfiguration host = getHostConfiguration(); BuildConfiguration target = getTargetConfiguration(); AspectDescriptor simpleAspect = new AspectDescriptor(TestAspects.SIMPLE_ASPECT); AspectDescriptor attributeAspect = new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT); AspectDescriptor errorAspect = new AspectDescriptor(TestAspects.ERROR_ASPECT); AspectCollection twoAspects = AspectCollection.createForTests(simpleAspect, attributeAspect); AspectCollection inverseAspects = AspectCollection.createForTests(attributeAspect, simpleAspect); AspectCollection differentAspects = AspectCollection.createForTests(attributeAspect, errorAspect); AspectCollection noAspects = AspectCollection.EMPTY; ImmutableMap twoAspectsHostMap = ImmutableMap.of(simpleAspect, host, attributeAspect, host); ImmutableMap twoAspectsTargetMap = ImmutableMap.of(simpleAspect, target, attributeAspect, target); ImmutableMap differentAspectsHostMap = ImmutableMap.of(attributeAspect, host, errorAspect, host); ImmutableMap differentAspectsTargetMap = ImmutableMap.of(attributeAspect, target, errorAspect, target); ImmutableMap noAspectsMap = ImmutableMap.of(); new EqualsTester() .addEqualityGroup( // base set: //a, host configuration, normal aspect set Dependency.withConfigurationAndAspects(a, host, twoAspects), Dependency.withConfigurationAndAspects(aExplicit, host, twoAspects), Dependency.withConfigurationAndAspects(a, host, inverseAspects), Dependency.withConfigurationAndAspects(aExplicit, host, inverseAspects), Dependency.withConfiguredAspects(a, host, twoAspects, twoAspectsHostMap), Dependency.withConfiguredAspects(aExplicit, host, twoAspects, twoAspectsHostMap)) .addEqualityGroup( // base set but with label //b Dependency.withConfigurationAndAspects(b, host, twoAspects), Dependency.withConfigurationAndAspects(b, host, inverseAspects), Dependency.withConfiguredAspects(b, host, twoAspects, twoAspectsHostMap)) .addEqualityGroup( // base set but with target configuration Dependency.withConfigurationAndAspects(a, target, twoAspects), Dependency.withConfigurationAndAspects(aExplicit, target, twoAspects), Dependency.withConfigurationAndAspects(a, target, inverseAspects), Dependency.withConfigurationAndAspects(aExplicit, target, inverseAspects), Dependency.withConfiguredAspects(a, target, twoAspects, twoAspectsTargetMap), Dependency.withConfiguredAspects(aExplicit, target, twoAspects, twoAspectsTargetMap)) .addEqualityGroup( // base set but with null configuration Dependency.withNullConfiguration(a), Dependency.withNullConfiguration(aExplicit)) .addEqualityGroup( // base set but with different aspects Dependency.withConfigurationAndAspects(a, host, differentAspects), Dependency.withConfigurationAndAspects(aExplicit, host, differentAspects), Dependency.withConfiguredAspects( a, host, differentAspects, differentAspectsHostMap), Dependency.withConfiguredAspects( aExplicit, host, differentAspects, differentAspectsHostMap)) .addEqualityGroup( // base set but with label //b and target configuration Dependency.withConfigurationAndAspects(b, target, twoAspects), Dependency.withConfigurationAndAspects(b, target, inverseAspects), Dependency.withConfiguredAspects(b, target, twoAspects, twoAspectsTargetMap)) .addEqualityGroup( // base set but with label //b and null configuration Dependency.withNullConfiguration(b)) .addEqualityGroup( // base set but with label //b and different aspects Dependency.withConfigurationAndAspects(b, host, differentAspects), Dependency.withConfiguredAspects( b, host, differentAspects, differentAspectsHostMap)) .addEqualityGroup( // base set but with target configuration and different aspects Dependency.withConfigurationAndAspects(a, target, differentAspects), Dependency.withConfigurationAndAspects(aExplicit, target, differentAspects), Dependency.withConfiguredAspects( a, target, differentAspects, differentAspectsTargetMap), Dependency.withConfiguredAspects( aExplicit, target, differentAspects, differentAspectsTargetMap)) .addEqualityGroup( // inverse of base set: //b, target configuration, different aspects Dependency.withConfigurationAndAspects(b, target, differentAspects), Dependency.withConfiguredAspects( b, target, differentAspects, differentAspectsTargetMap)) .addEqualityGroup( // base set but with no aspects Dependency.withConfiguration(a, host), Dependency.withConfiguration(aExplicit, host), Dependency.withConfigurationAndAspects(a, host, noAspects), Dependency.withConfigurationAndAspects(aExplicit, host, noAspects), Dependency.withConfiguredAspects(a, host, noAspects, noAspectsMap), Dependency.withConfiguredAspects(aExplicit, host, noAspects, noAspectsMap)) .addEqualityGroup( // base set but with label //b and no aspects Dependency.withConfiguration(b, host), Dependency.withConfigurationAndAspects(b, host, noAspects), Dependency.withConfiguredAspects(b, host, noAspects, noAspectsMap)) .addEqualityGroup( // base set but with target configuration and no aspects Dependency.withConfiguration(a, target), Dependency.withConfiguration(aExplicit, target), Dependency.withConfigurationAndAspects(a, target, noAspects), Dependency.withConfigurationAndAspects(aExplicit, target, noAspects), Dependency.withConfiguredAspects(a, target, noAspects, noAspectsMap), Dependency.withConfiguredAspects(aExplicit, target, noAspects, noAspectsMap)) .addEqualityGroup( // inverse of base set: //b, target configuration, no aspects Dependency.withConfiguration(b, target), Dependency.withConfigurationAndAspects(b, target, noAspects), Dependency.withConfiguredAspects(b, target, noAspects, noAspectsMap)) .addEqualityGroup( // base set but with transition HOST Dependency.withTransitionAndAspects(a, HostTransition.INSTANCE, twoAspects), Dependency.withTransitionAndAspects( aExplicit, HostTransition.INSTANCE, twoAspects), Dependency.withTransitionAndAspects(a, HostTransition.INSTANCE, inverseAspects), Dependency.withTransitionAndAspects( aExplicit, HostTransition.INSTANCE, inverseAspects)) .addEqualityGroup( // base set but with transition HOST and different aspects Dependency.withTransitionAndAspects(a, HostTransition.INSTANCE, differentAspects), Dependency.withTransitionAndAspects( aExplicit, HostTransition.INSTANCE, differentAspects)) .addEqualityGroup( // base set but with transition HOST and label //b Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, twoAspects), Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, inverseAspects)) .addEqualityGroup( // inverse of base set: transition HOST, label //b, different aspects Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, differentAspects), Dependency.withTransitionAndAspects(b, HostTransition.INSTANCE, differentAspects)) .addEqualityGroup( // base set but with transition NONE Dependency.withTransitionAndAspects(a, NoTransition.INSTANCE, twoAspects), Dependency.withTransitionAndAspects(aExplicit, NoTransition.INSTANCE, twoAspects), Dependency.withTransitionAndAspects(a, NoTransition.INSTANCE, inverseAspects), Dependency.withTransitionAndAspects(aExplicit, NoTransition.INSTANCE, inverseAspects)) .addEqualityGroup( // base set but with transition NONE and different aspects Dependency.withTransitionAndAspects(a, NoTransition.INSTANCE, differentAspects), Dependency.withTransitionAndAspects(aExplicit, NoTransition.INSTANCE, differentAspects)) .addEqualityGroup( // base set but with transition NONE and label //b Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, twoAspects), Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, inverseAspects)) .addEqualityGroup( // inverse of base set: transition NONE, label //b, different aspects Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, differentAspects), Dependency.withTransitionAndAspects(b, NoTransition.INSTANCE, differentAspects)) .testEquals(); } }