blob: a40319bd3bf1f25d7fca1cc0d834d1384238ef37 [file] [log] [blame]
// 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();
}
}