blob: 6aa52d5dabe603943c97ea8642d88a481ddd62d6 [file] [log] [blame]
ichern585647e2020-01-15 00:37:44 -08001// Copyright 2019 The Bazel Authors. All rights reserved.
brandjon60be5312017-10-04 23:06:41 +02002//
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.
ichern585647e2020-01-15 00:37:44 -080014//
brandjon60be5312017-10-04 23:06:41 +020015
16package com.google.devtools.build.lib.packages;
17
18import static com.google.common.truth.Truth.assertThat;
19
plf7e41f9b2018-08-03 01:47:22 -070020import com.google.common.collect.ImmutableList;
shahanfae34b92018-02-13 10:08:47 -080021import com.google.common.collect.ImmutableMap;
22import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
plf504a6d22018-07-31 08:41:20 -070023import com.google.devtools.build.lib.skyframe.serialization.DynamicCodec;
shahanfae34b92018-02-13 10:08:47 -080024import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
brandjon60be5312017-10-04 23:06:41 +020025import com.google.devtools.build.lib.skyframe.serialization.testutils.TestUtils;
laurentlb6659b4c2019-02-18 07:23:36 -080026import com.google.devtools.build.lib.syntax.StarlarkSemantics;
brandjon60be5312017-10-04 23:06:41 +020027import com.google.devtools.common.options.Options;
28import com.google.devtools.common.options.OptionsParser;
29import java.util.Arrays;
30import java.util.Random;
31import org.junit.Test;
32import org.junit.runner.RunWith;
33import org.junit.runners.JUnit4;
34
35/**
laurentlb92c43cd2019-02-18 08:27:55 -080036 * Tests for the flow of flags from {@link StarlarkSemanticsOptions} to {@link StarlarkSemantics},
laurentlb6659b4c2019-02-18 07:23:36 -080037 * and to and from {@code StarlarkSemantics}' serialized representation.
brandjon60be5312017-10-04 23:06:41 +020038 *
39 * <p>When adding a new option, it is trivial to make a transposition error or a copy/paste error.
40 * These tests guard against such errors. The following possible bugs are considered:
plf7e41f9b2018-08-03 01:47:22 -070041 *
brandjon60be5312017-10-04 23:06:41 +020042 * <ul>
laurentlb6659b4c2019-02-18 07:23:36 -080043 * <li>If a new option is added to {@code StarlarkSemantics} but not to {@code
laurentlb92c43cd2019-02-18 08:27:55 -080044 * StarlarkSemanticsOptions}, or vice versa, then the programmer will either be unable to
brandjon60be5312017-10-04 23:06:41 +020045 * implement its behavior, or unable to test it from the command line and add user
46 * documentation. We hope that the programmer notices this on their own.
gregce3eb74022020-05-14 10:50:09 -070047 * <li>If {@link StarlarkSemanticsOptions#toStarlarkSemantics} is not updated to set all fields of
laurentlb6659b4c2019-02-18 07:23:36 -080048 * {@code StarlarkSemantics}, then it will fail immediately because all fields of {@link
49 * StarlarkSemantics.Builder} are mandatory.
brandjon60be5312017-10-04 23:06:41 +020050 * <li>To catch a copy/paste error where the wrong field's data is threaded through {@code
gregce3eb74022020-05-14 10:50:09 -070051 * toStarlarkSemantics()} or {@code deserialize(...)}, we repeatedly generate matching random
brandjon60be5312017-10-04 23:06:41 +020052 * instances of the input and expected output objects.
brandjon60be5312017-10-04 23:06:41 +020053 * <li>The {@link #checkDefaultsMatch} test ensures that there is no divergence between the
54 * default values of the two classes.
plf7e41f9b2018-08-03 01:47:22 -070055 * <li>There is no test coverage for failing to update the non-generated webpage documentation. So
56 * don't forget that!
brandjon60be5312017-10-04 23:06:41 +020057 * </ul>
58 */
59@RunWith(JUnit4.class)
gregce3eb74022020-05-14 10:50:09 -070060public class StarlarkSemanticsConsistencyTest {
brandjon60be5312017-10-04 23:06:41 +020061
62 private static final int NUM_RANDOM_TRIALS = 10;
63
64 /**
laurentlb92c43cd2019-02-18 08:27:55 -080065 * Checks that a randomly generated {@link StarlarkSemanticsOptions} object can be converted to a
laurentlb6659b4c2019-02-18 07:23:36 -080066 * {@link StarlarkSemantics} object with the same field values.
brandjon60be5312017-10-04 23:06:41 +020067 */
68 @Test
69 public void optionsToSemantics() throws Exception {
70 for (int i = 0; i < NUM_RANDOM_TRIALS; i++) {
71 long seed = i;
laurentlb92c43cd2019-02-18 08:27:55 -080072 StarlarkSemanticsOptions options = buildRandomOptions(new Random(seed));
laurentlb6659b4c2019-02-18 07:23:36 -080073 StarlarkSemantics semantics = buildRandomSemantics(new Random(seed));
gregce3eb74022020-05-14 10:50:09 -070074 StarlarkSemantics semanticsFromOptions = options.toStarlarkSemantics();
brandjon60be5312017-10-04 23:06:41 +020075 assertThat(semanticsFromOptions).isEqualTo(semantics);
76 }
77 }
78
brandjon6ac92f92017-12-06 13:57:15 -080079 /**
laurentlb6659b4c2019-02-18 07:23:36 -080080 * Checks that a randomly generated {@link StarlarkSemantics} object can be serialized and
brandjon60be5312017-10-04 23:06:41 +020081 * deserialized to an equivalent object.
82 */
83 @Test
84 public void serializationRoundTrip() throws Exception {
plf504a6d22018-07-31 08:41:20 -070085 DynamicCodec codec = new DynamicCodec(buildRandomSemantics(new Random(2)).getClass());
brandjon60be5312017-10-04 23:06:41 +020086 for (int i = 0; i < NUM_RANDOM_TRIALS; i++) {
laurentlb6659b4c2019-02-18 07:23:36 -080087 StarlarkSemantics semantics = buildRandomSemantics(new Random(i));
88 StarlarkSemantics deserialized =
89 (StarlarkSemantics)
90 TestUtils.fromBytes(
91 new DeserializationContext(ImmutableMap.of()),
92 codec,
93 TestUtils.toBytes(new SerializationContext(ImmutableMap.of()), codec, semantics));
brandjon60be5312017-10-04 23:06:41 +020094 assertThat(deserialized).isEqualTo(semantics);
95 }
96 }
97
98 @Test
99 public void checkDefaultsMatch() {
laurentlb92c43cd2019-02-18 08:27:55 -0800100 StarlarkSemanticsOptions defaultOptions = Options.getDefaults(StarlarkSemanticsOptions.class);
adonovanb85d0b72020-05-08 11:59:19 -0700101 StarlarkSemantics defaultSemantics = StarlarkSemantics.DEFAULT;
gregce3eb74022020-05-14 10:50:09 -0700102 StarlarkSemantics semanticsFromOptions = defaultOptions.toStarlarkSemantics();
brandjon60be5312017-10-04 23:06:41 +0200103 assertThat(semanticsFromOptions).isEqualTo(defaultSemantics);
104 }
105
brandjon6ac92f92017-12-06 13:57:15 -0800106 @Test
107 public void canGetBuilderFromInstance() {
adonovanb85d0b72020-05-08 11:59:19 -0700108 StarlarkSemantics original = StarlarkSemantics.DEFAULT;
gregce3eb74022020-05-14 10:50:09 -0700109 assertThat(original.internalStarlarkFlagTestCanary()).isFalse();
110 StarlarkSemantics modified = original.toBuilder().internalStarlarkFlagTestCanary(true).build();
111 assertThat(modified.internalStarlarkFlagTestCanary()).isTrue();
brandjon6ac92f92017-12-06 13:57:15 -0800112 }
113
brandjon60be5312017-10-04 23:06:41 +0200114 /**
laurentlb92c43cd2019-02-18 08:27:55 -0800115 * Constructs a {@link StarlarkSemanticsOptions} object with random fields. Must access {@code
brandjon60be5312017-10-04 23:06:41 +0200116 * rand} using the same sequence of operations (for the same fields) as {@link
117 * #buildRandomSemantics}.
118 */
laurentlb92c43cd2019-02-18 08:27:55 -0800119 private static StarlarkSemanticsOptions buildRandomOptions(Random rand) throws Exception {
brandjon60be5312017-10-04 23:06:41 +0200120 return parseOptions(
121 // <== Add new options here in alphabetic order ==>
cparsons2b6a4352019-10-28 16:30:34 -0700122 "--experimental_action_args=" + rand.nextBoolean(),
lberki015f5862020-02-20 10:08:29 -0800123 "--experimental_disable_external_package=" + rand.nextBoolean(),
Jingwen Chen63605572020-02-13 13:47:00 -0800124 "--experimental_sibling_repository_layout=" + rand.nextBoolean(),
Googler137019f2019-04-23 02:23:37 -0700125 "--experimental_allow_incremental_repository_updates=" + rand.nextBoolean(),
brandjon6c5f9112020-05-27 08:28:39 -0700126 "--experimental_builtins_bzl_path=" + rand.nextDouble(),
plf7e41f9b2018-08-03 01:47:22 -0700127 "--experimental_cc_skylark_api_enabled_packages="
128 + rand.nextDouble()
129 + ","
130 + rand.nextDouble(),
Googlerc2cd9572018-10-02 14:38:15 -0700131 "--experimental_enable_android_migration_apis=" + rand.nextBoolean(),
cparsonsed6bfbe2019-04-19 10:17:03 -0700132 "--experimental_google_legacy_api=" + rand.nextBoolean(),
ichern585647e2020-01-15 00:37:44 -0800133 "--experimental_ninja_actions=" + rand.nextBoolean(),
cparsons140c0762018-10-05 14:07:19 -0700134 "--experimental_platforms_api=" + rand.nextBoolean(),
cparsonse0efc142018-10-17 09:39:10 -0700135 "--experimental_starlark_config_transitions=" + rand.nextBoolean(),
Googler57363812019-05-28 07:24:13 -0700136 "--experimental_starlark_unused_inputs_list=" + rand.nextBoolean(),
Googler7450e102019-11-26 13:52:51 -0800137 "--incompatible_allow_tags_propagation=" + rand.nextBoolean(), // flag, Java names differ
plfd6c87662019-11-05 01:14:03 -0800138 "--experimental_cc_shared_library=" + rand.nextBoolean(),
buchgr755e29d2019-11-19 05:34:15 -0800139 "--experimental_repo_remote_exec=" + rand.nextBoolean(),
juliexxia1dbf8542020-03-24 08:41:57 -0700140 "--experimental_exec_groups=" + rand.nextBoolean(),
Googler7450e102019-11-26 13:52:51 -0800141 "--incompatible_always_check_depset_elements=" + rand.nextBoolean(),
aiuto8ea115e2020-01-31 13:19:58 -0800142 "--incompatible_applicable_licenses=" + rand.nextBoolean(),
plf0d40b7f2019-04-29 08:09:11 -0700143 "--incompatible_depset_for_libraries_to_link_getter=" + rand.nextBoolean(),
cparsonsf1ee74d2019-07-31 07:09:53 -0700144 "--incompatible_disable_target_provider_fields=" + rand.nextBoolean(),
cparsonse5068582018-07-16 13:33:33 -0700145 "--incompatible_disable_deprecated_attr_params=" + rand.nextBoolean(),
cparsonsf0cf2b42019-08-15 10:56:40 -0700146 "--incompatible_disable_depset_items=" + rand.nextBoolean(),
gregce4aa059a2019-02-26 13:20:47 -0800147 "--incompatible_disable_third_party_license_checking=" + rand.nextBoolean(),
laurentlb9bc841e2019-05-28 05:59:35 -0700148 "--incompatible_disallow_empty_glob=" + rand.nextBoolean(),
Marwan Tammam7150aab2019-07-11 08:40:40 -0700149 "--incompatible_disallow_struct_provider_syntax=" + rand.nextBoolean(),
plf0d40b7f2019-04-29 08:09:11 -0700150 "--incompatible_do_not_split_linking_cmdline=" + rand.nextBoolean(),
plf906f5f12020-03-06 05:44:46 -0800151 "--incompatible_linkopts_to_linklibs=" + rand.nextBoolean(),
brandjon60be5312017-10-04 23:06:41 +0200152 "--incompatible_new_actions_api=" + rand.nextBoolean(),
laurentlbd8d37762018-10-26 14:08:33 -0700153 "--incompatible_no_attr_license=" + rand.nextBoolean(),
Klaus Aehlig2bb1bf92019-10-31 10:28:44 -0700154 "--incompatible_no_implicit_file_export=" + rand.nextBoolean(),
cparsons36c70a62019-06-07 09:31:14 -0700155 "--incompatible_no_rule_outputs_param=" + rand.nextBoolean(),
tomluaaf11e92018-06-02 10:20:16 -0700156 "--incompatible_no_support_tools_in_action_inputs=" + rand.nextBoolean(),
cparsonsc750f972019-06-13 15:52:40 -0700157 "--incompatible_run_shell_command_string=" + rand.nextBoolean(),
Gustav Westling00ea8fa2020-05-01 06:49:01 -0700158 "--incompatible_string_replace_count=" + rand.nextBoolean(),
Klaus Aehlig752ffcc2019-10-31 02:49:39 -0700159 "--incompatible_visibility_private_attributes_at_definition=" + rand.nextBoolean(),
plf8efc50e2020-02-25 07:11:14 -0800160 "--incompatible_require_linker_input_cc_api=" + rand.nextBoolean(),
Marwan Tammam20c84132019-06-04 07:27:31 -0700161 "--incompatible_restrict_string_escapes=" + rand.nextBoolean(),
hlopko23f052f2019-11-15 06:55:09 -0800162 "--incompatible_use_cc_configure_from_rules_cc=" + rand.nextBoolean(),
gregcec1c613d2020-06-09 09:11:37 -0700163 "--internal_starlark_flag_test_canary=" + rand.nextBoolean(),
adonovan553a0e42020-03-18 13:46:47 -0700164 "--max_computation_steps=" + rand.nextLong(),
adonovan40a737c2020-03-11 14:32:19 -0700165 "--record_rule_instantiation_callstack=" + rand.nextBoolean());
brandjon60be5312017-10-04 23:06:41 +0200166 }
167
168 /**
laurentlb6659b4c2019-02-18 07:23:36 -0800169 * Constructs a {@link StarlarkSemantics} object with random fields. Must access {@code rand}
170 * using the same sequence of operations (for the same fields) as {@link #buildRandomOptions}.
brandjon60be5312017-10-04 23:06:41 +0200171 */
laurentlb6659b4c2019-02-18 07:23:36 -0800172 private static StarlarkSemantics buildRandomSemantics(Random rand) {
173 return StarlarkSemantics.builder()
brandjon60be5312017-10-04 23:06:41 +0200174 // <== Add new options here in alphabetic order ==>
cparsons2b6a4352019-10-28 16:30:34 -0700175 .experimentalActionArgs(rand.nextBoolean())
lberki015f5862020-02-20 10:08:29 -0800176 .experimentalDisableExternalPackage(rand.nextBoolean())
Jingwen Chen63605572020-02-13 13:47:00 -0800177 .experimentalSiblingRepositoryLayout(rand.nextBoolean())
Googler137019f2019-04-23 02:23:37 -0700178 .experimentalAllowIncrementalRepositoryUpdates(rand.nextBoolean())
brandjon6c5f9112020-05-27 08:28:39 -0700179 .experimentalBuiltinsBzlPath(String.valueOf(rand.nextDouble()))
gregce3eb74022020-05-14 10:50:09 -0700180 .experimentalCcStarlarkApiEnabledPackages(
plf7e41f9b2018-08-03 01:47:22 -0700181 ImmutableList.of(String.valueOf(rand.nextDouble()), String.valueOf(rand.nextDouble())))
Googlerc2cd9572018-10-02 14:38:15 -0700182 .experimentalEnableAndroidMigrationApis(rand.nextBoolean())
cparsonsed6bfbe2019-04-19 10:17:03 -0700183 .experimentalGoogleLegacyApi(rand.nextBoolean())
ichern585647e2020-01-15 00:37:44 -0800184 .experimentalNinjaActions(rand.nextBoolean())
cparsons140c0762018-10-05 14:07:19 -0700185 .experimentalPlatformsApi(rand.nextBoolean())
cparsonse0efc142018-10-17 09:39:10 -0700186 .experimentalStarlarkConfigTransitions(rand.nextBoolean())
Googler57363812019-05-28 07:24:13 -0700187 .experimentalStarlarkUnusedInputsList(rand.nextBoolean())
ishikhman7e837212019-08-21 03:22:35 -0700188 .experimentalAllowTagsPropagation(rand.nextBoolean())
plfd6c87662019-11-05 01:14:03 -0800189 .experimentalCcSharedLibrary(rand.nextBoolean())
buchgr755e29d2019-11-19 05:34:15 -0800190 .experimentalRepoRemoteExec(rand.nextBoolean())
juliexxia1dbf8542020-03-24 08:41:57 -0700191 .experimentalExecGroups(rand.nextBoolean())
Googler7450e102019-11-26 13:52:51 -0800192 .incompatibleAlwaysCheckDepsetElements(rand.nextBoolean())
aiuto8ea115e2020-01-31 13:19:58 -0800193 .incompatibleApplicableLicenses(rand.nextBoolean())
plf0d40b7f2019-04-29 08:09:11 -0700194 .incompatibleDepsetForLibrariesToLinkGetter(rand.nextBoolean())
cparsonsf1ee74d2019-07-31 07:09:53 -0700195 .incompatibleDisableTargetProviderFields(rand.nextBoolean())
cparsonse5068582018-07-16 13:33:33 -0700196 .incompatibleDisableDeprecatedAttrParams(rand.nextBoolean())
cparsonsf0cf2b42019-08-15 10:56:40 -0700197 .incompatibleDisableDepsetItems(rand.nextBoolean())
gregce4aa059a2019-02-26 13:20:47 -0800198 .incompatibleDisableThirdPartyLicenseChecking(rand.nextBoolean())
laurentlb9bc841e2019-05-28 05:59:35 -0700199 .incompatibleDisallowEmptyGlob(rand.nextBoolean())
Marwan Tammam7150aab2019-07-11 08:40:40 -0700200 .incompatibleDisallowStructProviderSyntax(rand.nextBoolean())
plf0d40b7f2019-04-29 08:09:11 -0700201 .incompatibleDoNotSplitLinkingCmdline(rand.nextBoolean())
plf906f5f12020-03-06 05:44:46 -0800202 .incompatibleLinkoptsToLinkLibs(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200203 .incompatibleNewActionsApi(rand.nextBoolean())
laurentlbd8d37762018-10-26 14:08:33 -0700204 .incompatibleNoAttrLicense(rand.nextBoolean())
Klaus Aehlig2bb1bf92019-10-31 10:28:44 -0700205 .incompatibleNoImplicitFileExport(rand.nextBoolean())
cparsons36c70a62019-06-07 09:31:14 -0700206 .incompatibleNoRuleOutputsParam(rand.nextBoolean())
tomluaaf11e92018-06-02 10:20:16 -0700207 .incompatibleNoSupportToolsInActionInputs(rand.nextBoolean())
cparsonsc750f972019-06-13 15:52:40 -0700208 .incompatibleRunShellCommandString(rand.nextBoolean())
Gustav Westling00ea8fa2020-05-01 06:49:01 -0700209 .incompatibleStringReplaceCount(rand.nextBoolean())
Klaus Aehlig752ffcc2019-10-31 02:49:39 -0700210 .incompatibleVisibilityPrivateAttributesAtDefinition(rand.nextBoolean())
plf8efc50e2020-02-25 07:11:14 -0800211 .incompatibleRequireLinkerInputCcApi(rand.nextBoolean())
Marwan Tammam20c84132019-06-04 07:27:31 -0700212 .incompatibleRestrictStringEscapes(rand.nextBoolean())
hlopko23f052f2019-11-15 06:55:09 -0800213 .incompatibleUseCcConfigureFromRulesCc(rand.nextBoolean())
gregce3eb74022020-05-14 10:50:09 -0700214 .internalStarlarkFlagTestCanary(rand.nextBoolean())
adonovan553a0e42020-03-18 13:46:47 -0700215 .maxComputationSteps(rand.nextLong())
adonovan40a737c2020-03-11 14:32:19 -0700216 .recordRuleInstantiationCallstack(rand.nextBoolean())
brandjon60be5312017-10-04 23:06:41 +0200217 .build();
218 }
219
laurentlb92c43cd2019-02-18 08:27:55 -0800220 private static StarlarkSemanticsOptions parseOptions(String... args) throws Exception {
jcatere4545fe2019-06-19 07:43:02 -0700221 OptionsParser parser =
222 OptionsParser.builder()
223 .optionsClasses(StarlarkSemanticsOptions.class)
224 .allowResidue(false)
225 .build();
brandjon60be5312017-10-04 23:06:41 +0200226 parser.parse(Arrays.asList(args));
laurentlb92c43cd2019-02-18 08:27:55 -0800227 return parser.getOptions(StarlarkSemanticsOptions.class);
brandjon60be5312017-10-04 23:06:41 +0200228 }
229}