// 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.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 com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for {@link Dependency}. * * <p>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")); assertThat(nullDep.getLabel()).isEqualTo(Label.parseAbsolute("//a")); assertThat(nullDep.hasStaticConfiguration()).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"), getTargetConfiguration()); assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a")); assertThat(targetDep.hasStaticConfiguration()).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"), getTargetConfiguration(), twoAspects); assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a")); assertThat(targetDep.hasStaticConfiguration()).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"), 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"), 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<AspectDescriptor, BuildConfiguration> twoAspectMap = ImmutableMap.of( simpleAspect, getTargetConfiguration(), attributeAspect, getHostConfiguration()); Dependency targetDep = Dependency.withConfiguredAspects( Label.parseAbsolute("//a"), getTargetConfiguration(), aspects, twoAspectMap); assertThat(targetDep.getLabel()).isEqualTo(Label.parseAbsolute("//a")); assertThat(targetDep.hasStaticConfiguration()).isTrue(); assertThat(targetDep.getConfiguration()).isEqualTo(getTargetConfiguration()); assertThat(targetDep.getAspects().getAllAspects()) .containsExactlyElementsIn(ImmutableSet.of(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"), getTargetConfiguration(), AspectCollection.EMPTY, ImmutableMap.<AspectDescriptor, BuildConfiguration>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"), ConfigurationTransition.HOST, twoAspects); assertThat(hostDep.getLabel()).isEqualTo(Label.parseAbsolute("//a")); assertThat(hostDep.hasStaticConfiguration()).isFalse(); assertThat(hostDep.getAspects().getAllAspects()) .containsExactlyElementsIn(twoAspects.getAllAspects()); assertThat(hostDep.getTransition()).isEqualTo(ConfigurationTransition.HOST); 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"), ConfigurationTransition.HOST, 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")) .setDefault(BuildConfiguration.class, getTargetConfiguration()) .testAllPublicStaticMethods(Dependency.class); } @Test public void equalsPassesEqualsTester() throws Exception { update(); Label a = Label.parseAbsolute("//a"); Label aExplicit = Label.parseAbsolute("//a:a"); Label b = Label.parseAbsolute("//b"); 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<AspectDescriptor, BuildConfiguration> twoAspectsHostMap = ImmutableMap.of(simpleAspect, host, attributeAspect, host); ImmutableMap<AspectDescriptor, BuildConfiguration> twoAspectsTargetMap = ImmutableMap.of(simpleAspect, target, attributeAspect, target); ImmutableMap<AspectDescriptor, BuildConfiguration> differentAspectsHostMap = ImmutableMap.of(attributeAspect, host, errorAspect, host); ImmutableMap<AspectDescriptor, BuildConfiguration> differentAspectsTargetMap = ImmutableMap.of(attributeAspect, target, errorAspect, target); ImmutableMap<AspectDescriptor, BuildConfiguration> noAspectsMap = ImmutableMap.<AspectDescriptor, BuildConfiguration>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, ConfigurationTransition.HOST, twoAspects), Dependency.withTransitionAndAspects( aExplicit, ConfigurationTransition.HOST, twoAspects), Dependency.withTransitionAndAspects(a, ConfigurationTransition.HOST, inverseAspects), Dependency.withTransitionAndAspects( aExplicit, ConfigurationTransition.HOST, inverseAspects)) .addEqualityGroup( // base set but with transition HOST and different aspects Dependency.withTransitionAndAspects(a, ConfigurationTransition.HOST, differentAspects), Dependency.withTransitionAndAspects( aExplicit, ConfigurationTransition.HOST, differentAspects)) .addEqualityGroup( // base set but with transition HOST and label //b Dependency.withTransitionAndAspects(b, ConfigurationTransition.HOST, twoAspects), Dependency.withTransitionAndAspects(b, ConfigurationTransition.HOST, inverseAspects)) .addEqualityGroup( // inverse of base set: transition HOST, label //b, different aspects Dependency.withTransitionAndAspects(b, ConfigurationTransition.HOST, differentAspects), Dependency.withTransitionAndAspects(b, ConfigurationTransition.HOST, differentAspects)) .addEqualityGroup( // base set but with transition NONE Dependency.withTransitionAndAspects(a, ConfigurationTransition.NONE, twoAspects), Dependency.withTransitionAndAspects( aExplicit, ConfigurationTransition.NONE, twoAspects), Dependency.withTransitionAndAspects(a, ConfigurationTransition.NONE, inverseAspects), Dependency.withTransitionAndAspects( aExplicit, ConfigurationTransition.NONE, inverseAspects)) .addEqualityGroup( // base set but with transition NONE and different aspects Dependency.withTransitionAndAspects(a, ConfigurationTransition.NONE, differentAspects), Dependency.withTransitionAndAspects( aExplicit, ConfigurationTransition.NONE, differentAspects)) .addEqualityGroup( // base set but with transition NONE and label //b Dependency.withTransitionAndAspects(b, ConfigurationTransition.NONE, twoAspects), Dependency.withTransitionAndAspects(b, ConfigurationTransition.NONE, inverseAspects)) .addEqualityGroup( // inverse of base set: transition NONE, label //b, different aspects Dependency.withTransitionAndAspects(b, ConfigurationTransition.NONE, differentAspects), Dependency.withTransitionAndAspects(b, ConfigurationTransition.NONE, differentAspects)) .testEquals(); } }