Merge pull request 'Enable all pytest without core' (#3118) from enable-more-macos into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3118
This commit is contained in:
@@ -30,7 +30,7 @@ def import_sops(args: argparse.Namespace) -> None:
|
|||||||
if args.input_type:
|
if args.input_type:
|
||||||
cmd += ["--input-type", args.input_type]
|
cmd += ["--input-type", args.input_type]
|
||||||
cmd += ["--output-type", "json", "--decrypt", args.sops_file]
|
cmd += ["--output-type", "json", "--decrypt", args.sops_file]
|
||||||
cmd = nix_shell(["nixpkgs#sops"], cmd)
|
cmd = nix_shell(["nixpkgs#sops", "nixpkgs#gnupg"], cmd)
|
||||||
|
|
||||||
res = run(cmd, RunOpts(error_msg=f"Could not import sops file {file}"))
|
res = run(cmd, RunOpts(error_msg=f"Could not import sops file {file}"))
|
||||||
secrets = json.loads(res.stdout)
|
secrets = json.loads(res.stdout)
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ def sops_run(
|
|||||||
raise ClanError(msg)
|
raise ClanError(msg)
|
||||||
sops_cmd.append(str(secret_path))
|
sops_cmd.append(str(secret_path))
|
||||||
|
|
||||||
cmd = nix_shell(["nixpkgs#sops"], sops_cmd)
|
cmd = nix_shell(["nixpkgs#sops", "nixpkgs#gnupg"], sops_cmd)
|
||||||
opts = (
|
opts = (
|
||||||
dataclasses.replace(run_opts, env=environ)
|
dataclasses.replace(run_opts, env=environ)
|
||||||
if run_opts
|
if run_opts
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ let
|
|||||||
testDependencies = testRuntimeDependencies ++ [
|
testDependencies = testRuntimeDependencies ++ [
|
||||||
gnupg
|
gnupg
|
||||||
stdenv.cc # Compiler used for certain native extensions
|
stdenv.cc # Compiler used for certain native extensions
|
||||||
(pythonRuntime.withPackages (ps: (pyTestDeps ps) ++ (pyDeps ps)))
|
(pythonRuntime.withPackages pyTestDeps)
|
||||||
];
|
];
|
||||||
|
|
||||||
source = runCommand "clan-cli-source" { } ''
|
source = runCommand "clan-cli-source" { } ''
|
||||||
@@ -127,7 +127,7 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
# Define and expose the tests and checks to run in CI
|
# Define and expose the tests and checks to run in CI
|
||||||
passthru.tests =
|
passthru.tests =
|
||||||
(lib.mapAttrs' (n: lib.nameValuePair "clan-dep-${n}") testRuntimeDependenciesMap)
|
(lib.mapAttrs' (n: lib.nameValuePair "clan-dep-${n}") testRuntimeDependenciesMap)
|
||||||
// lib.optionalAttrs (!stdenv.isDarwin) {
|
// {
|
||||||
# disabled on macOS until we fix all remaining issues
|
# disabled on macOS until we fix all remaining issues
|
||||||
clan-pytest-without-core =
|
clan-pytest-without-core =
|
||||||
runCommand "clan-pytest-without-core"
|
runCommand "clan-pytest-without-core"
|
||||||
@@ -159,6 +159,8 @@ pythonRuntime.pkgs.buildPythonApplication {
|
|||||||
python -m pytest -m "not impure and not with_core" -n $jobs ./tests
|
python -m pytest -m "not impure and not with_core" -n $jobs ./tests
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (!stdenv.isDarwin) {
|
||||||
clan-pytest-with-core =
|
clan-pytest-with-core =
|
||||||
runCommand "clan-pytest-with-core"
|
runCommand "clan-pytest-with-core"
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from clan_cli.custom_logger import setup_logging
|
from clan_cli.custom_logger import setup_logging
|
||||||
from clan_cli.nix import nix_shell
|
|
||||||
|
|
||||||
pytest_plugins = [
|
pytest_plugins = [
|
||||||
"temporary_dir",
|
"temporary_dir",
|
||||||
"root",
|
"root",
|
||||||
"age_keys",
|
"age_keys",
|
||||||
|
"gpg_keys",
|
||||||
|
"git_repo",
|
||||||
"sshd",
|
"sshd",
|
||||||
"command",
|
"command",
|
||||||
"ports",
|
"ports",
|
||||||
@@ -28,18 +26,3 @@ def pytest_sessionstart(session: pytest.Session) -> None:
|
|||||||
print(f"Session config: {session.config}")
|
print(f"Session config: {session.config}")
|
||||||
|
|
||||||
setup_logging(level="DEBUG")
|
setup_logging(level="DEBUG")
|
||||||
|
|
||||||
|
|
||||||
# fixture for git_repo
|
|
||||||
@pytest.fixture
|
|
||||||
def git_repo(tmp_path: Path) -> Path:
|
|
||||||
# initialize a git repository
|
|
||||||
cmd = nix_shell(["nixpkgs#git"], ["git", "init"])
|
|
||||||
subprocess.run(cmd, cwd=tmp_path, check=True)
|
|
||||||
# set user.name and user.email
|
|
||||||
cmd = nix_shell(["nixpkgs#git"], ["git", "config", "user.name", "test"])
|
|
||||||
subprocess.run(cmd, cwd=tmp_path, check=True)
|
|
||||||
cmd = nix_shell(["nixpkgs#git"], ["git", "config", "user.email", "test@test.test"])
|
|
||||||
subprocess.run(cmd, cwd=tmp_path, check=True)
|
|
||||||
# return the path to the git repository
|
|
||||||
return tmp_path
|
|
||||||
|
|||||||
@@ -294,18 +294,19 @@ def create_flake(
|
|||||||
if tmp_store := nix_test_store():
|
if tmp_store := nix_test_store():
|
||||||
nix_options += ["--store", str(tmp_store)]
|
nix_options += ["--store", str(tmp_store)]
|
||||||
|
|
||||||
sp.run(
|
with locked_open(Path(lock_nix), "w"):
|
||||||
[
|
sp.run(
|
||||||
"nix",
|
[
|
||||||
"flake",
|
"nix",
|
||||||
"lock",
|
"flake",
|
||||||
flake,
|
"lock",
|
||||||
"--extra-experimental-features",
|
flake,
|
||||||
"nix-command flakes",
|
"--extra-experimental-features",
|
||||||
*nix_options,
|
"nix-command flakes",
|
||||||
],
|
*nix_options,
|
||||||
check=True,
|
],
|
||||||
)
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
if "/tmp" not in str(os.environ.get("HOME")):
|
if "/tmp" not in str(os.environ.get("HOME")):
|
||||||
log.warning(
|
log.warning(
|
||||||
|
|||||||
@@ -6,12 +6,44 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <sandbox.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
struct dyld_interpose {
|
||||||
|
const void *replacement;
|
||||||
|
const void *replacee;
|
||||||
|
};
|
||||||
|
#define WRAPPER(ret, name) static ret _fakeroot_wrapper_##name
|
||||||
|
#define WRAPPER_DEF(name) \
|
||||||
|
__attribute__(( \
|
||||||
|
used)) static struct dyld_interpose _fakeroot_interpose_##name \
|
||||||
|
__attribute__((section("__DATA,__interpose"))) = { \
|
||||||
|
&_fakeroot_wrapper_##name, &name};
|
||||||
|
#else
|
||||||
|
#define WRAPPER(ret, name) ret name
|
||||||
|
#define WRAPPER_DEF(name)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct passwd *(*getpwnam_type)(const char *name);
|
typedef struct passwd *(*getpwnam_type)(const char *name);
|
||||||
|
|
||||||
struct passwd *getpwnam(const char *name) {
|
WRAPPER(struct passwd *, getpwnam)(const char *name) {
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
getpwnam_type orig_getpwnam;
|
#ifdef __APPLE__
|
||||||
orig_getpwnam = (getpwnam_type)dlsym(RTLD_NEXT, "getpwnam");
|
#define orig_getpwnam(name) getpwnam(name)
|
||||||
|
#else
|
||||||
|
static getpwnam_type orig_getpwnam = NULL;
|
||||||
|
|
||||||
|
if (!orig_getpwnam) {
|
||||||
|
orig_getpwnam = (getpwnam_type)dlsym(RTLD_NEXT, "getpwnam");
|
||||||
|
if (!orig_getpwnam) {
|
||||||
|
fprintf(stderr, "dlsym error: %s\n", dlerror());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pw = orig_getpwnam(name);
|
pw = orig_getpwnam(name);
|
||||||
|
|
||||||
if (pw) {
|
if (pw) {
|
||||||
@@ -21,6 +53,17 @@ struct passwd *getpwnam(const char *name) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
pw->pw_shell = strdup(shell);
|
pw->pw_shell = strdup(shell);
|
||||||
|
fprintf(stderr, "getpwnam: %s -> %s\n", name, pw->pw_shell);
|
||||||
}
|
}
|
||||||
return pw;
|
return pw;
|
||||||
}
|
}
|
||||||
|
WRAPPER_DEF(getpwnam)
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// sandbox_init(3) doesn't work in nix build sandbox
|
||||||
|
WRAPPER(int, sandbox_init)(const char *profile, uint64_t flags, void *handle) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
WRAPPER_DEF(sandbox_init)
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|||||||
20
pkgs/clan-cli/tests/git_repo.py
Normal file
20
pkgs/clan-cli/tests/git_repo.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from clan_cli.nix import nix_shell
|
||||||
|
|
||||||
|
|
||||||
|
# fixture for git_repo
|
||||||
|
@pytest.fixture
|
||||||
|
def git_repo(temp_dir: Path) -> Path:
|
||||||
|
# initialize a git repository
|
||||||
|
cmd = nix_shell(["nixpkgs#git"], ["git", "init"])
|
||||||
|
subprocess.run(cmd, cwd=temp_dir, check=True)
|
||||||
|
# set user.name and user.email
|
||||||
|
cmd = nix_shell(["nixpkgs#git"], ["git", "config", "user.name", "test"])
|
||||||
|
subprocess.run(cmd, cwd=temp_dir, check=True)
|
||||||
|
cmd = nix_shell(["nixpkgs#git"], ["git", "config", "user.email", "test@test.test"])
|
||||||
|
subprocess.run(cmd, cwd=temp_dir, check=True)
|
||||||
|
# return the path to the git repository
|
||||||
|
return temp_dir
|
||||||
25
pkgs/clan-cli/tests/gpg_keys.py
Normal file
25
pkgs/clan-cli/tests/gpg_keys.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import shutil
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GpgKey:
|
||||||
|
fingerprint: str
|
||||||
|
gpg_home: Path
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def gpg_key(
|
||||||
|
temp_dir: Path,
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
test_root: Path,
|
||||||
|
) -> GpgKey:
|
||||||
|
gpg_home = temp_dir / "gnupghome"
|
||||||
|
|
||||||
|
shutil.copytree(test_root / "data" / "gnupg-home", gpg_home)
|
||||||
|
monkeypatch.setenv("GNUPGHOME", str(gpg_home))
|
||||||
|
|
||||||
|
return GpgKey("9A9B2741C8062D3D3DF1302D8B049E262A5CA255", gpg_home)
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
import functools
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from pathlib import Path
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from age_keys import assert_secrets_file_recipients
|
from age_keys import assert_secrets_file_recipients
|
||||||
from clan_cli.errors import ClanError
|
from clan_cli.errors import ClanError
|
||||||
from fixtures_flakes import FlakeForTest
|
from fixtures_flakes import FlakeForTest
|
||||||
|
from gpg_keys import GpgKey
|
||||||
from helpers import cli
|
from helpers import cli
|
||||||
from stdout import CaptureOutput
|
from stdout import CaptureOutput
|
||||||
|
|
||||||
@@ -426,12 +424,12 @@ def use_age_key(key: str, monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def use_gpg_key(key: str, monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
def use_gpg_key(key: GpgKey, monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
||||||
old_key_file = os.environ.get("SOPS_AGE_KEY_FILE")
|
old_key_file = os.environ.get("SOPS_AGE_KEY_FILE")
|
||||||
old_key = os.environ.get("SOPS_AGE_KEY")
|
old_key = os.environ.get("SOPS_AGE_KEY")
|
||||||
monkeypatch.delenv("SOPS_AGE_KEY_FILE", raising=False)
|
monkeypatch.delenv("SOPS_AGE_KEY_FILE", raising=False)
|
||||||
monkeypatch.delenv("SOPS_AGE_KEY", raising=False)
|
monkeypatch.delenv("SOPS_AGE_KEY", raising=False)
|
||||||
monkeypatch.setenv("SOPS_PGP_FP", key)
|
monkeypatch.setenv("SOPS_PGP_FP", key.fingerprint)
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
@@ -442,54 +440,11 @@ def use_gpg_key(key: str, monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
|
|||||||
monkeypatch.setenv("SOPS_AGE_KEY", old_key)
|
monkeypatch.setenv("SOPS_AGE_KEY", old_key)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def gpg_key(
|
|
||||||
tmp_path: Path,
|
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
|
||||||
) -> str:
|
|
||||||
gpg_home = tmp_path / "gnupghome"
|
|
||||||
gpg_home.mkdir(mode=0o700)
|
|
||||||
|
|
||||||
gpg_environ = os.environ.copy()
|
|
||||||
gpg_environ["GNUPGHOME"] = str(gpg_home)
|
|
||||||
run = functools.partial(
|
|
||||||
subprocess.run,
|
|
||||||
encoding="utf-8",
|
|
||||||
check=True,
|
|
||||||
env=gpg_environ,
|
|
||||||
)
|
|
||||||
key_parameters = "\n".join(
|
|
||||||
(
|
|
||||||
"%no-protection",
|
|
||||||
"%transient-key",
|
|
||||||
"Key-Type: rsa",
|
|
||||||
"Key-Usage: cert encrypt",
|
|
||||||
"Name-Real: Foo Bar",
|
|
||||||
"Name-Comment: Test user",
|
|
||||||
"Name-Email: test@clan.lol",
|
|
||||||
"%commit",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
run(["gpg", "--batch", "--quiet", "--generate-key"], input=key_parameters)
|
|
||||||
details = run(["gpg", "--list-keys", "--with-colons"], capture_output=True)
|
|
||||||
fingerprint = None
|
|
||||||
for line in details.stdout.strip().split(os.linesep):
|
|
||||||
if not line.startswith("fpr"):
|
|
||||||
continue
|
|
||||||
fingerprint = line.split(":")[9]
|
|
||||||
break
|
|
||||||
assert fingerprint is not None, "Could not generate test GPG key"
|
|
||||||
log.info(f"Created GPG key under {gpg_home}")
|
|
||||||
|
|
||||||
monkeypatch.setenv("GNUPGHOME", str(gpg_home))
|
|
||||||
return fingerprint
|
|
||||||
|
|
||||||
|
|
||||||
def test_secrets(
|
def test_secrets(
|
||||||
test_flake: FlakeForTest,
|
test_flake: FlakeForTest,
|
||||||
capture_output: CaptureOutput,
|
capture_output: CaptureOutput,
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
gpg_key: str,
|
gpg_key: GpgKey,
|
||||||
age_keys: list["KeyPair"],
|
age_keys: list["KeyPair"],
|
||||||
) -> None:
|
) -> None:
|
||||||
with capture_output as output:
|
with capture_output as output:
|
||||||
@@ -716,7 +671,7 @@ def test_secrets(
|
|||||||
"--flake",
|
"--flake",
|
||||||
str(test_flake.path),
|
str(test_flake.path),
|
||||||
"--pgp-key",
|
"--pgp-key",
|
||||||
gpg_key,
|
gpg_key.fingerprint,
|
||||||
"user2",
|
"user2",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -783,7 +738,7 @@ def test_secrets_key_generate_gpg(
|
|||||||
test_flake: FlakeForTest,
|
test_flake: FlakeForTest,
|
||||||
capture_output: CaptureOutput,
|
capture_output: CaptureOutput,
|
||||||
monkeypatch: pytest.MonkeyPatch,
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
gpg_key: str,
|
gpg_key: GpgKey,
|
||||||
) -> None:
|
) -> None:
|
||||||
with use_gpg_key(gpg_key, monkeypatch):
|
with use_gpg_key(gpg_key, monkeypatch):
|
||||||
# Make sure clan secrets key generate recognizes
|
# Make sure clan secrets key generate recognizes
|
||||||
@@ -805,7 +760,7 @@ def test_secrets_key_generate_gpg(
|
|||||||
cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
|
cli.run(["secrets", "key", "show", "--flake", str(test_flake.path)])
|
||||||
key = json.loads(output.out)
|
key = json.loads(output.out)
|
||||||
assert key["type"] == "pgp"
|
assert key["type"] == "pgp"
|
||||||
assert key["publickey"] == gpg_key
|
assert key["publickey"] == gpg_key.fingerprint
|
||||||
|
|
||||||
# Add testuser with the key that was (not) generated for the clan:
|
# Add testuser with the key that was (not) generated for the clan:
|
||||||
cli.run(
|
cli.run(
|
||||||
@@ -816,7 +771,7 @@ def test_secrets_key_generate_gpg(
|
|||||||
"--flake",
|
"--flake",
|
||||||
str(test_flake.path),
|
str(test_flake.path),
|
||||||
"--pgp-key",
|
"--pgp-key",
|
||||||
gpg_key,
|
gpg_key.fingerprint,
|
||||||
"testuser",
|
"testuser",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -833,7 +788,7 @@ def test_secrets_key_generate_gpg(
|
|||||||
)
|
)
|
||||||
key = json.loads(output.out)
|
key = json.loads(output.out)
|
||||||
assert key["type"] == "pgp"
|
assert key["type"] == "pgp"
|
||||||
assert key["publickey"] == gpg_key
|
assert key["publickey"] == gpg_key.fingerprint
|
||||||
|
|
||||||
monkeypatch.setenv("SOPS_NIX_SECRET", "secret-value")
|
monkeypatch.setenv("SOPS_NIX_SECRET", "secret-value")
|
||||||
cli.run(["secrets", "set", "--flake", str(test_flake.path), "secret-name"])
|
cli.run(["secrets", "set", "--flake", str(test_flake.path), "secret-name"])
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import contextlib
|
import contextlib
|
||||||
|
import sys
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from typing import Any, NamedTuple
|
from typing import Any, NamedTuple
|
||||||
|
|
||||||
@@ -127,6 +128,10 @@ def test_parse_ssh_options() -> None:
|
|||||||
assert host.ssh_options["StrictHostKeyChecking"] == "yes"
|
assert host.ssh_options["StrictHostKeyChecking"] == "yes"
|
||||||
|
|
||||||
|
|
||||||
|
is_darwin = sys.platform == "darwin"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_run(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_run(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
proc = runtime.async_run(
|
proc = runtime.async_run(
|
||||||
@@ -135,6 +140,7 @@ def test_run(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
|||||||
assert proc.wait().result.stdout == "hello\n"
|
assert proc.wait().result.stdout == "hello\n"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_run_environment(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_run_environment(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
proc = runtime.async_run(
|
proc = runtime.async_run(
|
||||||
@@ -157,6 +163,7 @@ def test_run_environment(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
|||||||
assert "env_var=true" in p2.wait().result.stdout
|
assert "env_var=true" in p2.wait().result.stdout
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_run_no_shell(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_run_no_shell(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
proc = runtime.async_run(
|
proc = runtime.async_run(
|
||||||
@@ -165,6 +172,7 @@ def test_run_no_shell(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
|||||||
assert proc.wait().result.stdout == "hello\n"
|
assert proc.wait().result.stdout == "hello\n"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_run_function(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_run_function(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
def some_func(h: Host) -> bool:
|
def some_func(h: Host) -> bool:
|
||||||
p = h.run(["echo", "hello"])
|
p = h.run(["echo", "hello"])
|
||||||
@@ -175,6 +183,7 @@ def test_run_function(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
|||||||
assert proc.wait().result
|
assert proc.wait().result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_timeout(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_timeout(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
proc = runtime.async_run(
|
proc = runtime.async_run(
|
||||||
@@ -184,6 +193,7 @@ def test_timeout(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
|||||||
assert isinstance(error, ClanCmdTimeoutError)
|
assert isinstance(error, ClanCmdTimeoutError)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_run_exception(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_run_exception(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
proc = runtime.async_run(
|
proc = runtime.async_run(
|
||||||
@@ -203,6 +213,7 @@ def test_run_exception(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
|||||||
raise AssertionError(msg)
|
raise AssertionError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin")
|
||||||
def test_run_function_exception(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
def test_run_function_exception(hosts: list[Host], runtime: AsyncRuntime) -> None:
|
||||||
def some_func(h: Host) -> CmdOut:
|
def some_func(h: Host) -> CmdOut:
|
||||||
return h.run_local(["exit 1"], RunOpts(shell=True))
|
return h.run_local(["exit 1"], RunOpts(shell=True))
|
||||||
|
|||||||
Reference in New Issue
Block a user