Han-Wen Nienhuys | 3428dc9 | 2015-10-21 15:03:34 +0000 | [diff] [blame] | 1 | // Copyright 2015 The Bazel Authors. All rights reserved. |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | package com.google.devtools.build.lib.packages; |
| 15 | |
| 16 | import static com.google.common.truth.Truth.assertThat; |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 17 | import static com.google.devtools.build.lib.packages.Attribute.attr; |
Lukacs Berki | ffa73ad | 2015-09-18 11:40:12 +0000 | [diff] [blame] | 18 | import static com.google.devtools.build.lib.packages.BuildType.LABEL; |
| 19 | import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; |
Googler | c5fcc86 | 2019-09-06 16:17:47 -0700 | [diff] [blame] | 20 | import static com.google.devtools.build.lib.packages.Type.INTEGER; |
| 21 | import static com.google.devtools.build.lib.packages.Type.STRING; |
| 22 | import static com.google.devtools.build.lib.packages.Type.STRING_LIST; |
michajlo | 660d17f | 2020-03-27 09:01:57 -0700 | [diff] [blame] | 23 | import static org.junit.Assert.assertThrows; |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 24 | |
| 25 | import com.google.common.base.Predicates; |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 26 | import com.google.common.collect.ImmutableList; |
dannark | 90e2b4b | 2018-06-27 13:35:04 -0700 | [diff] [blame] | 27 | import com.google.common.collect.ImmutableMap; |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 28 | import com.google.common.collect.ImmutableSet; |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 29 | import com.google.devtools.build.lib.analysis.config.BuildOptions; |
gregce | a048f0f | 2020-06-11 15:10:01 -0700 | [diff] [blame] | 30 | import com.google.devtools.build.lib.analysis.config.BuildOptionsView; |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 31 | import com.google.devtools.build.lib.analysis.config.HostTransition; |
jcater | 98a09b6 | 2019-04-02 13:06:19 -0700 | [diff] [blame] | 32 | import com.google.devtools.build.lib.analysis.config.TransitionFactories; |
John Cater | 5adcd3e | 2019-03-28 10:14:32 -0700 | [diff] [blame] | 33 | import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition; |
gregce | 6bc35ed | 2017-12-22 11:51:39 -0800 | [diff] [blame] | 34 | import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; |
John Cater | 0a9e1ed | 2019-03-27 11:02:01 -0700 | [diff] [blame] | 35 | import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory; |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 36 | import com.google.devtools.build.lib.analysis.util.TestAspects; |
Lukacs Berki | 6e91eb9 | 2015-09-21 09:12:37 +0000 | [diff] [blame] | 37 | import com.google.devtools.build.lib.cmdline.Label; |
gregce | f0a40ac | 2020-03-31 14:11:30 -0700 | [diff] [blame] | 38 | import com.google.devtools.build.lib.events.EventHandler; |
Googler | 72f3a10 | 2017-12-01 16:28:28 -0800 | [diff] [blame] | 39 | import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassNamePredicate; |
John Cater | 0a9e1ed | 2019-03-27 11:02:01 -0700 | [diff] [blame] | 40 | import com.google.devtools.build.lib.testutil.FakeAttributeMapper; |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 41 | import com.google.devtools.build.lib.util.FileType; |
| 42 | import com.google.devtools.build.lib.util.FileTypeSet; |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 43 | import java.util.Arrays; |
| 44 | import java.util.Collections; |
| 45 | import java.util.List; |
Googler | 19226b7 | 2020-02-06 12:58:43 -0800 | [diff] [blame] | 46 | import java.util.Map; |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 47 | import net.starlark.java.eval.StarlarkInt; |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 48 | import org.junit.Test; |
| 49 | import org.junit.runner.RunWith; |
| 50 | import org.junit.runners.JUnit4; |
| 51 | |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 52 | /** Tests of Attribute code. */ |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 53 | @RunWith(JUnit4.class) |
| 54 | public class AttributeTest { |
| 55 | |
| 56 | private void assertDefaultValue(Object expected, Attribute attr) { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 57 | assertThat(attr.getDefaultValue(null)).isEqualTo(expected); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | private void assertType(Type<?> expectedType, Attribute attr) { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 61 | assertThat(attr.getType()).isEqualTo(expectedType); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | @Test |
| 65 | public void testBasics() throws Exception { |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 66 | Attribute attr = attr("foo", Type.INTEGER).mandatory().value(StarlarkInt.of(3)).build(); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 67 | assertThat(attr.getName()).isEqualTo("foo"); |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 68 | assertThat(attr.getDefaultValue(null)).isEqualTo(StarlarkInt.of(3)); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 69 | assertThat(attr.getType()).isEqualTo(Type.INTEGER); |
| 70 | assertThat(attr.isMandatory()).isTrue(); |
| 71 | assertThat(attr.isDocumented()).isTrue(); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 72 | attr = attr("$foo", Type.INTEGER).build(); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 73 | assertThat(attr.isDocumented()).isFalse(); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | @Test |
| 77 | public void testNonEmptyReqiresListType() throws Exception { |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 78 | NullPointerException e = |
| 79 | assertThrows( |
| 80 | NullPointerException.class, |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 81 | () -> attr("foo", Type.INTEGER).nonEmpty().value(StarlarkInt.of(3)).build()); |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 82 | assertThat(e).hasMessageThat().isEqualTo("attribute 'foo' must be a list"); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | @Test |
| 86 | public void testNonEmpty() throws Exception { |
Lukacs Berki | ffa73ad | 2015-09-18 11:40:12 +0000 | [diff] [blame] | 87 | Attribute attr = attr("foo", BuildType.LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build(); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 88 | assertThat(attr.getName()).isEqualTo("foo"); |
| 89 | assertThat(attr.getType()).isEqualTo(BuildType.LABEL_LIST); |
| 90 | assertThat(attr.isNonEmpty()).isTrue(); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | @Test |
| 94 | public void testSingleArtifactReqiresLabelType() throws Exception { |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 95 | IllegalStateException e = |
| 96 | assertThrows( |
| 97 | IllegalStateException.class, |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 98 | () -> attr("foo", Type.INTEGER).singleArtifact().value(StarlarkInt.of(3)).build()); |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 99 | assertThat(e).hasMessageThat().isEqualTo("attribute 'foo' must be a label-valued type"); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | @Test |
| 103 | public void testDoublePropertySet() { |
jcater | ffb65c8 | 2019-03-29 07:52:16 -0700 | [diff] [blame] | 104 | Attribute.Builder<String> builder = |
| 105 | attr("x", STRING) |
| 106 | .mandatory() |
| 107 | .cfg(HostTransition.createFactory()) |
| 108 | .undocumented("") |
| 109 | .value("y"); |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 110 | assertThrows(IllegalStateException.class, () -> builder.mandatory()); |
| 111 | assertThrows(IllegalStateException.class, () -> builder.cfg(HostTransition.createFactory())); |
| 112 | assertThrows(IllegalStateException.class, () -> builder.undocumented("")); |
| 113 | assertThrows(IllegalStateException.class, () -> builder.value("z")); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 114 | |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 115 | Attribute.Builder<String> builder2 = attr("$x", STRING); |
| 116 | assertThrows(IllegalStateException.class, () -> builder2.undocumented("")); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Tests the "convenience factories" (string, label, etc) for default |
| 121 | * values. |
| 122 | */ |
| 123 | @Test |
| 124 | public void testConvenienceFactoriesDefaultValues() throws Exception { |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 125 | assertDefaultValue(StarlarkInt.of(0), attr("x", INTEGER).build()); |
| 126 | assertDefaultValue(StarlarkInt.of(42), attr("x", INTEGER).value(StarlarkInt.of(42)).build()); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 127 | |
| 128 | assertDefaultValue("", |
| 129 | attr("x", STRING).build()); |
| 130 | assertDefaultValue("foo", |
| 131 | attr("x", STRING).value("foo").build()); |
| 132 | |
dannark | 90e2b4b | 2018-06-27 13:35:04 -0700 | [diff] [blame] | 133 | Label label = Label.parseAbsolute("//foo:bar", ImmutableMap.of()); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 134 | assertDefaultValue(null, |
| 135 | attr("x", LABEL).legacyAllowAnyFileType().build()); |
| 136 | assertDefaultValue(label, |
| 137 | attr("x", LABEL).legacyAllowAnyFileType().value(label).build()); |
| 138 | |
| 139 | List<String> slist = Arrays.asList("foo", "bar"); |
| 140 | assertDefaultValue(Collections.emptyList(), |
| 141 | attr("x", STRING_LIST).build()); |
| 142 | assertDefaultValue(slist, |
| 143 | attr("x", STRING_LIST).value(slist).build()); |
| 144 | |
dannark | 90e2b4b | 2018-06-27 13:35:04 -0700 | [diff] [blame] | 145 | List<Label> llist = |
| 146 | Arrays.asList( |
| 147 | Label.parseAbsolute("//foo:bar", ImmutableMap.of()), |
| 148 | Label.parseAbsolute("//foo:wiz", ImmutableMap.of())); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 149 | assertDefaultValue(Collections.emptyList(), |
| 150 | attr("x", LABEL_LIST).legacyAllowAnyFileType().build()); |
| 151 | assertDefaultValue(llist, |
| 152 | attr("x", LABEL_LIST).legacyAllowAnyFileType().value(llist).build()); |
| 153 | } |
| 154 | |
| 155 | /** |
| 156 | * Tests the "convenience factories" (string, label, etc) for types. |
| 157 | */ |
| 158 | @Test |
| 159 | public void testConvenienceFactoriesTypes() throws Exception { |
| 160 | assertType(INTEGER, |
| 161 | attr("x", INTEGER).build()); |
adonovan | 3ed7ed5 | 2020-09-30 12:03:28 -0700 | [diff] [blame] | 162 | assertType(INTEGER, attr("x", INTEGER).value(StarlarkInt.of(42)).build()); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 163 | |
| 164 | assertType(STRING, |
| 165 | attr("x", STRING).build()); |
| 166 | assertType(STRING, |
| 167 | attr("x", STRING).value("foo").build()); |
| 168 | |
dannark | 90e2b4b | 2018-06-27 13:35:04 -0700 | [diff] [blame] | 169 | Label label = Label.parseAbsolute("//foo:bar", ImmutableMap.of()); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 170 | assertType(LABEL, |
| 171 | attr("x", LABEL).legacyAllowAnyFileType().build()); |
| 172 | assertType(LABEL, |
| 173 | attr("x", LABEL).legacyAllowAnyFileType().value(label).build()); |
| 174 | |
| 175 | List<String> slist = Arrays.asList("foo", "bar"); |
| 176 | assertType(STRING_LIST, |
| 177 | attr("x", STRING_LIST).build()); |
| 178 | assertType(STRING_LIST, |
| 179 | attr("x", STRING_LIST).value(slist).build()); |
| 180 | |
dannark | 90e2b4b | 2018-06-27 13:35:04 -0700 | [diff] [blame] | 181 | List<Label> llist = |
| 182 | Arrays.asList( |
| 183 | Label.parseAbsolute("//foo:bar", ImmutableMap.of()), |
| 184 | Label.parseAbsolute("//foo:wiz", ImmutableMap.of())); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 185 | assertType(LABEL_LIST, |
| 186 | attr("x", LABEL_LIST).legacyAllowAnyFileType().build()); |
| 187 | assertType(LABEL_LIST, |
| 188 | attr("x", LABEL_LIST).legacyAllowAnyFileType().value(llist).build()); |
| 189 | } |
| 190 | |
| 191 | @Test |
| 192 | public void testCloneBuilder() { |
| 193 | FileTypeSet txtFiles = FileTypeSet.of(FileType.of("txt")); |
Googler | 72f3a10 | 2017-12-01 16:28:28 -0800 | [diff] [blame] | 194 | RuleClassNamePredicate ruleClasses = RuleClassNamePredicate.only("mock_rule"); |
Han-Wen Nienhuys | 3428dc9 | 2015-10-21 15:03:34 +0000 | [diff] [blame] | 195 | |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 196 | Attribute parentAttr = |
| 197 | attr("x", LABEL_LIST) |
| 198 | .allowedFileTypes(txtFiles) |
| 199 | .mandatory() |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 200 | .aspect(TestAspects.SIMPLE_ASPECT) |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 201 | .build(); |
Han-Wen Nienhuys | 3428dc9 | 2015-10-21 15:03:34 +0000 | [diff] [blame] | 202 | |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 203 | { |
| 204 | Attribute childAttr1 = parentAttr.cloneBuilder().build(); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 205 | assertThat(childAttr1.getName()).isEqualTo("x"); |
| 206 | assertThat(childAttr1.getAllowedFileTypesPredicate()).isEqualTo(txtFiles); |
| 207 | assertThat(childAttr1.getAllowedRuleClassesPredicate()).isEqualTo(Predicates.alwaysTrue()); |
| 208 | assertThat(childAttr1.isMandatory()).isTrue(); |
| 209 | assertThat(childAttr1.isNonEmpty()).isFalse(); |
cushon | 8c6b7ab | 2018-04-27 01:25:50 -0700 | [diff] [blame] | 210 | assertThat(childAttr1.getAspects(/* rule= */ null)).hasSize(1); |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 211 | } |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 212 | |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 213 | { |
| 214 | Attribute childAttr2 = |
| 215 | parentAttr |
| 216 | .cloneBuilder() |
| 217 | .nonEmpty() |
| 218 | .allowedRuleClasses(ruleClasses) |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 219 | .aspect(TestAspects.ERROR_ASPECT) |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 220 | .build(); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 221 | assertThat(childAttr2.getName()).isEqualTo("x"); |
| 222 | assertThat(childAttr2.getAllowedFileTypesPredicate()).isEqualTo(txtFiles); |
Googler | 72f3a10 | 2017-12-01 16:28:28 -0800 | [diff] [blame] | 223 | assertThat(childAttr2.getAllowedRuleClassesPredicate()) |
| 224 | .isEqualTo(ruleClasses.asPredicateOfRuleClass()); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 225 | assertThat(childAttr2.isMandatory()).isTrue(); |
| 226 | assertThat(childAttr2.isNonEmpty()).isTrue(); |
cushon | 8c6b7ab | 2018-04-27 01:25:50 -0700 | [diff] [blame] | 227 | assertThat(childAttr2.getAspects(/* rule= */ null)).hasSize(2); |
Carmi Grushko | 215fa84 | 2016-03-31 18:14:39 +0000 | [diff] [blame] | 228 | } |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 229 | |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 230 | // Check if the parent attribute is unchanged |
| 231 | assertThat(parentAttr.isNonEmpty()).isFalse(); |
| 232 | assertThat(parentAttr.getAllowedRuleClassesPredicate()).isEqualTo(Predicates.alwaysTrue()); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 233 | } |
| 234 | |
| 235 | /** |
| 236 | * Tests that configurability settings are properly received. |
| 237 | */ |
| 238 | @Test |
| 239 | public void testConfigurability() { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 240 | assertThat( |
| 241 | attr("foo_configurable", BuildType.LABEL_LIST) |
| 242 | .legacyAllowAnyFileType() |
| 243 | .build() |
| 244 | .isConfigurable()) |
| 245 | .isTrue(); |
| 246 | assertThat( |
| 247 | attr("foo_nonconfigurable", BuildType.LABEL_LIST) |
| 248 | .legacyAllowAnyFileType() |
| 249 | .nonconfigurable("test") |
| 250 | .build() |
| 251 | .isConfigurable()) |
| 252 | .isFalse(); |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 253 | } |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 254 | |
| 255 | @Test |
| 256 | public void testSplitTransition() throws Exception { |
| 257 | TestSplitTransition splitTransition = new TestSplitTransition(); |
jcater | 98a09b6 | 2019-04-02 13:06:19 -0700 | [diff] [blame] | 258 | Attribute attr = |
| 259 | attr("foo", LABEL).cfg(TransitionFactories.of(splitTransition)).allowedFileTypes().build(); |
jcater | e8f5a98 | 2019-04-02 11:12:19 -0700 | [diff] [blame] | 260 | assertThat(attr.getTransitionFactory().isSplit()).isTrue(); |
John Cater | 5adcd3e | 2019-03-28 10:14:32 -0700 | [diff] [blame] | 261 | ConfigurationTransition transition = |
John Cater | 2c0dece | 2019-04-02 09:18:18 -0700 | [diff] [blame] | 262 | attr.getTransitionFactory() |
jcater | 2358946 | 2019-05-20 08:51:24 -0700 | [diff] [blame] | 263 | .create( |
| 264 | AttributeTransitionData.builder().attributes(FakeAttributeMapper.empty()).build()); |
John Cater | 5adcd3e | 2019-03-28 10:14:32 -0700 | [diff] [blame] | 265 | assertThat(transition).isEqualTo(splitTransition); |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 266 | } |
| 267 | |
| 268 | @Test |
| 269 | public void testSplitTransitionProvider() throws Exception { |
| 270 | TestSplitTransitionProvider splitTransitionProvider = new TestSplitTransitionProvider(); |
| 271 | Attribute attr = |
| 272 | attr("foo", LABEL).cfg(splitTransitionProvider).allowedFileTypes().build(); |
jcater | e8f5a98 | 2019-04-02 11:12:19 -0700 | [diff] [blame] | 273 | assertThat(attr.getTransitionFactory().isSplit()).isTrue(); |
John Cater | 5adcd3e | 2019-03-28 10:14:32 -0700 | [diff] [blame] | 274 | ConfigurationTransition transition = |
John Cater | 2c0dece | 2019-04-02 09:18:18 -0700 | [diff] [blame] | 275 | attr.getTransitionFactory() |
jcater | 2358946 | 2019-05-20 08:51:24 -0700 | [diff] [blame] | 276 | .create( |
| 277 | AttributeTransitionData.builder().attributes(FakeAttributeMapper.empty()).build()); |
John Cater | 5adcd3e | 2019-03-28 10:14:32 -0700 | [diff] [blame] | 278 | assertThat(transition).isInstanceOf(TestSplitTransition.class); |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 279 | } |
| 280 | |
| 281 | @Test |
| 282 | public void testHostTransition() throws Exception { |
jcater | ffb65c8 | 2019-03-29 07:52:16 -0700 | [diff] [blame] | 283 | Attribute attr = |
| 284 | attr("foo", LABEL).cfg(HostTransition.createFactory()).allowedFileTypes().build(); |
jcater | b44167f | 2019-04-02 12:06:26 -0700 | [diff] [blame] | 285 | assertThat(attr.getTransitionFactory().isHost()).isTrue(); |
jcater | e8f5a98 | 2019-04-02 11:12:19 -0700 | [diff] [blame] | 286 | assertThat(attr.getTransitionFactory().isSplit()).isFalse(); |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 287 | } |
| 288 | |
gregce | 6bc35ed | 2017-12-22 11:51:39 -0800 | [diff] [blame] | 289 | private static class TestSplitTransition implements SplitTransition { |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 290 | @Override |
gregce | a048f0f | 2020-06-11 15:10:01 -0700 | [diff] [blame] | 291 | public Map<String, BuildOptions> split( |
| 292 | BuildOptionsView buildOptions, EventHandler eventHandler) { |
| 293 | return ImmutableMap.of( |
| 294 | "test0", buildOptions.clone().underlying(), "test1", buildOptions.clone().underlying()); |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 295 | } |
| 296 | } |
| 297 | |
John Cater | 0a9e1ed | 2019-03-27 11:02:01 -0700 | [diff] [blame] | 298 | private static class TestSplitTransitionProvider |
John Cater | 2c0dece | 2019-04-02 09:18:18 -0700 | [diff] [blame] | 299 | implements TransitionFactory<AttributeTransitionData> { |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 300 | @Override |
John Cater | 2c0dece | 2019-04-02 09:18:18 -0700 | [diff] [blame] | 301 | public SplitTransition create(AttributeTransitionData data) { |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 302 | return new TestSplitTransition(); |
| 303 | } |
cparsons | 21e2518 | 2019-01-15 16:00:26 -0800 | [diff] [blame] | 304 | |
| 305 | @Override |
John Cater | 0428828 | 2021-07-28 10:36:20 -0700 | [diff] [blame^] | 306 | public TransitionType transitionType() { |
| 307 | return TransitionType.ATTRIBUTE; |
| 308 | } |
| 309 | |
| 310 | @Override |
John Cater | 0a9e1ed | 2019-03-27 11:02:01 -0700 | [diff] [blame] | 311 | public boolean isSplit() { |
| 312 | return true; |
| 313 | } |
Chris Parsons | 2e62c0d | 2016-04-19 22:13:59 +0000 | [diff] [blame] | 314 | } |
gregce | da4c959 | 2017-07-27 22:09:34 +0200 | [diff] [blame] | 315 | |
| 316 | @Test |
| 317 | public void allowedRuleClassesAndAllowedRuleClassesWithWarningsCannotOverlap() throws Exception { |
jcater | b922677 | 2019-04-29 12:04:52 -0700 | [diff] [blame] | 318 | IllegalStateException e = |
| 319 | assertThrows( |
| 320 | IllegalStateException.class, |
| 321 | () -> |
| 322 | attr("x", LABEL_LIST) |
| 323 | .allowedRuleClasses("foo", "bar", "baz") |
| 324 | .allowedRuleClassesWithWarning("bar") |
| 325 | .allowedFileTypes() |
| 326 | .build()); |
| 327 | assertThat(e).hasMessageThat().contains("may not contain the same rule classes"); |
gregce | da4c959 | 2017-07-27 22:09:34 +0200 | [diff] [blame] | 328 | } |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 329 | |
| 330 | private static final Label FAKE_LABEL = Label.parseAbsoluteUnchecked("//fake/label.bzl"); |
| 331 | |
| 332 | private static final StarlarkProviderIdentifier STARLARK_P1 = |
| 333 | StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P1")); |
| 334 | |
| 335 | private static final StarlarkProviderIdentifier STARLARK_P2 = |
| 336 | StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P2")); |
| 337 | |
| 338 | private static final StarlarkProviderIdentifier STARLARK_P3 = |
| 339 | StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P3")); |
| 340 | |
| 341 | private static final StarlarkProviderIdentifier STARLARK_P4 = |
| 342 | StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, "STARLARK_P4")); |
| 343 | |
| 344 | @Test |
| 345 | public void testAttrRequiredAspects_inheritAttrAspects() throws Exception { |
| 346 | ImmutableList<String> inheritedAttributeAspects1 = ImmutableList.of("attr1", "attr2"); |
| 347 | ImmutableList<String> inheritedAttributeAspects2 = ImmutableList.of("attr3", "attr2"); |
| 348 | |
messa | 14694d1c | 2021-07-06 05:58:31 -0700 | [diff] [blame] | 349 | Attribute.Builder<Label> attrBuilder = attr("x", LABEL).allowedFileTypes(); |
| 350 | attrBuilder |
| 351 | .getAspectsListBuilder() |
| 352 | .addAspect( |
| 353 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 354 | "base_aspect_1", |
| 355 | /** inheritedRequiredProviders= */ |
| 356 | ImmutableList.of(), |
| 357 | inheritedAttributeAspects1); |
| 358 | attrBuilder |
| 359 | .getAspectsListBuilder() |
| 360 | .addAspect( |
| 361 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 362 | "base_aspect_2", |
| 363 | /** inheritedRequiredProviders= */ |
| 364 | ImmutableList.of(), |
| 365 | inheritedAttributeAspects2); |
| 366 | Attribute attr = attrBuilder.build(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 367 | |
| 368 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 369 | assertThat(aspects).hasSize(1); |
| 370 | AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor(); |
| 371 | assertThat(aspectDescriptor.getInheritedAttributeAspects()) |
| 372 | .containsExactly("attr1", "attr2", "attr3"); |
| 373 | } |
| 374 | |
| 375 | @Test |
| 376 | public void testAttrRequiredAspects_inheritRequiredProviders() throws Exception { |
| 377 | ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders1 = |
| 378 | ImmutableList.of(ImmutableSet.of(STARLARK_P1), ImmutableSet.of(STARLARK_P2, STARLARK_P3)); |
| 379 | ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders2 = |
| 380 | ImmutableList.of(ImmutableSet.of(STARLARK_P4), ImmutableSet.of(STARLARK_P2, STARLARK_P3)); |
| 381 | |
messa | 14694d1c | 2021-07-06 05:58:31 -0700 | [diff] [blame] | 382 | Attribute.Builder<Label> attrBuilder = attr("x", LABEL).allowedFileTypes(); |
| 383 | attrBuilder |
| 384 | .getAspectsListBuilder() |
| 385 | .addAspect( |
| 386 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 387 | "base_aspect_1", |
| 388 | inheritedRequiredProviders1, |
| 389 | /** inheritedAttributeAspects= */ |
| 390 | ImmutableList.of()); |
| 391 | attrBuilder |
| 392 | .getAspectsListBuilder() |
| 393 | .addAspect( |
| 394 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 395 | "base_aspect_2", |
| 396 | inheritedRequiredProviders2, |
| 397 | /** inheritedAttributeAspects= */ |
| 398 | ImmutableList.of()); |
| 399 | Attribute attr = attrBuilder.build(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 400 | |
| 401 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 402 | assertThat(aspects).hasSize(1); |
| 403 | |
| 404 | RequiredProviders actualInheritedRequiredProviders = |
| 405 | aspects.get(0).getDescriptor().getInheritedRequiredProviders(); |
| 406 | AdvertisedProviderSet expectedOkSet1 = |
| 407 | AdvertisedProviderSet.builder().addStarlark(STARLARK_P1).build(); |
| 408 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet1)).isTrue(); |
| 409 | |
| 410 | AdvertisedProviderSet expectedOkSet2 = |
| 411 | AdvertisedProviderSet.builder().addStarlark(STARLARK_P4).build(); |
| 412 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet2)).isTrue(); |
| 413 | |
| 414 | AdvertisedProviderSet expectedOkSet3 = |
| 415 | AdvertisedProviderSet.builder().addStarlark(STARLARK_P2).addStarlark(STARLARK_P3).build(); |
| 416 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet3)).isTrue(); |
| 417 | |
| 418 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue(); |
| 419 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)) |
| 420 | .isFalse(); |
| 421 | } |
| 422 | |
| 423 | @Test |
| 424 | public void testAttrRequiredAspects_aspectAlreadyExists_inheritAttrAspects() throws Exception { |
| 425 | ImmutableList<String> inheritedAttributeAspects = ImmutableList.of("attr1", "attr2"); |
| 426 | |
messa | 14694d1c | 2021-07-06 05:58:31 -0700 | [diff] [blame] | 427 | Attribute.Builder<Label> attrBuilder = |
| 428 | attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes(); |
| 429 | attrBuilder |
| 430 | .getAspectsListBuilder() |
| 431 | .addAspect( |
| 432 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 433 | "base_aspect", |
| 434 | /** inheritedRequiredProviders = */ |
| 435 | ImmutableList.of(), |
| 436 | inheritedAttributeAspects); |
| 437 | Attribute attr = attrBuilder.build(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 438 | |
| 439 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 440 | assertThat(aspects).hasSize(1); |
| 441 | AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor(); |
| 442 | assertThat(aspectDescriptor.getInheritedAttributeAspects()).containsExactly("attr1", "attr2"); |
| 443 | } |
| 444 | |
| 445 | @Test |
| 446 | public void testAttrRequiredAspects_aspectAlreadyExists_inheritRequiredProviders() |
| 447 | throws Exception { |
| 448 | ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders = |
| 449 | ImmutableList.of(ImmutableSet.of(STARLARK_P1), ImmutableSet.of(STARLARK_P2, STARLARK_P3)); |
| 450 | |
messa | 14694d1c | 2021-07-06 05:58:31 -0700 | [diff] [blame] | 451 | Attribute.Builder<Label> attrBuilder = |
| 452 | attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes(); |
| 453 | attrBuilder |
| 454 | .getAspectsListBuilder() |
| 455 | .addAspect( |
| 456 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 457 | "base_aspect", |
| 458 | inheritedRequiredProviders, |
| 459 | /** inheritedAttributeAspects= */ |
| 460 | ImmutableList.of()); |
| 461 | Attribute attr = attrBuilder.build(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 462 | |
| 463 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 464 | assertThat(aspects).hasSize(1); |
| 465 | |
| 466 | RequiredProviders actualInheritedRequiredProviders = |
| 467 | aspects.get(0).getDescriptor().getInheritedRequiredProviders(); |
| 468 | AdvertisedProviderSet expectedOkSet1 = |
| 469 | AdvertisedProviderSet.builder().addStarlark(STARLARK_P1).build(); |
| 470 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet1)).isTrue(); |
| 471 | |
| 472 | AdvertisedProviderSet expectedOkSet2 = |
| 473 | AdvertisedProviderSet.builder().addStarlark(STARLARK_P4).build(); |
| 474 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet2)).isFalse(); |
| 475 | |
| 476 | AdvertisedProviderSet expectedOkSet3 = |
| 477 | AdvertisedProviderSet.builder().addStarlark(STARLARK_P2).addStarlark(STARLARK_P3).build(); |
| 478 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(expectedOkSet3)).isTrue(); |
| 479 | |
| 480 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue(); |
| 481 | assertThat(actualInheritedRequiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)) |
| 482 | .isFalse(); |
| 483 | } |
| 484 | |
| 485 | @Test |
| 486 | public void testAttrRequiredAspects_inheritAllAttrAspects() throws Exception { |
| 487 | ImmutableList<String> inheritedAttributeAspects1 = ImmutableList.of("attr1", "attr2"); |
| 488 | ImmutableList<String> inheritedAttributeAspects2 = ImmutableList.of("*"); |
| 489 | |
messa | 14694d1c | 2021-07-06 05:58:31 -0700 | [diff] [blame] | 490 | Attribute.Builder<Label> attrBuilder = |
| 491 | attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes(); |
| 492 | attrBuilder |
| 493 | .getAspectsListBuilder() |
| 494 | .addAspect( |
| 495 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 496 | "base_aspect_1", |
| 497 | /** inheritedRequiredProviders = */ |
| 498 | ImmutableList.of(), |
| 499 | inheritedAttributeAspects1); |
| 500 | attrBuilder |
| 501 | .getAspectsListBuilder() |
| 502 | .addAspect( |
| 503 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 504 | "base_aspect_2", |
| 505 | /** inheritedRequiredProviders = */ |
| 506 | ImmutableList.of(), |
| 507 | inheritedAttributeAspects2); |
| 508 | Attribute attr = attrBuilder.build(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 509 | |
| 510 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 511 | assertThat(aspects).hasSize(1); |
| 512 | AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor(); |
| 513 | assertThat(aspectDescriptor.getInheritedAttributeAspects()).isNull(); |
| 514 | } |
| 515 | |
| 516 | @Test |
| 517 | public void testAttrRequiredAspects_inheritAllRequiredProviders() throws Exception { |
| 518 | ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders1 = |
| 519 | ImmutableList.of(); |
| 520 | ImmutableList<ImmutableSet<StarlarkProviderIdentifier>> inheritedRequiredProviders2 = |
| 521 | ImmutableList.of(ImmutableSet.of(STARLARK_P4), ImmutableSet.of(STARLARK_P2, STARLARK_P3)); |
| 522 | |
messa | 14694d1c | 2021-07-06 05:58:31 -0700 | [diff] [blame] | 523 | Attribute.Builder<Label> attrBuilder = |
| 524 | attr("x", LABEL).aspect(TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT).allowedFileTypes(); |
| 525 | attrBuilder |
| 526 | .getAspectsListBuilder() |
| 527 | .addAspect( |
| 528 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 529 | "base_aspect_1", |
| 530 | inheritedRequiredProviders1, |
| 531 | /** inheritedAttributeAspects= */ |
| 532 | ImmutableList.of()); |
| 533 | attrBuilder |
| 534 | .getAspectsListBuilder() |
| 535 | .addAspect( |
| 536 | TestAspects.SIMPLE_STARLARK_NATIVE_ASPECT, |
| 537 | "base_aspect_2", |
| 538 | inheritedRequiredProviders2, |
| 539 | /** inheritedAttributeAspects= */ |
| 540 | ImmutableList.of()); |
| 541 | Attribute attr = attrBuilder.build(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 542 | |
| 543 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 544 | assertThat(aspects).hasSize(1); |
| 545 | AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor(); |
| 546 | assertThat(aspectDescriptor.getInheritedRequiredProviders()) |
| 547 | .isEqualTo(RequiredProviders.acceptAnyBuilder().build()); |
| 548 | } |
| 549 | |
| 550 | @Test |
| 551 | public void testAttrRequiredAspects_defaultInheritedRequiredProvidersAndAttrAspects() |
| 552 | throws Exception { |
| 553 | Attribute attr = attr("x", LABEL).aspect(TestAspects.SIMPLE_ASPECT).allowedFileTypes().build(); |
| 554 | |
| 555 | ImmutableList<Aspect> aspects = attr.getAspects(null); |
| 556 | assertThat(aspects).hasSize(1); |
| 557 | AspectDescriptor aspectDescriptor = aspects.get(0).getDescriptor(); |
| 558 | assertThat(aspectDescriptor.getInheritedAttributeAspects()).isEmpty(); |
messa | ed7ddfa | 2021-06-09 05:45:34 -0700 | [diff] [blame] | 559 | assertThat(aspectDescriptor.getInheritedRequiredProviders()).isNull(); |
messa | f8c3408 | 2021-06-04 02:51:04 -0700 | [diff] [blame] | 560 | } |
Ulf Adams | 83763ee | 2015-05-04 15:36:12 +0000 | [diff] [blame] | 561 | } |