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:
Rob Lemley 2024-02-20 15:27:51 -05:00
Родитель 5607540ba2
Коммит 019d4c418c
8 изменённых файлов: 168 добавлений и 3 удалений

Просмотреть файл

@ -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)

7
taskcluster/docker/tb-updatebot/vendor/test/conftest.py поставляемый Normal file
Просмотреть файл

@ -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)

139
taskcluster/docker/tb-updatebot/vendor/test/test_support.py поставляемый Normal file
Просмотреть файл

@ -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")