Fixed cyclic dependencie AND swapped pytest-parallel for pytest-xdist to fix deadlock in tests
This commit is contained in:
@@ -11,7 +11,7 @@ from typing import Any, Optional, Tuple, get_origin
|
||||
|
||||
from clan_cli.dirs import machine_settings_file, specific_flake_dir
|
||||
from clan_cli.errors import ClanError
|
||||
from clan_cli.flakes.types import FlakeName
|
||||
from clan_cli.types import FlakeName
|
||||
from clan_cli.git import commit_file
|
||||
from clan_cli.nix import nix_eval
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ from clan_cli.dirs import (
|
||||
from clan_cli.git import commit_file, find_git_repo_root
|
||||
from clan_cli.nix import nix_eval
|
||||
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
|
||||
|
||||
def verify_machine_config(
|
||||
|
||||
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from .errors import ClanError
|
||||
from .flakes.types import FlakeName
|
||||
from .types import FlakeName
|
||||
|
||||
|
||||
def _get_clan_flake_toplevel() -> Path:
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Dict
|
||||
from ..async_cmd import CmdOut, run, runforcli
|
||||
from ..dirs import specific_flake_dir, specific_machine_dir
|
||||
from ..errors import ClanError
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from ..nix import nix_shell
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from ..dirs import specific_machine_dir
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
|
||||
|
||||
def machine_has_fact(flake_name: FlakeName, machine: str, fact: str) -> bool:
|
||||
|
||||
@@ -3,7 +3,7 @@ import logging
|
||||
import os
|
||||
|
||||
from ..dirs import machines_dir
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from .types import validate_hostname
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Callable
|
||||
|
||||
from ..dirs import specific_flake_dir
|
||||
from ..errors import ClanError
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
|
||||
|
||||
def get_sops_folder(flake_name: FlakeName) -> Path:
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
from pathlib import Path
|
||||
|
||||
from ..errors import ClanError
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from ..machines.types import machine_name_type, validate_hostname
|
||||
from . import secrets
|
||||
from .folders import (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import argparse
|
||||
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from ..machines.types import machine_name_type, validate_hostname
|
||||
from . import secrets
|
||||
from .folders import list_objects, remove_object, sops_machines_folder
|
||||
|
||||
@@ -8,7 +8,7 @@ from typing import IO
|
||||
|
||||
from .. import tty
|
||||
from ..errors import ClanError
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from .folders import (
|
||||
list_objects,
|
||||
sops_groups_folder,
|
||||
|
||||
@@ -9,7 +9,7 @@ from typing import IO, Iterator
|
||||
|
||||
from ..dirs import user_config_dir
|
||||
from ..errors import ClanError
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from ..nix import nix_shell
|
||||
from .folders import sops_machines_folder, sops_users_folder
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from clan_cli.nix import nix_shell
|
||||
|
||||
from ..dirs import specific_flake_dir
|
||||
from ..errors import ClanError
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from .folders import sops_secrets_folder
|
||||
from .machines import add_machine, has_machine
|
||||
from .secrets import decrypt_secret, encrypt_secret, has_secret
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import argparse
|
||||
|
||||
from ..flakes.types import FlakeName
|
||||
from ..types import FlakeName
|
||||
from . import secrets
|
||||
from .folders import list_objects, remove_object, sops_users_folder
|
||||
from .sops import read_key, write_key
|
||||
|
||||
@@ -10,7 +10,7 @@ from ...config.machine import (
|
||||
set_config_for_machine,
|
||||
verify_machine_config,
|
||||
)
|
||||
from ...flakes.types import FlakeName
|
||||
from ...types import FlakeName
|
||||
from ...machines.create import create_machine as _create_machine
|
||||
from ...machines.list import list_machines as _list_machines
|
||||
from ..api_outputs import (
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
, openssh
|
||||
, pytest
|
||||
, pytest-cov
|
||||
, pytest-xdist
|
||||
, pytest-subprocess
|
||||
, pytest-parallel
|
||||
, pytest-timeout
|
||||
@@ -45,7 +46,8 @@ let
|
||||
pytest
|
||||
pytest-cov
|
||||
pytest-subprocess
|
||||
pytest-parallel
|
||||
# pytest-parallel
|
||||
pytest-xdist
|
||||
pytest-timeout
|
||||
openssh
|
||||
git
|
||||
|
||||
@@ -14,9 +14,13 @@ exclude = ["clan_cli.nixpkgs*"]
|
||||
[tool.setuptools.package-data]
|
||||
clan_cli = [ "config/jsonschema/*", "webui/assets/**/*"]
|
||||
|
||||
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = "tests"
|
||||
faulthandler_timeout = 60
|
||||
addopts = "--cov . --cov-report term --cov-report html:.reports/html --no-cov-on-fail --workers auto --durations 5"
|
||||
log_level = "DEBUG"
|
||||
addopts = "--cov . --cov-report term --cov-report html:.reports/html --no-cov-on-fail -n auto --durations 5 --maxfail=1 --new-first"
|
||||
norecursedirs = "tests/helpers"
|
||||
markers = [ "impure" ]
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ mkShell {
|
||||
register-python-argcomplete --shell fish clan > $tmp_path/share/fish/vendor_completions.d/clan.fish
|
||||
register-python-argcomplete --shell bash clan > $tmp_path/share/bash-completion/completions/clan
|
||||
|
||||
./bin/clan machines create example
|
||||
./bin/clan flakes create example_clan
|
||||
./bin/clan machines create example_machine example_clan
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import pytest
|
||||
from root import CLAN_CORE
|
||||
|
||||
from clan_cli.dirs import nixpkgs_source
|
||||
from clan_cli.flakes.types import FlakeName
|
||||
from clan_cli.types import FlakeName
|
||||
|
||||
|
||||
# substitutes string sin a file.
|
||||
@@ -28,7 +28,7 @@ def substitute(
|
||||
print(line, end="")
|
||||
|
||||
|
||||
class TestFlake(NamedTuple):
|
||||
class FlakeForTest(NamedTuple):
|
||||
name: FlakeName
|
||||
path: Path
|
||||
|
||||
@@ -39,7 +39,7 @@ def create_flake(
|
||||
clan_core_flake: Path | None = None,
|
||||
machines: list[str] = [],
|
||||
remote: bool = False,
|
||||
) -> Iterator[TestFlake]:
|
||||
) -> Iterator[FlakeForTest]:
|
||||
"""
|
||||
Creates a flake with the given name and machines.
|
||||
The machine names map to the machines in ./test_machines
|
||||
@@ -66,20 +66,20 @@ def create_flake(
|
||||
with tempfile.TemporaryDirectory() as workdir:
|
||||
monkeypatch.chdir(workdir)
|
||||
monkeypatch.setenv("HOME", str(home))
|
||||
yield TestFlake(flake_name, flake)
|
||||
yield FlakeForTest(flake_name, flake)
|
||||
else:
|
||||
monkeypatch.chdir(flake)
|
||||
monkeypatch.setenv("HOME", str(home))
|
||||
yield TestFlake(flake_name, flake)
|
||||
yield FlakeForTest(flake_name, flake)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_flake(monkeypatch: pytest.MonkeyPatch) -> Iterator[TestFlake]:
|
||||
def test_flake(monkeypatch: pytest.MonkeyPatch) -> Iterator[FlakeForTest]:
|
||||
yield from create_flake(monkeypatch, FlakeName("test_flake"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_flake_with_core(monkeypatch: pytest.MonkeyPatch) -> Iterator[TestFlake]:
|
||||
def test_flake_with_core(monkeypatch: pytest.MonkeyPatch) -> Iterator[FlakeForTest]:
|
||||
if not (CLAN_CORE / "flake.nix").exists():
|
||||
raise Exception(
|
||||
"clan-core flake not found. This test requires the clan-core flake to be present"
|
||||
@@ -90,7 +90,7 @@ def test_flake_with_core(monkeypatch: pytest.MonkeyPatch) -> Iterator[TestFlake]
|
||||
@pytest.fixture
|
||||
def test_flake_with_core_and_pass(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> Iterator[TestFlake]:
|
||||
) -> Iterator[FlakeForTest]:
|
||||
if not (CLAN_CORE / "flake.nix").exists():
|
||||
raise Exception(
|
||||
"clan-core flake not found. This test requires the clan-core flake to be present"
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import argparse
|
||||
|
||||
from clan_cli import create_parser
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import shlex
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class Cli:
|
||||
def __init__(self) -> None:
|
||||
self.parser = create_parser(prog="clan")
|
||||
|
||||
def run(self, args: list[str]) -> argparse.Namespace:
|
||||
cmd = shlex.join(["clan"] + args)
|
||||
log.debug(f"Command: {cmd}")
|
||||
parsed = self.parser.parse_args(args)
|
||||
if hasattr(parsed, "func"):
|
||||
parsed.func(parsed)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from fixtures_flakes import TestFlake
|
||||
from fixtures_flakes import FlakeForTest
|
||||
|
||||
from clan_cli.config import machine
|
||||
|
||||
|
||||
def test_schema_for_machine(test_flake: TestFlake) -> None:
|
||||
def test_schema_for_machine(test_flake: FlakeForTest) -> None:
|
||||
schema = machine.schema_for_machine(test_flake.name, "machine1")
|
||||
assert "properties" in schema
|
||||
|
||||
@@ -3,23 +3,27 @@ from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Iterator
|
||||
|
||||
import logging
|
||||
import pytest
|
||||
from cli import Cli
|
||||
from fixtures_flakes import FlakeForTest
|
||||
|
||||
from clan_cli.errors import ClanError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from age_keys import KeyPair
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _test_identities(
|
||||
what: str,
|
||||
test_flake: Path,
|
||||
test_flake: FlakeForTest,
|
||||
capsys: pytest.CaptureFixture,
|
||||
age_keys: list["KeyPair"],
|
||||
) -> None:
|
||||
cli = Cli()
|
||||
sops_folder = test_flake / "sops"
|
||||
sops_folder = test_flake.path / "sops"
|
||||
|
||||
cli.run(["secrets", what, "add", "foo", age_keys[0].pubkey])
|
||||
assert (sops_folder / what / "foo" / "key.json").exists()
|
||||
@@ -34,6 +38,7 @@ def _test_identities(
|
||||
"-f",
|
||||
"foo",
|
||||
age_keys[0].privkey,
|
||||
test_flake.name,
|
||||
]
|
||||
)
|
||||
|
||||
@@ -60,19 +65,19 @@ def _test_identities(
|
||||
|
||||
|
||||
def test_users(
|
||||
test_flake: Path, capsys: pytest.CaptureFixture, age_keys: list["KeyPair"]
|
||||
test_flake: FlakeForTest, capsys: pytest.CaptureFixture, age_keys: list["KeyPair"]
|
||||
) -> None:
|
||||
_test_identities("users", test_flake, capsys, age_keys)
|
||||
|
||||
|
||||
def test_machines(
|
||||
test_flake: Path, capsys: pytest.CaptureFixture, age_keys: list["KeyPair"]
|
||||
test_flake: FlakeForTest, capsys: pytest.CaptureFixture, age_keys: list["KeyPair"]
|
||||
) -> None:
|
||||
_test_identities("machines", test_flake, capsys, age_keys)
|
||||
|
||||
|
||||
def test_groups(
|
||||
test_flake: Path, capsys: pytest.CaptureFixture, age_keys: list["KeyPair"]
|
||||
test_flake: FlakeForTest, capsys: pytest.CaptureFixture, age_keys: list["KeyPair"]
|
||||
) -> None:
|
||||
cli = Cli()
|
||||
capsys.readouterr() # empty the buffer
|
||||
@@ -100,7 +105,7 @@ def test_groups(
|
||||
|
||||
cli.run(["secrets", "groups", "remove-user", "group1", "user1"])
|
||||
cli.run(["secrets", "groups", "remove-machine", "group1", "machine1"])
|
||||
groups = os.listdir(test_flake / "sops" / "groups")
|
||||
groups = os.listdir(test_flake.path / "sops" / "groups")
|
||||
assert len(groups) == 0
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from cli import Cli
|
||||
from fixtures_flakes import TestFlake
|
||||
from fixtures_flakes import FlakeForTest
|
||||
|
||||
from clan_cli.machines.facts import machine_get_fact
|
||||
from clan_cli.secrets.folders import sops_secrets_folder
|
||||
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
||||
@pytest.mark.impure
|
||||
def test_generate_secret(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
test_flake_with_core: TestFlake,
|
||||
test_flake_with_core: FlakeForTest,
|
||||
age_keys: list["KeyPair"],
|
||||
) -> None:
|
||||
monkeypatch.chdir(test_flake_with_core.path)
|
||||
|
||||
@@ -3,7 +3,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from cli import Cli
|
||||
from fixtures_flakes import TestFlake
|
||||
from fixtures_flakes import FlakeForTest
|
||||
|
||||
from clan_cli.machines.facts import machine_get_fact
|
||||
from clan_cli.nix import nix_shell
|
||||
@@ -13,7 +13,7 @@ from clan_cli.ssh import HostGroup
|
||||
@pytest.mark.impure
|
||||
def test_upload_secret(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
test_flake_with_core_and_pass: TestFlake,
|
||||
test_flake_with_core_and_pass: FlakeForTest,
|
||||
temporary_dir: Path,
|
||||
host_group: HostGroup,
|
||||
) -> None:
|
||||
|
||||
@@ -5,18 +5,18 @@ from typing import TYPE_CHECKING, Iterator
|
||||
import pytest
|
||||
from api import TestClient
|
||||
from cli import Cli
|
||||
from fixtures_flakes import TestFlake, create_flake
|
||||
from fixtures_flakes import FlakeForTest, create_flake
|
||||
from httpx import SyncByteStream
|
||||
from root import CLAN_CORE
|
||||
|
||||
from clan_cli.flakes.types import FlakeName
|
||||
from clan_cli.types import FlakeName
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from age_keys import KeyPair
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def flake_with_vm_with_secrets(monkeypatch: pytest.MonkeyPatch) -> Iterator[TestFlake]:
|
||||
def flake_with_vm_with_secrets(monkeypatch: pytest.MonkeyPatch) -> Iterator[FlakeForTest]:
|
||||
yield from create_flake(
|
||||
monkeypatch,
|
||||
FlakeName("test_flake_with_core_dynamic_machines"),
|
||||
@@ -28,7 +28,7 @@ def flake_with_vm_with_secrets(monkeypatch: pytest.MonkeyPatch) -> Iterator[Test
|
||||
@pytest.fixture
|
||||
def remote_flake_with_vm_without_secrets(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> Iterator[TestFlake]:
|
||||
) -> Iterator[FlakeForTest]:
|
||||
yield from create_flake(
|
||||
monkeypatch,
|
||||
FlakeName("test_flake_with_core_dynamic_machines"),
|
||||
|
||||
Reference in New Issue
Block a user