| // Copyright 2016 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.bazel.rules; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| import static com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider.pathOrDefault; |
| |
| import com.google.common.base.Strings; |
| import com.google.common.collect.ImmutableList; |
| import com.google.devtools.build.lib.actions.ActionEnvironment; |
| import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; |
| import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.RuleSet; |
| import com.google.devtools.build.lib.analysis.ShellConfiguration; |
| import com.google.devtools.build.lib.analysis.config.BuildOptions; |
| import com.google.devtools.build.lib.analysis.config.CoreOptions; |
| import com.google.devtools.build.lib.analysis.config.Fragment; |
| import com.google.devtools.build.lib.analysis.config.FragmentClassSet; |
| import com.google.devtools.build.lib.analysis.config.FragmentOptions; |
| import com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider.StrictActionEnvOptions; |
| import com.google.devtools.build.lib.packages.RuleClass; |
| import com.google.devtools.build.lib.rules.config.ConfigRules; |
| import com.google.devtools.build.lib.rules.core.CoreRules; |
| import com.google.devtools.build.lib.rules.repository.CoreWorkspaceRules; |
| import com.google.devtools.build.lib.util.OS; |
| import com.google.devtools.build.lib.vfs.PathFragment; |
| import com.google.devtools.common.options.Options; |
| import java.util.HashSet; |
| import java.util.Set; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** |
| * Tests consistency of {@link BazelRuleClassProvider}. |
| */ |
| @RunWith(JUnit4.class) |
| public class BazelRuleClassProviderTest { |
| |
| private static void checkConfigConsistency(ConfiguredRuleClassProvider provider) { |
| // Check that every fragment required by a rule is present. |
| FragmentClassSet configurationFragments = provider.getFragmentRegistry().getAllFragments(); |
| for (RuleClass ruleClass : provider.getRuleClassMap().values()) { |
| for (Class<?> fragment : |
| ruleClass.getConfigurationFragmentPolicy().getRequiredConfigurationFragments()) { |
| assertWithMessage(ruleClass.toString()).that(configurationFragments).contains(fragment); |
| } |
| } |
| |
| Set<Class<? extends FragmentOptions>> configOptions = |
| provider.getFragmentRegistry().getOptionsClasses(); |
| for (Class<? extends Fragment> fragmentClass : configurationFragments) { |
| // Check that every options class required for fragment creation is provided. |
| for (Class<? extends FragmentOptions> options : Fragment.requiredOptions(fragmentClass)) { |
| assertThat(configOptions).contains(options); |
| } |
| } |
| } |
| |
| private static void checkModule(RuleSet top) { |
| ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); |
| builder.setToolsRepository(BazelRuleClassProvider.TOOLS_REPOSITORY); |
| Set<RuleSet> result = new HashSet<>(); |
| result.add(BazelRuleClassProvider.BAZEL_SETUP); |
| collectTransitiveClosure(result, top); |
| for (RuleSet module : result) { |
| module.init(builder); |
| } |
| ConfiguredRuleClassProvider provider = builder.build(); |
| assertThat(provider).isNotNull(); |
| checkConfigConsistency(provider); |
| } |
| |
| private static void collectTransitiveClosure(Set<RuleSet> result, RuleSet module) { |
| if (result.add(module)) { |
| for (RuleSet dep : module.requires()) { |
| collectTransitiveClosure(result, dep); |
| } |
| } |
| } |
| |
| @Test |
| public void coreConsistency() { |
| checkModule(CoreRules.INSTANCE); |
| } |
| |
| @Test |
| public void coreWorkspaceConsistency() { |
| checkModule(CoreWorkspaceRules.INSTANCE); |
| } |
| |
| @Test |
| public void genericConsistency() { |
| checkModule(GenericRules.INSTANCE); |
| } |
| |
| @Test |
| public void configConsistency() { |
| checkModule(ConfigRules.INSTANCE); |
| } |
| |
| @Test |
| public void shConsistency() { |
| checkModule(ShRules.INSTANCE); |
| } |
| |
| @Test |
| public void protoConsistency() { |
| checkModule(BazelRuleClassProvider.PROTO_RULES); |
| } |
| |
| @Test |
| public void cppConsistency() { |
| checkModule(CcRules.INSTANCE); |
| } |
| |
| @Test |
| public void javaConsistency() { |
| checkModule(JavaRules.INSTANCE); |
| } |
| |
| @Test |
| public void pythonConsistency() { |
| checkModule(BazelRuleClassProvider.PYTHON_RULES); |
| } |
| |
| @Test |
| public void androidConsistency() { |
| checkModule(BazelRuleClassProvider.ANDROID_RULES); |
| } |
| |
| @Test |
| public void objcConsistency() { |
| checkModule(ObjcRules.INSTANCE); |
| } |
| |
| @Test |
| public void j2objcConsistency() { |
| checkModule(J2ObjcRules.INSTANCE); |
| } |
| |
| @Test |
| public void variousWorkspaceConsistency() { |
| checkModule(BazelRuleClassProvider.VARIOUS_WORKSPACE_RULES); |
| } |
| |
| @Test |
| public void toolchainConsistency() { |
| checkModule(ToolchainRules.INSTANCE); |
| } |
| |
| @Test |
| public void strictActionEnv() throws Exception { |
| if (OS.getCurrent() == OS.WINDOWS) { |
| return; |
| } |
| |
| BuildOptions options = |
| BuildOptions.of( |
| ImmutableList.of( |
| CoreOptions.class, ShellConfiguration.Options.class, StrictActionEnvOptions.class), |
| "--experimental_strict_action_env", |
| "--action_env=FOO=bar"); |
| |
| ActionEnvironment env = BazelRuleClassProvider.SHELL_ACTION_ENV.getActionEnvironment(options); |
| assertThat(env.getFixedEnv()).containsEntry("PATH", "/bin:/usr/bin:/usr/local/bin"); |
| assertThat(env.getFixedEnv()).containsEntry("FOO", "bar"); |
| } |
| |
| @Test |
| public void pathOrDefaultOnLinux() { |
| assertThat(pathOrDefault(OS.LINUX, null, null)).isEqualTo("/bin:/usr/bin:/usr/local/bin"); |
| assertThat(pathOrDefault(OS.LINUX, "/not/bin", null)).isEqualTo("/bin:/usr/bin:/usr/local/bin"); |
| } |
| |
| @Test |
| public void pathOrDefaultOnWindows() { |
| String defaultWindowsPath = ""; |
| String systemRoot = System.getenv("SYSTEMROOT"); |
| if (Strings.isNullOrEmpty(systemRoot)) { |
| systemRoot = "C:\\Windows"; |
| } |
| defaultWindowsPath += ";" + systemRoot; |
| defaultWindowsPath += ";" + systemRoot + "\\System32"; |
| defaultWindowsPath += ";" + systemRoot + "\\System32\\WindowsPowerShell\\v1.0"; |
| assertThat(pathOrDefault(OS.WINDOWS, null, null)).isEqualTo(defaultWindowsPath); |
| assertThat(pathOrDefault(OS.WINDOWS, "C:/mypath", null)) |
| .isEqualTo(defaultWindowsPath + ";C:/mypath"); |
| assertThat(pathOrDefault(OS.WINDOWS, "C:/mypath", PathFragment.create("D:/foo/shell"))) |
| .isEqualTo("D:\\foo" + defaultWindowsPath + ";C:/mypath"); |
| } |
| |
| @Test |
| public void optionsAlsoApplyToHost() { |
| StrictActionEnvOptions o = Options.getDefaults( |
| StrictActionEnvOptions.class); |
| o.useStrictActionEnv = true; |
| StrictActionEnvOptions h = o.getHost(); |
| assertThat(h.useStrictActionEnv).isTrue(); |
| } |
| } |