From 5dd3a29bb5828403545c1d2f4465b1bdb4cd9728 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Fri, 24 Oct 2025 11:14:45 +0200 Subject: [PATCH] fix: get_taskcluster_client should respect PRODUCTION_TASKCLUSTER_ROOT_URL If no root url is set in the environment but PRODUCTION_TASKCLUSTER_ROOT_URL is set, we should use that. See https://bugzilla.mozilla.org/show_bug.cgi?id=1996183 --- src/taskgraph/util/taskcluster.py | 2 +- test/test_util_taskcluster.py | 55 ++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/taskgraph/util/taskcluster.py b/src/taskgraph/util/taskcluster.py index 17ce6f9a5..1560ff7c5 100644 --- a/src/taskgraph/util/taskcluster.py +++ b/src/taskgraph/util/taskcluster.py @@ -65,7 +65,7 @@ def get_taskcluster_client(service: str): if "TASKCLUSTER_PROXY_URL" in os.environ: options = {"rootUrl": os.environ["TASKCLUSTER_PROXY_URL"]} else: - options = taskcluster.optionsFromEnvironment() + options = taskcluster.optionsFromEnvironment({"rootUrl": get_root_url()}) return getattr(taskcluster, service[0].upper() + service[1:])(options) diff --git a/test/test_util_taskcluster.py b/test/test_util_taskcluster.py index bdff659e6..6d9e7d3a5 100644 --- a/test/test_util_taskcluster.py +++ b/test/test_util_taskcluster.py @@ -3,7 +3,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import datetime -import os +from unittest.mock import MagicMock import pytest @@ -19,13 +19,8 @@ def root_url(): @pytest.fixture(autouse=True) def mock_environ(monkeypatch, root_url): # Ensure user specified environment variables don't interfere with URLs. - monkeypatch.setattr( - os, - "environ", - { - "TASKCLUSTER_ROOT_URL": root_url, - }, - ) + monkeypatch.setenv("TASKCLUSTER_ROOT_URL", root_url) + monkeypatch.delenv("TASKCLUSTER_PROXY_URL", raising=False) @pytest.fixture(autouse=True) @@ -566,3 +561,47 @@ def test_get_ancestors_string(responses, root_url): "eee": "task-eee", } assert got == expected, f"got: {got}, expected: {expected}" + + +def test_get_taskcluster_client(monkeypatch, root_url): + tc.get_root_url.cache_clear() + tc.get_taskcluster_client.cache_clear() + service_mock = MagicMock() + monkeypatch.setattr("taskcluster.Foo", service_mock, raising=False) + + # No environment and no default → error + monkeypatch.delenv("TASKCLUSTER_ROOT_URL", raising=False) + monkeypatch.delenv("TASKCLUSTER_PROXY_URL", raising=False) + monkeypatch.setattr(tc, "PRODUCTION_TASKCLUSTER_ROOT_URL", None) + with pytest.raises(RuntimeError): + tc.get_taskcluster_client("foo") + service_mock.assert_not_called() + + tc.get_root_url.cache_clear() + tc.get_taskcluster_client.cache_clear() + service_mock.reset_mock() + + # No environment, use default + monkeypatch.setattr( + tc, "PRODUCTION_TASKCLUSTER_ROOT_URL", "http://taskcluster-prod" + ) + tc.get_taskcluster_client("foo") + service_mock.assert_called_once_with({"rootUrl": "http://taskcluster-prod"}) + + tc.get_root_url.cache_clear() + tc.get_taskcluster_client.cache_clear() + service_mock.reset_mock() + + # root url from environment + monkeypatch.setenv("TASKCLUSTER_ROOT_URL", "http://taskcluster-env") + tc.get_taskcluster_client("foo") + service_mock.assert_called_once_with({"rootUrl": "http://taskcluster-env"}) + + tc.get_root_url.cache_clear() + tc.get_taskcluster_client.cache_clear() + service_mock.reset_mock() + + # proxy url from environment + monkeypatch.setenv("TASKCLUSTER_PROXY_URL", "http://taskcluster-proxy") + tc.get_taskcluster_client("foo") + service_mock.assert_called_once_with({"rootUrl": "http://taskcluster-proxy"})