aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java
diff options
context:
space:
mode:
authorGravatar Benjamin Peterson <bp@benjamin.pe>2017-11-27 03:14:43 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-27 03:16:07 -0800
commit8610d97d2b68cfbcf6b7de4441665a64f378eb9c (patch)
tree15a4967abd18a1963fa147fcbd462ca74155085d /src/test/java
parent9fea5b89a5cf8744dbe32aff279a9e2c2613c9d8 (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.java124
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java33
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)"