Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions taskcluster/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ workers:
implementation: docker-worker
os: linux
worker-type: linux-docker
t-windows:
provisioner: 'taskgraph-t'
implementation: generic-worker
os: windows
worker-type: win11-64-24h2
29 changes: 23 additions & 6 deletions taskcluster/kinds/test/kind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,59 @@ task-defaults:
artifact_prefix: public
retrigger: true
code-review: true
worker-type: t-linux
worker:
docker-image: {in-tree: python}
max-run-time: 1800
env:
LC_ALL: "C"
PYTHONUTF8: "0"
PYTHONCOERCECLOCALE: "0"
HGENCODING: "utf-8"
treeherder:
kind: test
platform: test/opt
tier: 1
run:
using: run-task
cwd: '{checkout}'
use-caches: [checkout, uv]

tasks:
unit:
description: "Run unit tests with py{matrix[python]}"
unit-linux:
description: "Run unit tests with py{matrix[python]} on Linux"
matrix:
set-name: "unit-py{matrix[python]}"
substitution-fields: [description, run.command, treeherder, worker, attributes]
python: ["314t", "314", "313", "312", "311", "310", "39"]
attributes:
python: "{matrix[python]}"
platform: linux
worker-type: t-linux
worker:
docker-image: {in-tree: python}
artifacts:
- type: file
path: "/builds/worker/artifacts/coverage"
name: "public/coverage.py{matrix[python]}"
env:
LC_ALL: "C"
UV_PYTHON: "{matrix[python]}"
treeherder:
platform: test-linux/opt
symbol: unit(py{matrix[python]})
run:
command: >-
uv run coverage run --data-file /builds/worker/artifacts/coverage --context=py{matrix[python]} -m pytest -vv

unit-win:
description: "Run unit tests with python on Windows"
attributes:
platform: windows
worker-type: t-windows
worker:
taskcluster-proxy: true
treeherder:
platform: test-win/opt
symbol: unit(py)
run:
command: >-
python3 -V &&
powershell -ExecutionPolicy ByPass -c 'irm https://astral.sh/uv/install.ps1 | iex' &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fyi there's an exec-with: powershell key you could add here to just execute the payload via powershell entirely:
https://github.com/taskcluster/taskgraph/blob/main/src/taskgraph/transforms/run/run_task.py#L80

Just mentioning it in case you weren't aware and this somehow makes things easier. The solution you ended up with is totally fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL - that's useful to know. I think I'll stick with what I have, partly because I know it works, and partly because the powershell is only there because it's the recommended way to install uv on Windows. Keeping this bash-oriented is useful for consistency, I think.

~/.local/bin/uv.exe run -m pytest -vv
7 changes: 7 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import platform
from pathlib import Path

import pytest
Expand All @@ -16,6 +17,12 @@
# no way to ignore ~/.gitconfig other than overriding $HOME, which is overkill.
os.environ["GIT_CONFIG_NOSYSTEM"] = "1"

# Some of the tests marked with this may be fixable on Windows; we should
# look into these in more depth at some point.
nowin = pytest.mark.skipif(
platform.system() == "Windows", reason="test currently broken on Windows"
)


@pytest.fixture
def responses():
Expand Down
3 changes: 3 additions & 0 deletions test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

from taskgraph.config import GraphConfig

from .conftest import nowin


def test_graph_config_basic():
graph_config = GraphConfig({"foo": "bar"}, "root")
Expand Down Expand Up @@ -50,6 +52,7 @@ def test_vcs_root_with_non_standard_dir():
assert vcs_root == expected_path


@nowin
def test_vcs_root_fallback(mocker):
mocker.patch("os.getcwd", return_value="/path/to/repo")

Expand Down
19 changes: 19 additions & 0 deletions test/test_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from taskgraph.transforms.docker_image import IMAGE_BUILDER_IMAGE
from taskgraph.util.vcs import get_repository

from .conftest import nowin


@pytest.fixture
def root_url():
Expand Down Expand Up @@ -112,6 +114,7 @@ def test_load_task_invalid_task(run_load_task):
assert run_load_task(task)[0] == 1


@nowin
def test_load_task(run_load_task):
image_task_id = "def"
task = {
Expand Down Expand Up @@ -172,6 +175,7 @@ def test_load_task(run_load_task):
assert exp == actual[i]


@nowin
def test_load_task_env_init_and_remove(mocker, run_load_task):
# Mock NamedTemporaryFile to capture what's written to it
mock_envfile = mocker.MagicMock()
Expand Down Expand Up @@ -252,6 +256,7 @@ def test_load_task_env_init_and_remove(mocker, run_load_task):
assert actual[6:8] == ["-v", "/tmp/test_initfile:/builds/worker/.bashrc"]


@nowin
@pytest.mark.parametrize(
"image",
[
Expand Down Expand Up @@ -292,6 +297,7 @@ def test_load_task_with_different_image_types(
mocks["load_image_by_task_id"].assert_called_once_with(image_task_id)


@nowin
def test_load_task_with_local_image(
mocker,
run_load_task,
Expand Down Expand Up @@ -322,6 +328,7 @@ def test_load_task_with_local_image(
assert mocks["build_image"].call_args[0][1] == "hello-world"


@nowin
def test_load_task_with_unsupported_image_type(caplog, run_load_task):
caplog.set_level(logging.DEBUG)
task = {
Expand All @@ -343,6 +350,7 @@ def test_load_task_with_unsupported_image_type(caplog, run_load_task):
assert "Tasks with unsupported-type images are not supported!" in caplog.text


@nowin
def test_load_task_with_task_definition(run_load_task, caplog):
# Test passing a task definition directly instead of a task ID
caplog.set_level(logging.INFO)
Expand Down Expand Up @@ -372,6 +380,7 @@ def test_load_task_with_task_definition(run_load_task, caplog):
assert "Loading 'test-task-direct' from provided definition" in caplog.text


@nowin
def test_load_task_with_interactive_false(run_load_task):
# Test non-interactive mode that doesn't require run-task
# Task that doesn't use run-task (would fail in interactive mode)
Expand Down Expand Up @@ -427,6 +436,7 @@ def task():
}


@nowin
def test_load_task_with_custom_image_in_tree(run_load_task, task):
image = "hello-world"
ret, mocks = run_load_task(task, custom_image=image)
Expand All @@ -453,13 +463,15 @@ def test_load_task_with_custom_image_in_tree(run_load_task, task):
assert tag == f"taskcluster/{image}:latest"


@nowin
def test_load_task_with_custom_image_task_id(run_load_task, task):
image = "task-id=abc"
ret, mocks = run_load_task(task, custom_image=image)
assert ret == 0
mocks["load_image_by_task_id"].assert_called_once_with("abc")


@nowin
def test_load_task_with_custom_image_index(mocker, run_load_task, task):
image = "index=abc"
mocker.patch.object(docker, "find_task_id", return_value="abc")
Expand All @@ -468,6 +480,7 @@ def test_load_task_with_custom_image_index(mocker, run_load_task, task):
mocks["load_image_by_task_id"].assert_called_once_with("abc")


@nowin
def test_load_task_with_custom_image_registry(mocker, run_load_task, task):
image = "ubuntu:latest"
ret, mocks = run_load_task(task, custom_image=image)
Expand All @@ -476,6 +489,7 @@ def test_load_task_with_custom_image_registry(mocker, run_load_task, task):
assert not mocks["build_image"].called


@nowin
def test_load_task_with_develop(mocker, run_load_task, task):
repo_name = "foo"
repo_path = "/workdir/vcs"
Expand Down Expand Up @@ -623,6 +637,7 @@ def mock_path_constructor(path_arg):
return inner


@nowin
def test_build_image(run_build_image):
# Test building image without save_image
result, mocks = run_build_image("hello-world")
Expand Down Expand Up @@ -654,6 +669,7 @@ def test_build_image(run_build_image):
assert result == "hello-world:latest"


@nowin
def test_build_image_with_parent(mocker, responses, root_url, run_build_image):
parent_task_id = "abc"
responses.get(f"{root_url}/api/queue/v1/task/{parent_task_id}/status")
Expand Down Expand Up @@ -687,6 +703,7 @@ def test_build_image_with_parent(mocker, responses, root_url, run_build_image):
assert docker_load_args[:3] == ["docker", "load", "-i"]


@nowin
def test_build_image_with_parent_not_found(
mocker, responses, root_url, run_build_image
):
Expand Down Expand Up @@ -725,6 +742,7 @@ def test_build_image_with_parent_not_found(
assert docker_load_args[:3] == ["docker", "load", "-i"]


@nowin
def test_build_image_with_save_image(run_build_image):
save_path = "/path/to/save.tar"

Expand All @@ -741,6 +759,7 @@ def test_build_image_with_save_image(run_build_image):
assert save_path in str(result)


@nowin
def test_build_image_context_only(run_build_image):
context_path = "/path/to/context.tar"

Expand Down
3 changes: 3 additions & 0 deletions test/test_scripts_run_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import taskgraph
from taskgraph.util.caches import CACHES

from .conftest import nowin


@pytest.fixture(scope="module")
def run_task_mod():
Expand Down Expand Up @@ -617,6 +619,7 @@ def inner(extra_args=None, env=None):
return inner


@nowin
def test_main_abspath_environment(mocker, run_main):
envvars = ["GECKO_PATH", "MOZ_FETCHES_DIR", "UPLOAD_DIR"]
envvars += [cache["env"] for cache in CACHES.values() if "env" in cache]
Expand Down
3 changes: 3 additions & 0 deletions test/test_transforms_run_toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from taskgraph.util.templates import merge
from taskgraph.util.vcs import GitRepository

from .conftest import nowin

TASK_DEFAULTS = {
"description": "fake description",
"label": "fake-task-label",
Expand Down Expand Up @@ -205,6 +207,7 @@ def assert_relative_script(task, taskdesc):
assert_docker_worker(task, taskdesc)


@nowin
@pytest.mark.parametrize(
"task",
(
Expand Down
7 changes: 7 additions & 0 deletions test/test_util_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
create_tar_gz_from_files,
)

from .conftest import nowin

MODE_STANDARD = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH


Expand Down Expand Up @@ -72,6 +74,7 @@ def test_dirs_refused(tmp_path):
create_tar_from_files(fh, {"test": str(tmp_path)})


@nowin
def test_setuid_setgid_refused(tmp_path):
uid = tmp_path / "setuid"
uid.touch()
Expand All @@ -89,6 +92,7 @@ def test_setuid_setgid_refused(tmp_path):
create_tar_from_files(fh, {"test": str(gid)})


@nowin
def test_create_tar_basic(tmp_path, create_files):
files = create_files()

Expand All @@ -103,6 +107,7 @@ def test_create_tar_basic(tmp_path, create_files):
verify_basic_tarfile(tf)


@nowin
def test_executable_preserved(tmp_path):
p = tmp_path / "exec"
p.write_bytes(b"#!/bin/bash\n")
Expand All @@ -129,6 +134,7 @@ def test_executable_preserved(tmp_path):
assert extracted_content == b"#!/bin/bash\n"


@nowin
def test_create_tar_gz_basic(tmp_path, create_files):
gp = tmp_path / "test.tar.gz"
with open(gp, "wb") as fh:
Expand Down Expand Up @@ -156,6 +162,7 @@ def test_create_tar_gz_basic(tmp_path, create_files):
verify_basic_tarfile(tf)


@nowin
def test_tar_gz_name(tmp_path, create_files):
gp = tmp_path / "test.tar.gz"
with open(gp, "wb") as fh:
Expand Down
Loading
Loading