blob: e1c4cd1d684809faab2feb095105fbcaedf501fa [file] [log] [blame]
cparsonse2d200f2018-03-06 16:15:11 -08001// Copyright 2018 The Bazel Authors. All rights reserved.
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.
14package com.google.devtools.build.lib.skylark;
15
16import static com.google.common.truth.Truth.assertThat;
17
18import com.google.common.collect.ImmutableList;
dannark90e2b4b2018-06-27 13:35:04 -070019import com.google.common.collect.ImmutableMap;
cparsonse2d200f2018-03-06 16:15:11 -080020import com.google.common.collect.Iterables;
21import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
cparsonsbb956ec2018-04-11 11:22:38 -070022import com.google.devtools.build.lib.actions.Artifact;
ulfjackc23bdac2018-06-13 03:06:16 -070023import com.google.devtools.build.lib.analysis.AnalysisResult;
cparsonse2d200f2018-03-06 16:15:11 -080024import com.google.devtools.build.lib.analysis.ConfiguredAspect;
25import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
26import com.google.devtools.build.lib.cmdline.Label;
27import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
cparsonsbb956ec2018-04-11 11:22:38 -070028import com.google.devtools.build.lib.syntax.SkylarkDict;
cparsonse2d200f2018-03-06 16:15:11 -080029import com.google.devtools.build.lib.syntax.SkylarkList;
cparsonsbb956ec2018-04-11 11:22:38 -070030import java.util.List;
cparsonse2d200f2018-03-06 16:15:11 -080031import java.util.stream.Collectors;
32import org.junit.Test;
33import org.junit.runner.RunWith;
34import org.junit.runners.JUnit4;
35
36/** Tests for the Skylark-accessible actions provider on rule configured targets. */
37@RunWith(JUnit4.class)
38public class SkylarkActionProviderTest extends AnalysisTestCase {
39
40 @Test
41 public void aspectGetsActionProviderForNativeRule() throws Exception {
42 scratch.file(
43 "test/aspect.bzl",
44 "foo = provider()",
45 "def _impl(target, ctx):",
46 " return [foo(actions = target.actions)]",
47 "MyAspect = aspect(implementation=_impl)");
48 scratch.file(
49 "test/BUILD",
50 "genrule(",
51 " name = 'xxx',",
52 " cmd = 'echo \"hello\" > $@',",
53 " outs = ['mygen.out']",
54 ")");
55
56 AnalysisResult analysisResult =
57 update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
58
59 ConfiguredAspect configuredAspect =
60 Iterables.getOnlyElement(analysisResult.getAspects()).getConfiguredAspect();
61
dannark90e2b4b2018-06-27 13:35:04 -070062 SkylarkKey fooKey =
63 new SkylarkKey(Label.parseAbsolute("//test:aspect.bzl", ImmutableMap.of()), "foo");
cparsonse2d200f2018-03-06 16:15:11 -080064
65 assertThat(configuredAspect.get(fooKey).getValue("actions")).isNotNull();
66 @SuppressWarnings("unchecked")
67 SkylarkList<ActionAnalysisMetadata> actions =
68 (SkylarkList<ActionAnalysisMetadata>) configuredAspect.get(fooKey).getValue("actions");
69 assertThat(actions).isNotEmpty();
70
71 ActionAnalysisMetadata action = actions.get(0);
72 assertThat(action.getMnemonic()).isEqualTo("Genrule");
73 }
74
75 @Test
cparsonsbb956ec2018-04-11 11:22:38 -070076 @SuppressWarnings("unchecked")
cparsonse2d200f2018-03-06 16:15:11 -080077 public void aspectGetsActionProviderForSkylarkRule() throws Exception {
78 scratch.file(
79 "test/aspect.bzl",
80 "foo = provider()",
81 "def _impl(target, ctx):",
cparsonsbb956ec2018-04-11 11:22:38 -070082 " mnemonics = [a.mnemonic for a in target.actions]",
83 " envs = [a.env for a in target.actions]",
84 " inputs = [a.inputs.to_list() for a in target.actions]",
85 " outputs = [a.outputs.to_list() for a in target.actions]",
86 " argv = [a.argv for a in target.actions]",
87 " return [foo(",
88 " actions = target.actions,",
89 " mnemonics = mnemonics,",
90 " envs = envs,",
91 " inputs = inputs,",
92 " outputs = outputs,",
93 " argv = argv",
94 " )]",
cparsonse2d200f2018-03-06 16:15:11 -080095 "MyAspect = aspect(implementation=_impl)");
96 scratch.file(
97 "test/rule.bzl",
98 "def impl(ctx):",
99 " output_file0 = ctx.new_file('myfile0')",
100 " output_file1 = ctx.new_file('myfile1')",
cparsonsbb956ec2018-04-11 11:22:38 -0700101 " executable = ctx.new_file('executable')",
102 " ctx.actions.run(outputs=[output_file0], executable=executable,",
103 " mnemonic='MyAction0', env={'foo':'bar', 'pet':'puppy'})",
104 " ctx.actions.run_shell(outputs=[executable, output_file1],",
105 " command='fakecmd', mnemonic='MyAction1', env={'pet':'bunny'})",
cparsonse2d200f2018-03-06 16:15:11 -0800106 " return None",
107 "my_rule = rule(impl)");
108 scratch.file(
109 "test/BUILD", "load('//test:rule.bzl', 'my_rule')", "my_rule(", " name = 'xxx',", ")");
110
111 AnalysisResult analysisResult =
112 update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
113
114 ConfiguredAspect configuredAspect =
115 Iterables.getOnlyElement(analysisResult.getAspects()).getConfiguredAspect();
116
dannark90e2b4b2018-06-27 13:35:04 -0700117 SkylarkKey fooKey =
118 new SkylarkKey(Label.parseAbsolute("//test:aspect.bzl", ImmutableMap.of()), "foo");
cparsonse2d200f2018-03-06 16:15:11 -0800119
120 assertThat(configuredAspect.get(fooKey).getValue("actions")).isNotNull();
cparsonsbb956ec2018-04-11 11:22:38 -0700121
cparsonse2d200f2018-03-06 16:15:11 -0800122 SkylarkList<ActionAnalysisMetadata> actions =
123 (SkylarkList<ActionAnalysisMetadata>) configuredAspect.get(fooKey).getValue("actions");
124 assertThat(actions).hasSize(2);
125
cparsonsbb956ec2018-04-11 11:22:38 -0700126 SkylarkList<String> mnemonics =
127 (SkylarkList<String>) configuredAspect.get(fooKey).getValue("mnemonics");
128 assertThat(mnemonics).containsExactly("MyAction0", "MyAction1");
129
130 SkylarkList<SkylarkDict<String, String>> envs =
131 (SkylarkList<SkylarkDict<String, String>>) configuredAspect.get(fooKey).getValue("envs");
132 assertThat(envs).containsExactly(
133 SkylarkDict.of(null, "foo", "bar", "pet", "puppy"),
134 SkylarkDict.of(null, "pet", "bunny"));
135
136 SkylarkList<SkylarkList<Artifact>> inputs =
137 (SkylarkList<SkylarkList<Artifact>>) configuredAspect.get(fooKey).getValue("inputs");
138 assertThat(flattenArtifactNames(inputs)).containsExactly("executable");
139
140 SkylarkList<SkylarkList<Artifact>> outputs =
141 (SkylarkList<SkylarkList<Artifact>>) configuredAspect.get(fooKey).getValue("outputs");
142 assertThat(flattenArtifactNames(outputs)).containsExactly("myfile0", "executable", "myfile1");
143
144 SkylarkList<SkylarkList<String>> argv =
145 (SkylarkList<SkylarkList<String>>) configuredAspect.get(fooKey).getValue("argv");
146 assertThat(argv.get(0)).hasSize(1);
147 assertThat(argv.get(0).get(0)).endsWith("executable");
148 assertThat(argv.get(1)).contains("fakecmd");
149 }
150
151 private static List<String> flattenArtifactNames(
152 SkylarkList<SkylarkList<Artifact>> artifactLists) {
153 return artifactLists.stream()
154 .flatMap(artifacts -> artifacts.stream())
155 .map(artifact -> artifact.getFilename())
156 .collect(Collectors.toList());
cparsonse2d200f2018-03-06 16:15:11 -0800157 }
158}