diff --git a/src/scriptworker/config.py b/src/scriptworker/config.py index 244417d7..103edb88 100644 --- a/src/scriptworker/config.py +++ b/src/scriptworker/config.py @@ -125,11 +125,17 @@ def check_config(config, path): if key not in DEFAULT_CONFIG: messages.append("Unknown key {} in {}!".format(key, path)) continue + is_by_cot_product = isinstance(DEFAULT_CONFIG[key], Mapping) and "by-cot-product" in DEFAULT_CONFIG[key] if value is None: - messages.append(_VALUE_UNDEFINED_MESSAGE.format(path=path, key=key)) + if key != "cot_product" and not is_by_cot_product: + messages.append(_VALUE_UNDEFINED_MESSAGE.format(path=path, key=key)) else: value_type = type(value) - if isinstance(DEFAULT_CONFIG[key], Mapping) and "by-cot-product" in DEFAULT_CONFIG[key]: + if key == "cot_product": + # `cot_product`'s own default is `None`, so its type can't be + # inferred from `DEFAULT_CONFIG` the way other keys' can. + default_type = str + elif is_by_cot_product: default_type = type(DEFAULT_CONFIG[key]["by-cot-product"][config["cot_product"]]) else: default_type = type(DEFAULT_CONFIG[key]) @@ -139,6 +145,8 @@ def check_config(config, path): messages.append(_VALUE_UNDEFINED_MESSAGE.format(path=path, key=key)) if key in ("provisioner_id", "worker_group", "worker_type", "worker_id") and not _is_id_valid(value): messages.append('{} doesn\'t match "{}" (required by Taskcluster)'.format(key, _GENERIC_ID_REGEX.pattern)) + if config.get("cot_product") is None and config.get("verify_chain_of_trust"): + messages.append("{} verify_chain_of_trust can't be True when cot_product is not set!".format(path)) return messages @@ -161,6 +169,9 @@ def apply_product_config(config): for key in config: if isinstance(config[key], Mapping) and "by-cot-product" in config[key]: + if cot_product is None: + config[key] = None + continue try: config[key] = config[key]["by-cot-product"][cot_product] except KeyError: diff --git a/src/scriptworker/constants.py b/src/scriptworker/constants.py index 2ab6ea78..95f6d700 100644 --- a/src/scriptworker/constants.py +++ b/src/scriptworker/constants.py @@ -73,7 +73,7 @@ "verify_chain_of_trust": False, # TODO True "verify_cot_signature": False, "cot_job_type": "unknown", # e.g., signing - "cot_product": "firefox", + "cot_product": None, "cot_version": 3, "min_cot_version": 2, "max_chain_length": 20, diff --git a/tests/test_config.py b/tests/test_config.py index 693397c3..6de66d5c 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -117,6 +117,35 @@ def test_check_config_good(t_config): assert messages == [] +@pytest.mark.parametrize("cot_product", (None, "firefox")) +def test_check_config_good_by_cot_product(cot_product): + """`check_config` shouldn't flag false-positive type mismatches on + `by-cot-product`-keyed values, whether `cot_product` is unset or set to a + real product.""" + raw_config = dict(deepcopy(DEFAULT_CONFIG)) + raw_config["cot_product"] = cot_product + t_config = _fill_missing_values(config.apply_product_config(raw_config)) + messages = config.check_config(t_config, "test_path") + assert messages == [] + + +def test_check_config_verify_chain_of_trust_without_cot_product(t_config): + t_config = _fill_missing_values(t_config) + t_config["cot_product"] = None + t_config["verify_chain_of_trust"] = True + messages = config.check_config(t_config, "test_path") + assert "verify_chain_of_trust can't be True when cot_product is not set" in "\n".join(messages) + + +def test_check_config_verify_chain_of_trust_with_cot_product(): + raw_config = dict(deepcopy(DEFAULT_CONFIG)) + raw_config["cot_product"] = "firefox" + raw_config["verify_chain_of_trust"] = True + t_config = _fill_missing_values(config.apply_product_config(raw_config)) + messages = config.check_config(t_config, "test_path") + assert messages == [] + + # create_config {{{1 def test_create_config_missing_file(): with pytest.raises(SystemExit): @@ -226,3 +255,13 @@ def test_apply_product_config_unknown_product(): c = {"cot_product": "seamonkey", "keyed": {"by-cot-product": {"thunderbird": "expected", "firefox": "unexpected"}}} with pytest.raises(config.ConfigError): config.apply_product_config(c) + + +def test_apply_product_config_none_product(): + """ + `apply_product_config` resolves `by-cot-product`-keyed entries to `None` + when `cot_product` is not set. + """ + c = {"cot_product": None, "unkeyed": "no keys", "keyed": {"by-cot-product": {"thunderbird": "expected", "firefox": "unexpected"}}} + expected_config = {"cot_product": None, "unkeyed": "no keys", "keyed": None} + assert config.apply_product_config(dict(c)) == expected_config