diff options
author | Benjamin Peterson <bp@benjamin.pe> | 2017-11-27 03:14:43 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2017-11-27 03:16:07 -0800 |
commit | 8610d97d2b68cfbcf6b7de4441665a64f378eb9c (patch) | |
tree | 15a4967abd18a1963fa147fcbd462ca74155085d /src/test/java | |
parent | 9fea5b89a5cf8744dbe32aff279a9e2c2613c9d8 (diff) |
Shape sharing for Skylark providers.
Add CompactSkylarkInfo, which stores its values as an array instead of
a map. The space savings will probably not be dramatic because
providers usually have a limited amount of keys. But, there are a lot
of them!
Change-Id: Idd452a5e3982f773b1c5202c73f3d7031ec022c6
PiperOrigin-RevId: 176995376
Diffstat (limited to 'src/test/java')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/packages/SkylarkInfoTest.java | 124 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java | 33 |
2 files changed, 157 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkInfoTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkInfoTest.java new file mode 100644 index 0000000000..a0d546f4fb --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkInfoTest.java @@ -0,0 +1,124 @@ +// Copyright 2017 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.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.testing.EqualsTester; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.packages.SkylarkInfo.CompactSkylarkInfo; +import com.google.devtools.build.lib.packages.SkylarkInfo.MapBackedSkylarkInfo; +import com.google.devtools.build.lib.syntax.Concatable; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Test class for {@link SkylarkInfo} and its subclasses. */ +@RunWith(JUnit4.class) +public class SkylarkInfoTest { + + @Test + public void sameProviderDifferentLayoutConcatenation() throws Exception { + SkylarkProvider provider = + new SkylarkProvider("provider", ImmutableList.of("f1", "f2"), Location.BUILTIN); + ImmutableMap<String, Integer> layout1 = ImmutableMap.of("f1", 0, "f2", 1); + ImmutableMap<String, Integer> layout2 = ImmutableMap.of("f1", 1, "f2", 0); + CompactSkylarkInfo info1 = + new CompactSkylarkInfo(provider, layout1, new Object[] {5, null}, Location.BUILTIN); + CompactSkylarkInfo info2 = + new CompactSkylarkInfo(provider, layout2, new Object[] {4, null}, Location.BUILTIN); + SkylarkInfo result = (SkylarkInfo) info1.getConcatter().concat(info1, info2, Location.BUILTIN); + assertThat(result).isInstanceOf(MapBackedSkylarkInfo.class); + assertThat(result.getValue("f1")).isEqualTo(5); + assertThat(result.getValue("f2")).isEqualTo(4); + } + + @Test + public void immutabilityPredicate() throws Exception { + SkylarkProvider provider = + new SkylarkProvider("provider", ImmutableList.of("f1", "f2"), Location.BUILTIN); + ImmutableMap<String, Integer> layout = ImmutableMap.of("f1", 0, "f2", 1); + SkylarkInfo compactInfo = + new CompactSkylarkInfo(provider, layout, new Object[] {5, null}, Location.BUILTIN); + assertThat(compactInfo.isImmutable()).isFalse(); + SkylarkInfo mapInfo = + new MapBackedSkylarkInfo(provider, ImmutableMap.of("f1", 5), Location.BUILTIN); + assertThat(mapInfo.isImmutable()).isFalse(); + provider.export(Label.create("package", "target"), "provider"); + assertThat(compactInfo.isImmutable()).isTrue(); + assertThat(mapInfo.isImmutable()).isTrue(); + compactInfo = + new CompactSkylarkInfo(provider, layout, new Object[] {5, new Object()}, Location.BUILTIN); + assertThat(compactInfo.isImmutable()).isFalse(); + mapInfo = + new MapBackedSkylarkInfo( + provider, ImmutableMap.of("f1", 5, "f2", new Object()), Location.BUILTIN); + assertThat(mapInfo.isImmutable()).isFalse(); + } + + @Test + public void equality() throws Exception { + Provider provider1 = + new SkylarkProvider("provider1", ImmutableList.of("f1", "f2"), Location.BUILTIN); + Provider provider2 = + new SkylarkProvider("provider2", ImmutableList.of("f1", "f2"), Location.BUILTIN); + ImmutableMap<String, Integer> layout = ImmutableMap.of("f1", 0, "f2", 1); + new EqualsTester() + .addEqualityGroup( + new CompactSkylarkInfo(provider1, layout, new Object[] {4, null}, Location.BUILTIN), + new MapBackedSkylarkInfo(provider1, ImmutableMap.of("f1", 4), Location.BUILTIN)) + .addEqualityGroup( + new CompactSkylarkInfo(provider2, layout, new Object[] {4, null}, Location.BUILTIN), + new MapBackedSkylarkInfo(provider2, ImmutableMap.of("f1", 4), Location.BUILTIN)) + .addEqualityGroup( + new CompactSkylarkInfo(provider1, layout, new Object[] {4, 5}, Location.BUILTIN), + new MapBackedSkylarkInfo( + provider1, ImmutableMap.of("f1", 4, "f2", 5), Location.BUILTIN)) + .testEquals(); + } + + @Test + public void heterogeneousConcatenation() throws Exception { + Provider provider = + new SkylarkProvider("provider", ImmutableList.of("f1", "f2"), Location.BUILTIN); + ImmutableMap<String, Integer> layout = ImmutableMap.of("f1", 0, "f2", 1); + SkylarkInfo p1 = new MapBackedSkylarkInfo(provider, ImmutableMap.of("f1", 4), Location.BUILTIN); + CompactSkylarkInfo p2 = + new CompactSkylarkInfo(provider, layout, new Object[] {null, 5}, Location.BUILTIN); + Concatable result = p1.getConcatter().concat(p1, p2, Location.BUILTIN); + assertThat(result).isInstanceOf(MapBackedSkylarkInfo.class); + assertThat(((SkylarkInfo) result).getKeys()).containsExactly("f1", "f2"); + assertThat(((SkylarkInfo) result).getValue("f1")).isEqualTo(4); + assertThat(((SkylarkInfo) result).getValue("f2")).isEqualTo(5); + } + + @Test + public void compactConcatenationReturnsCompact() throws Exception { + Provider provider = + new SkylarkProvider("provider", ImmutableList.of("f1", "f2"), Location.BUILTIN); + ImmutableMap<String, Integer> layout = ImmutableMap.of("f1", 0, "f2", 1); + CompactSkylarkInfo p1 = + new CompactSkylarkInfo(provider, layout, new Object[] {4, null}, Location.BUILTIN); + CompactSkylarkInfo p2 = + new CompactSkylarkInfo(provider, layout, new Object[] {null, 5}, Location.BUILTIN); + Concatable result = p1.getConcatter().concat(p1, p2, Location.BUILTIN); + assertThat(result).isInstanceOf(CompactSkylarkInfo.class); + assertThat(((CompactSkylarkInfo) result).getKeys()).containsExactly("f1", "f2"); + assertThat(((CompactSkylarkInfo) result).getValue("f1")).isEqualTo(4); + assertThat(((CompactSkylarkInfo) result).getValue("f2")).isEqualTo(5); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java index bbf3c5b09c..ccf7309412 100644 --- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java +++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java @@ -1265,6 +1265,39 @@ public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase { } @Test + public void declaredProvidersWithFieldsConcatSuccess() throws Exception { + evalAndExport( + "data = provider(fields=['f1', 'f2'])", + "d1 = data(f1 = 4)", + "d2 = data(f2 = 5)", + "d3 = d1 + d2", + "f1 = d3.f1", + "f2 = d3.f2"); + assertThat(lookup("f1")).isEqualTo(4); + assertThat(lookup("f2")).isEqualTo(5); + } + + @Test + public void declaredProvidersWithFieldsConcatError() throws Exception { + evalAndExport("data1 = provider(fields=['f1', 'f2'])", "data2 = provider(fields=['f3'])"); + checkEvalError( + "Cannot concat data1 with data2", + "d1 = data1(f1=1, f2=2)", + "d2 = data2(f3=3)", + "d = d1 + d2"); + } + + @Test + public void declaredProvidersWithOverlappingFieldsConcatError() throws Exception { + evalAndExport("data = provider(fields=['f1', 'f2'])"); + checkEvalError( + "Cannot concat structs with common field(s): f1", + "d1 = data(f1 = 4)", + "d2 = data(f1 = 5)", + "d1 + d2"); + } + + @Test public void structsAsDeclaredProvidersTest() throws Exception { evalAndExport( "data = struct(x = 1)" |