blob: 50ff3410bdb97fc772c12f1fc17213dd1d5ef1fc [file] [log] [blame]
brandjon60be5312017-10-04 23:06:41 +02001// Copyright 2017 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.
14
15package com.google.devtools.build.lib.packages;
16
17import static com.google.common.truth.Truth.assertThat;
18
plf7e41f9b2018-08-03 01:47:22 -070019import com.google.common.collect.ImmutableList;
shahanfae34b92018-02-13 10:08:47 -080020import com.google.common.collect.ImmutableMap;
21import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
plf504a6d22018-07-31 08:41:20 -070022import com.google.devtools.build.lib.skyframe.serialization.DynamicCodec;
shahanfae34b92018-02-13 10:08:47 -080023import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
brandjon60be5312017-10-04 23:06:41 +020024import com.google.devtools.build.lib.skyframe.serialization.testutils.TestUtils;
laurentlb6659b4c2019-02-18 07:23:36 -080025import com.google.devtools.build.lib.syntax.StarlarkSemantics;
brandjon60be5312017-10-04 23:06:41 +020026import com.google.devtools.common.options.Options;
27import com.google.devtools.common.options.OptionsParser;
28import java.util.Arrays;
29import java.util.Random;
30import org.junit.Test;
31import org.junit.runner.RunWith;
32import org.junit.runners.JUnit4;
33
34/**
laurentlb92c43cd2019-02-18 08:27:55 -080035 * Tests for the flow of flags from {@link StarlarkSemanticsOptions} to {@link StarlarkSemantics},
laurentlb6659b4c2019-02-18 07:23:36 -080036 * and to and from {@code StarlarkSemantics}' serialized representation.
brandjon60be5312017-10-04 23:06:41 +020037 *
38 * <p>When adding a new option, it is trivial to make a transposition error or a copy/paste error.
39 * These tests guard against such errors. The following possible bugs are considered:
plf7e41f9b2018-08-03 01:47:22 -070040 *
brandjon60be5312017-10-04 23:06:41 +020041 * <ul>
laurentlb6659b4c2019-02-18 07:23:36 -080042 * <li>If a new option is added to {@code StarlarkSemantics} but not to {@code
laurentlb92c43cd2019-02-18 08:27:55 -080043 * StarlarkSemanticsOptions}, or vice versa, then the programmer will either be unable to
brandjon60be5312017-10-04 23:06:41 +020044 * implement its behavior, or unable to test it from the command line and add user
45 * documentation. We hope that the programmer notices this on their own.
laurentlb92c43cd2019-02-18 08:27:55 -080046 * <li>If {@link StarlarkSemanticsOptions#toSkylarkSemantics} is not updated to set all fields of
laurentlb6659b4c2019-02-18 07:23:36 -080047 * {@code StarlarkSemantics}, then it will fail immediately because all fields of {@link
48 * StarlarkSemantics.Builder} are mandatory.
brandjon60be5312017-10-04 23:06:41 +020049 * <li>To catch a copy/paste error where the wrong field's data is threaded through {@code
50 * toSkylarkSemantics()} or {@code deserialize(...)}, we repeatedly generate matching random
51 * instances of the input and expected output objects.
brandjon60be5312017-10-04 23:06:41 +020052 * <li>The {@link #checkDefaultsMatch} test ensures that there is no divergence between the
53 * default values of the two classes.
plf7e41f9b2018-08-03 01:47:22 -070054 * <li>There is no test coverage for failing to update the non-generated webpage documentation. So
55 * don't forget that!
brandjon60be5312017-10-04 23:06:41 +020056 * </ul>
57 */
58@RunWith(JUnit4.class)
59public class SkylarkSemanticsConsistencyTest {
60
61 private static final int NUM_RANDOM_TRIALS = 10;
62
63 /**
laurentlb92c43cd2019-02-18 08:27:55 -080064 * Checks that a randomly generated {@link StarlarkSemanticsOptions} object can be converted to a
laurentlb6659b4c2019-02-18 07:23:36 -080065 * {@link StarlarkSemantics} object with the same field values.
brandjon60be5312017-10-04 23:06:41 +020066 */
67 @Test
68 public void optionsToSemantics() throws Exception {
69 for (int i = 0; i < NUM_RANDOM_TRIALS; i++) {
70 long seed = i;
laurentlb92c43cd2019-02-18 08:27:55 -080071 StarlarkSemanticsOptions options = buildRandomOptions(new Random(seed));
laurentlb6659b4c2019-02-18 07:23:36 -080072 StarlarkSemantics semantics = buildRandomSemantics(new Random(seed));
73 StarlarkSemantics semanticsFromOptions = options.toSkylarkSemantics();
brandjon60be5312017-10-04 23:06:41 +020074 assertThat(semanticsFromOptions).isEqualTo(semantics);
75 }
76 }
77
brandjon6ac92f92017-12-06 13:57:15 -080078 /**
laurentlb6659b4c2019-02-18 07:23:36 -080079 * Checks that a randomly generated {@link StarlarkSemantics} object can be serialized and
brandjon60be5312017-10-04 23:06:41 +020080 * deserialized to an equivalent object.
81 */
82 @Test
83 public void serializationRoundTrip() throws Exception {
plf504a6d22018-07-31 08:41:20 -070084 DynamicCodec codec = new DynamicCodec(buildRandomSemantics(new Random(2)).getClass());
brandjon60be5312017-10-04 23:06:41 +020085 for (int i = 0; i < NUM_RANDOM_TRIALS; i++) {
laurentlb6659b4c2019-02-18 07:23:36 -080086 StarlarkSemantics semantics = buildRandomSemantics(new Random(i));
87 StarlarkSemantics deserialized =
88 (StarlarkSemantics)
89 TestUtils.fromBytes(
90 new DeserializationContext(ImmutableMap.of()),
91 codec,
92 TestUtils.toBytes(new SerializationContext(ImmutableMap.of()), codec, semantics));
brandjon60be5312017-10-04 23:06:41 +020093 assertThat(deserialized).isEqualTo(semantics);
94 }
95 }
96
97 @Test
98 public void checkDefaultsMatch() {
laurentlb92c43cd2019-02-18 08:27:55 -080099 StarlarkSemanticsOptions defaultOptions = Options.getDefaults(StarlarkSemanticsOptions.class);
laurentlb6659b4c2019-02-18 07:23:36 -0800100 StarlarkSemantics defaultSemantics = StarlarkSemantics.DEFAULT_SEMANTICS;
101 StarlarkSemantics semanticsFromOptions = defaultOptions.toSkylarkSemantics();
brandjon60be5312017-10-04 23:06:41 +0200102 assertThat(semanticsFromOptions).isEqualTo(defaultSemantics);
103 }
104
brandjon6ac92f92017-12-06 13:57:15 -0800105 @Test
106 public void canGetBuilderFromInstance() {
laurentlb6659b4c2019-02-18 07:23:36 -0800107 StarlarkSemantics original = StarlarkSemantics.DEFAULT_SEMANTICS;
brandjon6ac92f92017-12-06 13:57:15 -0800108 assertThat(original.internalSkylarkFlagTestCanary()).isFalse();
laurentlb6659b4c2019-02-18 07:23:36 -0800109 StarlarkSemantics modified = original.toBuilder().internalSkylarkFlagTestCanary(true).build();
brandjon6ac92f92017-12-06 13:57:15 -0800110 assertThat(modified.internalSkylarkFlagTestCanary()).isTrue();
111 }
112
brandjon60be5312017-10-04 23:06:41 +0200113 /**
laurentlb92c43cd2019-02-18 08:27:55 -0800114 * Constructs a {@link StarlarkSemanticsOptions} object with random fields. Must access {@code
brandjon60be5312017-10-04 23:06:41 +0200115 * rand} using the same sequence of operations (for the same fields) as {@link
116 * #buildRandomSemantics}.
117 */
laurentlb92c43cd2019-02-18 08:27:55 -0800118 private static StarlarkSemanticsOptions buildRandomOptions(Random rand) throws Exception {
brandjon60be5312017-10-04 23:06:41 +0200119 return parseOptions(
120 // <== Add new options here in alphabetic order ==>
Googler137019f2019-04-23 02:23:37 -0700121 "--experimental_allow_incremental_repository_updates=" + rand.nextBoolean(),
juliexxia1f332e02018-10-31 14:20:55 -0700122 "--experimental_build_setting_api=" + rand.nextBoolean(),
plf7e41f9b2018-08-03 01:47:22 -0700123 "--experimental_cc_skylark_api_enabled_packages="
124 + rand.nextDouble()
125 + ","
126 + rand.nextDouble(),
Googlerc2cd9572018-10-02 14:38:15 -0700127 "--experimental_enable_android_migration_apis=" + rand.nextBoolean(),
cparsonsed6bfbe2019-04-19 10:17:03 -0700128 "--experimental_google_legacy_api=" + rand.nextBoolean(),
elenairinae679d022019-01-07 07:49:27 -0800129 "--experimental_java_common_create_provider_enabled_packages="
130 + rand.nextDouble()
131 + ","
132 + rand.nextDouble(),
cparsons140c0762018-10-05 14:07:19 -0700133 "--experimental_platforms_api=" + rand.nextBoolean(),
cparsonse0efc142018-10-17 09:39:10 -0700134 "--experimental_starlark_config_transitions=" + rand.nextBoolean(),
Googler57363812019-05-28 07:24:13 -0700135 "--experimental_starlark_unused_inputs_list=" + rand.nextBoolean(),
brandjon60be5312017-10-04 23:06:41 +0200136 "--incompatible_bzl_disallow_load_after_statement=" + rand.nextBoolean(),
plf0d40b7f2019-04-29 08:09:11 -0700137 "--incompatible_depset_for_libraries_to_link_getter=" + rand.nextBoolean(),
brandjon60be5312017-10-04 23:06:41 +0200138 "--incompatible_depset_is_not_iterable=" + rand.nextBoolean(),
laurentlb2bbda4a2017-12-07 10:38:46 -0800139 "--incompatible_depset_union=" + rand.nextBoolean(),
cparsonse5068582018-07-16 13:33:33 -0700140 "--incompatible_disable_deprecated_attr_params=" + rand.nextBoolean(),
cparsons99be8b42018-03-01 15:16:46 -0800141 "--incompatible_disable_objc_provider_resources=" + rand.nextBoolean(),
gregce4aa059a2019-02-26 13:20:47 -0800142 "--incompatible_disable_third_party_license_checking=" + rand.nextBoolean(),
brandjon60be5312017-10-04 23:06:41 +0200143 "--incompatible_disallow_dict_plus=" + rand.nextBoolean(),
laurentlb9bc841e2019-05-28 05:59:35 -0700144 "--incompatible_disallow_empty_glob=" + rand.nextBoolean(),
laurentlb707acfe2018-04-13 06:09:30 -0700145 "--incompatible_disallow_filetype=" + rand.nextBoolean(),
tomlue3749702018-05-02 09:38:00 -0700146 "--incompatible_disallow_legacy_javainfo=" + rand.nextBoolean(),
elenairina2fe38c12019-01-10 00:49:13 -0800147 "--incompatible_disallow_legacy_java_provider=" + rand.nextBoolean(),
nharmatad86b5092018-10-16 15:50:21 -0700148 "--incompatible_disallow_load_labels_to_cross_package_boundaries=" + rand.nextBoolean(),
laurentlb64e833c2019-02-22 09:50:34 -0800149 "--incompatible_disallow_native_in_build_file=" + rand.nextBoolean(),
tomlubeafd7e2018-04-05 15:03:19 -0700150 "--incompatible_disallow_old_style_args_add=" + rand.nextBoolean(),
cparsons5d531712019-02-05 13:31:03 -0800151 "--incompatible_disallow_struct_provider_syntax=" + rand.nextBoolean(),
John Cater56887932019-04-26 05:27:07 -0700152 "--incompatible_disallow_rule_execution_platform_constraints_allowed=" + rand.nextBoolean(),
plf0d40b7f2019-04-29 08:09:11 -0700153 "--incompatible_do_not_split_linking_cmdline=" + rand.nextBoolean(),
tomlu774bfe02018-08-24 14:15:44 -0700154 "--incompatible_expand_directories=" + rand.nextBoolean(),
brandjon60be5312017-10-04 23:06:41 +0200155 "--incompatible_new_actions_api=" + rand.nextBoolean(),
laurentlbd8d37762018-10-26 14:08:33 -0700156 "--incompatible_no_attr_license=" + rand.nextBoolean(),
laurentlbde41cf82019-04-12 13:47:58 -0700157 "--incompatible_no_kwargs_in_build_files=" + rand.nextBoolean(),
cparsonsfbc828b2018-10-04 14:38:50 -0700158 "--incompatible_no_output_attr_default=" + rand.nextBoolean(),
cparsons36c70a62019-06-07 09:31:14 -0700159 "--incompatible_no_rule_outputs_param=" + rand.nextBoolean(),
tomluaaf11e92018-06-02 10:20:16 -0700160 "--incompatible_no_support_tools_in_action_inputs=" + rand.nextBoolean(),
cparsons3cb3a5d2018-10-01 10:36:08 -0700161 "--incompatible_no_target_output_group=" + rand.nextBoolean(),
laurentlb9d179e12018-09-27 08:15:42 -0700162 "--incompatible_no_transitive_loads=" + rand.nextBoolean(),
Googlerf8e87fb2019-04-12 19:13:28 -0700163 "--incompatible_objc_framework_cleanup=" + rand.nextBoolean(),
dannarked874632019-01-17 14:01:15 -0800164 "--incompatible_remap_main_repo=" + rand.nextBoolean(),
Danna Kelmer21f4bd32018-11-29 11:04:48 -0800165 "--incompatible_remove_native_maven_jar=" + rand.nextBoolean(),
cparsons6b3724f2019-04-26 08:53:32 -0700166 "--incompatible_restrict_named_params=" + rand.nextBoolean(),
laurentlbed633332019-04-12 16:34:08 -0700167 "--incompatible_static_name_resolution_in_build_files=" + rand.nextBoolean(),
laurentlb18ef7a52019-03-28 08:07:25 -0700168 "--incompatible_string_join_requires_strings=" + rand.nextBoolean(),
Marwan Tammam20c84132019-06-04 07:27:31 -0700169 "--incompatible_restrict_string_escapes=" + rand.nextBoolean(),
plf0d40b7f2019-04-29 08:09:11 -0700170 "--internal_skylark_flag_test_canary=" + rand.nextBoolean());
brandjon60be5312017-10-04 23:06:41 +0200171 }
172
173 /**
laurentlb6659b4c2019-02-18 07:23:36 -0800174 * Constructs a {@link StarlarkSemantics} object with random fields. Must access {@code rand}
175 * using the same sequence of operations (for the same fields) as {@link #buildRandomOptions}.
brandjon60be5312017-10-04 23:06:41 +0200176 */
laurentlb6659b4c2019-02-18 07:23:36 -0800177 private static StarlarkSemantics buildRandomSemantics(Random rand) {
178 return StarlarkSemantics.builder()
brandjon60be5312017-10-04 23:06:41 +0200179 // <== Add new options here in alphabetic order ==>
Googler137019f2019-04-23 02:23:37 -0700180 .experimentalAllowIncrementalRepositoryUpdates(rand.nextBoolean())
juliexxia1f332e02018-10-31 14:20:55 -0700181 .experimentalBuildSettingApi(rand.nextBoolean())
plf7e41f9b2018-08-03 01:47:22 -0700182 .experimentalCcSkylarkApiEnabledPackages(
183 ImmutableList.of(String.valueOf(rand.nextDouble()), String.valueOf(rand.nextDouble())))
Googlerc2cd9572018-10-02 14:38:15 -0700184 .experimentalEnableAndroidMigrationApis(rand.nextBoolean())
cparsonsed6bfbe2019-04-19 10:17:03 -0700185 .experimentalGoogleLegacyApi(rand.nextBoolean())
elenairinae679d022019-01-07 07:49:27 -0800186 .experimentalJavaCommonCreateProviderEnabledPackages(
187 ImmutableList.of(String.valueOf(rand.nextDouble()), String.valueOf(rand.nextDouble())))
cparsons140c0762018-10-05 14:07:19 -0700188 .experimentalPlatformsApi(rand.nextBoolean())
cparsonse0efc142018-10-17 09:39:10 -0700189 .experimentalStarlarkConfigTransitions(rand.nextBoolean())
Googler57363812019-05-28 07:24:13 -0700190 .experimentalStarlarkUnusedInputsList(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200191 .incompatibleBzlDisallowLoadAfterStatement(rand.nextBoolean())
plf0d40b7f2019-04-29 08:09:11 -0700192 .incompatibleDepsetForLibrariesToLinkGetter(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200193 .incompatibleDepsetIsNotIterable(rand.nextBoolean())
laurentlb2bbda4a2017-12-07 10:38:46 -0800194 .incompatibleDepsetUnion(rand.nextBoolean())
cparsonse5068582018-07-16 13:33:33 -0700195 .incompatibleDisableDeprecatedAttrParams(rand.nextBoolean())
cparsons99be8b42018-03-01 15:16:46 -0800196 .incompatibleDisableObjcProviderResources(rand.nextBoolean())
gregce4aa059a2019-02-26 13:20:47 -0800197 .incompatibleDisableThirdPartyLicenseChecking(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200198 .incompatibleDisallowDictPlus(rand.nextBoolean())
laurentlb9bc841e2019-05-28 05:59:35 -0700199 .incompatibleDisallowEmptyGlob(rand.nextBoolean())
laurentlb707acfe2018-04-13 06:09:30 -0700200 .incompatibleDisallowFileType(rand.nextBoolean())
tomlue3749702018-05-02 09:38:00 -0700201 .incompatibleDisallowLegacyJavaInfo(rand.nextBoolean())
elenairina2fe38c12019-01-10 00:49:13 -0800202 .incompatibleDisallowLegacyJavaProvider(rand.nextBoolean())
nharmatad86b5092018-10-16 15:50:21 -0700203 .incompatibleDisallowLoadLabelsToCrossPackageBoundaries(rand.nextBoolean())
laurentlb64e833c2019-02-22 09:50:34 -0800204 .incompatibleDisallowNativeInBuildFile(rand.nextBoolean())
tomlubeafd7e2018-04-05 15:03:19 -0700205 .incompatibleDisallowOldStyleArgsAdd(rand.nextBoolean())
cparsons5d531712019-02-05 13:31:03 -0800206 .incompatibleDisallowStructProviderSyntax(rand.nextBoolean())
John Cater56887932019-04-26 05:27:07 -0700207 .incompatibleDisallowRuleExecutionPlatformConstraintsAllowed(rand.nextBoolean())
plf0d40b7f2019-04-29 08:09:11 -0700208 .incompatibleDoNotSplitLinkingCmdline(rand.nextBoolean())
tomlu774bfe02018-08-24 14:15:44 -0700209 .incompatibleExpandDirectories(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200210 .incompatibleNewActionsApi(rand.nextBoolean())
laurentlbd8d37762018-10-26 14:08:33 -0700211 .incompatibleNoAttrLicense(rand.nextBoolean())
laurentlbde41cf82019-04-12 13:47:58 -0700212 .incompatibleNoKwargsInBuildFiles(rand.nextBoolean())
cparsonsfbc828b2018-10-04 14:38:50 -0700213 .incompatibleNoOutputAttrDefault(rand.nextBoolean())
cparsons36c70a62019-06-07 09:31:14 -0700214 .incompatibleNoRuleOutputsParam(rand.nextBoolean())
tomluaaf11e92018-06-02 10:20:16 -0700215 .incompatibleNoSupportToolsInActionInputs(rand.nextBoolean())
cparsons3cb3a5d2018-10-01 10:36:08 -0700216 .incompatibleNoTargetOutputGroup(rand.nextBoolean())
laurentlb9d179e12018-09-27 08:15:42 -0700217 .incompatibleNoTransitiveLoads(rand.nextBoolean())
Googlerf8e87fb2019-04-12 19:13:28 -0700218 .incompatibleObjcFrameworkCleanup(rand.nextBoolean())
dannarked874632019-01-17 14:01:15 -0800219 .incompatibleRemapMainRepo(rand.nextBoolean())
Danna Kelmer21f4bd32018-11-29 11:04:48 -0800220 .incompatibleRemoveNativeMavenJar(rand.nextBoolean())
cparsons6b3724f2019-04-26 08:53:32 -0700221 .incompatibleRestrictNamedParams(rand.nextBoolean())
laurentlbed633332019-04-12 16:34:08 -0700222 .incompatibleStaticNameResolutionInBuildFiles(rand.nextBoolean())
laurentlb18ef7a52019-03-28 08:07:25 -0700223 .incompatibleStringJoinRequiresStrings(rand.nextBoolean())
Marwan Tammam20c84132019-06-04 07:27:31 -0700224 .incompatibleRestrictStringEscapes(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200225 .internalSkylarkFlagTestCanary(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200226 .build();
227 }
228
laurentlb92c43cd2019-02-18 08:27:55 -0800229 private static StarlarkSemanticsOptions parseOptions(String... args) throws Exception {
230 OptionsParser parser = OptionsParser.newOptionsParser(StarlarkSemanticsOptions.class);
brandjon60be5312017-10-04 23:06:41 +0200231 parser.setAllowResidue(false);
232 parser.parse(Arrays.asList(args));
laurentlb92c43cd2019-02-18 08:27:55 -0800233 return parser.getOptions(StarlarkSemanticsOptions.class);
brandjon60be5312017-10-04 23:06:41 +0200234 }
235}