Bug 1879159 - [tb-rust ci] Add some tests to verify it works. r=dandarnell
Differential Revision: https://phabricator.services.mozilla.com/D201839 --HG-- rename : taskcluster/comm_taskgraph/test/conftest.py => taskcluster/docker/tb-updatebot/vendor/test/conftest.py extra : amend_source : 13817df2d7b26d5c6da73febd2f367b390f0f9aa
This commit is contained in:
Родитель
5607540ba2
Коммит
019d4c418c
|
@ -8,7 +8,7 @@ COPY privileged-setup.sh /setup/privileged-setup.sh
|
|||
COPY setup.sh /builds/worker/setup.sh
|
||||
COPY requirements.txt /builds/worker/requirements.txt
|
||||
COPY hgrc /etc/mercurial/hgrc.d/updatebot.rc
|
||||
COPY vendor/* /builds/worker/vendor/
|
||||
COPY vendor/ /builds/worker/vendor/
|
||||
COPY moz-phab-config /builds/worker/.moz-phab-config
|
||||
|
||||
# %include comm/taskcluster/docker/recipes/make_venv.sh
|
||||
|
|
|
@ -3,3 +3,5 @@ pip-tools==7.3.0
|
|||
requests==2.31.0
|
||||
taskcluster==60.3.4
|
||||
taskcluster-urls==13.0.1
|
||||
pytest==8.0.0
|
||||
responses==0.24.1
|
||||
|
|
|
@ -49,6 +49,8 @@ idna==3.6
|
|||
# via
|
||||
# requests
|
||||
# yarl
|
||||
iniconfig==2.0.0
|
||||
# via pytest
|
||||
jinja2==3.1.3
|
||||
# via glean-parser
|
||||
jsonschema==4.21.1
|
||||
|
@ -71,14 +73,19 @@ packaging==23.2
|
|||
# via
|
||||
# build
|
||||
# mozphab
|
||||
# pytest
|
||||
pathspec==0.12.1
|
||||
# via yamllint
|
||||
pip-tools==7.3.0
|
||||
# via -r requirements.in
|
||||
pluggy==1.4.0
|
||||
# via pytest
|
||||
pycparser==2.21
|
||||
# via cffi
|
||||
pyproject-hooks==1.0.0
|
||||
# via build
|
||||
pytest==8.0.0
|
||||
# via -r requirements.in
|
||||
python-dateutil==2.8.2
|
||||
# via taskcluster
|
||||
python-hglib==2.6.2
|
||||
|
@ -86,6 +93,7 @@ python-hglib==2.6.2
|
|||
pyyaml==6.0.1
|
||||
# via
|
||||
# glean-parser
|
||||
# responses
|
||||
# yamllint
|
||||
referencing==0.33.0
|
||||
# via
|
||||
|
@ -94,7 +102,10 @@ referencing==0.33.0
|
|||
requests==2.31.0
|
||||
# via
|
||||
# -r requirements.in
|
||||
# responses
|
||||
# taskcluster
|
||||
responses==0.24.1
|
||||
# via -r requirements.in
|
||||
rpds-py==0.17.1
|
||||
# via
|
||||
# jsonschema
|
||||
|
@ -116,6 +127,7 @@ taskcluster-urls==13.0.1
|
|||
urllib3==2.2.0
|
||||
# via
|
||||
# requests
|
||||
# responses
|
||||
# sentry-sdk
|
||||
wheel==0.42.0
|
||||
# via pip-tools
|
||||
|
|
|
@ -27,3 +27,6 @@ exec python3 -m vendor
|
|||
_EOF_
|
||||
|
||||
chmod +x "$HOME/bin/runme.sh"
|
||||
|
||||
# Run vendor unit tests
|
||||
"${VENV_DIR}/bin/pytest" -v --full-trace --color=no
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
from . import support # noqa: F401
|
||||
|
|
|
@ -57,7 +57,7 @@ class TaskClusterSecrets:
|
|||
def __init__(self, base_path: str):
|
||||
self.base_path = base_path
|
||||
|
||||
def get_secret(self, name: str) -> dict | str:
|
||||
def get_secret(self, name: str) -> Union[dict, str]:
|
||||
secret = None
|
||||
e_name = name.replace("-", "")
|
||||
if f"TASKCLUSTER_SECRET_{e_name}" in os.environ:
|
||||
|
@ -98,7 +98,7 @@ def write_arcrc(phabricator_url: str, phabricator_token: str):
|
|||
arc_filename = Path.home() / ".arcrc"
|
||||
arc_json = {"hosts": {phabricator_url: phabricator_token}}
|
||||
with open(arc_filename, "w") as arcrc:
|
||||
json.dump(arc_json, arcrc)
|
||||
arcrc.write(json.dumps(arc_json))
|
||||
os.chmod(arc_filename, stat.S_IRUSR | stat.S_IWUSR)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
HERE = os.path.dirname(__file__)
|
||||
EXT_PATH = os.path.abspath(os.path.join(HERE, "..", ".."))
|
||||
|
||||
sys.path.insert(0, EXT_PATH)
|
|
@ -0,0 +1,139 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, # You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, mock_open, patch
|
||||
|
||||
import conftest # noqa: F401
|
||||
import pytest
|
||||
import requests.exceptions
|
||||
import responses
|
||||
import vendor
|
||||
|
||||
|
||||
def stringio_open(*args, **kwargs):
|
||||
# Much of this borrowed from unittest.mock.mock_open
|
||||
import _io
|
||||
|
||||
open_spec = list(set(dir(_io.open)))
|
||||
file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))))
|
||||
mock = MagicMock(name="open", spec=open_spec)
|
||||
handle = MagicMock(name="handle", spec=file_spec)
|
||||
|
||||
_state = ["", None]
|
||||
|
||||
def _write_side_effect(data, *args, **kwargs):
|
||||
_state[0] = data
|
||||
|
||||
handle.write.side_effect = _write_side_effect
|
||||
handle.write.return_value = None
|
||||
|
||||
def _read_side_effect(*args, **kwargs):
|
||||
return _state[0]
|
||||
|
||||
handle.read.side_effect = _read_side_effect
|
||||
handle.read.return_value = None
|
||||
|
||||
handle.__enter__.return_value = handle
|
||||
mock.return_value = handle
|
||||
return mock
|
||||
|
||||
|
||||
@patch("vendor.support.Path.home", return_value=Path("/home"))
|
||||
@patch("vendor.support.os.chmod")
|
||||
def test_write_ssh_key(mock_home, mock_chmod):
|
||||
with patch("builtins.open", mock_open()) as m:
|
||||
vendor.support.write_ssh_key("dummy_file", "dummy_value")
|
||||
|
||||
mock_chmod.assert_called_once()
|
||||
m.assert_called_once_with(Path("/home") / "dummy_file", "w")
|
||||
handle = m()
|
||||
handle.write.assert_called_once_with("dummy_value")
|
||||
|
||||
|
||||
@patch("vendor.support.Path.home", return_value=Path("/home"))
|
||||
def test_hgrc_userinfo(mock_home):
|
||||
username = "username"
|
||||
keyfile = "/path/to/keyfile"
|
||||
with patch("builtins.open", stringio_open()) as m:
|
||||
vendor.support.write_hgrc_userinfo(username, Path(keyfile))
|
||||
|
||||
m.assert_called_once_with(Path("/home") / ".hgrc", "w")
|
||||
handle = m()
|
||||
written_lines = handle.read().split("\n")
|
||||
assert len(written_lines) == 4
|
||||
assert keyfile in written_lines[1]
|
||||
assert f"{username}@mozilla.com" in written_lines[2]
|
||||
|
||||
|
||||
@patch("vendor.support.Path.home", return_value=Path("/home"))
|
||||
@patch("vendor.support.os.chmod")
|
||||
def test_write_arcrc(mock_home, mock_chmod):
|
||||
phab_url = "https://bogus.example.zzz/"
|
||||
phab_token = "bogus_token"
|
||||
with patch("builtins.open", stringio_open()) as m:
|
||||
vendor.support.write_arcrc(phab_url, phab_token)
|
||||
|
||||
mock_chmod.assert_called_once()
|
||||
m.assert_called_once_with(Path("/home") / ".arcrc", "w")
|
||||
handle = m()
|
||||
written = handle.read()
|
||||
data = json.loads(written)
|
||||
assert "hosts" in data
|
||||
assert phab_url in data["hosts"]
|
||||
assert data["hosts"][phab_url] == phab_token
|
||||
|
||||
|
||||
@responses.activate
|
||||
@pytest.mark.parametrize(
|
||||
"task_id,artifact_path,body,status,expected",
|
||||
[
|
||||
pytest.param("AAAAAAA", "public/foo.txt", "D12345", 200, "D12345"),
|
||||
pytest.param("BBBBBBB", "public/checksums.json", '{"a": "b"}', 200, '{"a": "b"}'),
|
||||
pytest.param("CCCC404", "public/notfound.json", "", 404, None),
|
||||
pytest.param("DDDD401", "public/unauthorized.txt", "", 401, None),
|
||||
],
|
||||
)
|
||||
def test_fetch_indexed_artifact(task_id, artifact_path, body, status, expected):
|
||||
url = vendor.support.artifact_url(task_id, artifact_path)
|
||||
|
||||
responses.get(
|
||||
url,
|
||||
body=body,
|
||||
status=status,
|
||||
)
|
||||
if status in (200, 404):
|
||||
artifact = vendor.support.fetch_indexed_artifact(task_id, artifact_path)
|
||||
assert artifact == expected
|
||||
else:
|
||||
with pytest.raises(requests.exceptions.HTTPError):
|
||||
artifact = vendor.support.fetch_indexed_artifact(task_id, artifact_path)
|
||||
responses.assert_call_count(url, 1)
|
||||
|
||||
|
||||
class Repo:
|
||||
api_url = "https://api_url"
|
||||
dot_path = "dot_path"
|
||||
phab_url = "phab_url"
|
||||
path = "path"
|
||||
cvs = "git"
|
||||
|
||||
|
||||
conduit = vendor.support.ExtendedConduit()
|
||||
conduit.set_repo(Repo())
|
||||
|
||||
|
||||
class TestExtendedConduit:
|
||||
@staticmethod
|
||||
def _get_revisions(is_closed):
|
||||
return [{"fields": {"status": {"closed": is_closed}}}]
|
||||
|
||||
@patch("vendor.support.ExtendedConduit.get_revisions")
|
||||
def test_is_revision_open(self, mock_get_revisions):
|
||||
mock_get_revisions.return_value = self._get_revisions(True)
|
||||
assert not conduit.is_revision_open("D12345")
|
||||
|
||||
mock_get_revisions.return_value = self._get_revisions(False)
|
||||
assert conduit.is_revision_open("D12345")
|
Загрузка…
Ссылка в новой задаче