blob: 6238d45336ee68b0c1a65ae942f4d26c95921e96 [file] [log] [blame]
// Copyright 2015 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.analysis.config;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
/**
* Tests for {@link ConfigSetting}.
*/
public class ConfigSettingTest extends BuildViewTestCase {
private void writeSimpleExample() throws Exception {
scratch.file("pkg/BUILD",
"config_setting(",
" name = 'foo',",
" values = {",
" 'compilation_mode': 'dbg',",
" 'stamp': '1',",
" })");
}
private ConfigMatchingProvider getConfigMatchingProvider(String label) throws Exception {
return getConfiguredTarget(label).getProvider(ConfigMatchingProvider.class);
}
/**
* Returns the default value of the given flag.
*/
private Object flagDefault(String option) {
Class<? extends OptionsBase> optionsClass = getTargetConfiguration().getOptionClass(option);
return OptionsParser.newOptionsParser(optionsClass)
.getOptions(optionsClass)
.asMap()
.get(option);
}
/**
* Tests that a config_setting only matches build configurations where *all* of
* its flag specifications match.
*/
public void testMatchingCriteria() throws Exception {
writeSimpleExample();
// First flag mismatches:
useConfiguration("-c", "opt", "--stamp");
assertFalse(getConfigMatchingProvider("//pkg:foo").matches());
// Second flag mismatches:
useConfiguration("-c", "dbg", "--nostamp");
assertFalse(getConfigMatchingProvider("//pkg:foo").matches());
// Both flags mismatch:
useConfiguration("-c", "opt", "--nostamp");
assertFalse(getConfigMatchingProvider("//pkg:foo").matches());
// Both flags match:
useConfiguration("-c", "dbg", "--stamp");
assertTrue(getConfigMatchingProvider("//pkg:foo").matches());
}
/**
* Tests that {@link ConfigMatchingProvider#label} is correct.
*/
public void testLabel() throws Exception {
writeSimpleExample();
assertEquals(
Label.parseAbsolute("//pkg:foo"),
getConfigMatchingProvider("//pkg:foo").label());
}
/**
* Tests that rule analysis fails on unknown options.
*/
public void testUnknownOption() throws Exception {
checkError("foo", "badoption",
"unknown option: 'not_an_option'",
"config_setting(",
" name = 'badoption',",
" values = {'not_an_option': 'bar'})");
}
/**
* Tests that rule analysis fails on invalid option values.
*/
public void testInvalidOptionValue() throws Exception {
checkError("foo", "badvalue",
"Not a valid compilation mode: 'baz'",
"config_setting(",
" name = 'badvalue',",
" values = {'compilation_mode': 'baz'})");
}
/**
* Tests that when the first option is valid but the config_setting doesn't match,
* remaining options are still validity-checked.
*/
public void testInvalidOptionFartherDown() throws Exception {
checkError("foo", "badoption",
"unknown option: 'not_an_option'",
"config_setting(",
" name = 'badoption',",
" values = {",
" 'compilation_mode': 'opt',",
" 'not_an_option': 'bar',",
" })");
}
/**
* Tests that *some* settings must be specified.
*/
public void testEmptySettings() throws Exception {
checkError("foo", "empty",
"//foo:empty: no settings specified",
"config_setting(",
" name = 'empty',",
" values = {})");
}
/**
* Tests {@link BuildConfiguration.Fragment#lateBoundOptionDefaults} options (options
* that take alternative defaults from what's specified in {@link
* com.google.devtools.common.options.Option#defaultValue}).
*/
public void testLateBoundOptionDefaults() throws Exception {
String crosstoolCpuDefault = (String) getTargetConfiguration().getOptionValue("cpu");
String crosstoolCompilerDefault = (String) getTargetConfiguration().getOptionValue("compiler");
scratch.file("test/BUILD",
"config_setting(",
" name = 'match',",
" values = {",
" 'cpu': '" + crosstoolCpuDefault + "',",
" 'compiler': '" + crosstoolCompilerDefault + "',", //'gcc-4.4.0',",
" })");
assertTrue(getConfigMatchingProvider("//test:match").matches());
assertNull(flagDefault("cpu"));
assertNotNull(crosstoolCpuDefault);
assertNull(flagDefault("compiler"));
assertNotNull(crosstoolCompilerDefault);
}
/**
* Tests matching on multi-value attributes with key=value entries (e.g. --define).
*/
public void testMultiValueDict() throws Exception {
scratch.file("test/BUILD",
"config_setting(",
" name = 'match',",
" values = {",
" 'define': 'foo=bar',",
" })");
useConfiguration("");
assertFalse(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--define", "foo=bar");
assertTrue(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--define", "foo=baz");
assertFalse(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--define", "foo=bar", "--define", "bar=baz");
assertTrue(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--define", "foo=bar", "--define", "bar=baz", "--define", "foo=nope");
assertFalse(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--define", "foo=nope", "--define", "bar=baz", "--define", "foo=bar");
assertTrue(getConfigMatchingProvider("//test:match").matches());
}
/**
* Tests matching on multi-value attributes with primitive values.
*/
public void testMultiValueList() throws Exception {
scratch.file("test/BUILD",
"config_setting(",
" name = 'match',",
" values = {",
" 'copt': '-Dfoo',",
" })");
useConfiguration("");
assertFalse(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--copt", "-Dfoo");
assertTrue(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--copt", "-Dbar");
assertFalse(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--copt", "-Dfoo", "--copt", "-Dbar");
assertTrue(getConfigMatchingProvider("//test:match").matches());
useConfiguration("--copt", "-Dbar", "--copt", "-Dfoo");
assertTrue(getConfigMatchingProvider("//test:match").matches());
}
}