89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
import asyncio
|
|
|
|
import pytest
|
|
|
|
from gitea_dynamic_runner.models import RunnerRequest
|
|
from gitea_dynamic_runner.opensandbox_worker import (
|
|
OpenSandboxScheduler,
|
|
RegistrationTokens,
|
|
sandbox_request,
|
|
)
|
|
|
|
|
|
def request(backend: str = "vm") -> RunnerRequest:
|
|
return RunnerRequest(
|
|
job_id=42,
|
|
run_id=7,
|
|
backend=backend,
|
|
repository="panxiao81/example",
|
|
job_name="publish image",
|
|
labels=("self-hosted", backend),
|
|
)
|
|
|
|
|
|
def test_sandbox_request_uses_pool_identity_and_one_time_token_url():
|
|
document = sandbox_request(
|
|
request(), "gitea-vm-abcd", "http://scheduler/token/nonce"
|
|
)
|
|
assert document["pool"] == "ci-vm"
|
|
assert document["entrypoint"] == [
|
|
"/usr/local/libexec/gitea-opensandbox-runner"
|
|
]
|
|
assert document["env"]["GITEA_RUNNER_LABELS"] == "self-hosted:host,vm:host"
|
|
assert document["env"]["GITEA_RUNNER_REGISTRATION_TOKEN_URL"].endswith(
|
|
"/nonce"
|
|
)
|
|
assert document["env"]["CI_SPIFFE_ID"] == (
|
|
"spiffe://ddupan.top/ci/panxiao81/example/publish-image-3e72cdc4a97e"
|
|
)
|
|
assert document["metadata"]["ci.ddupan.top/runner"] == "true"
|
|
|
|
|
|
async def test_registration_token_is_single_use(monkeypatch):
|
|
monkeypatch.setattr(
|
|
"gitea_dynamic_runner.opensandbox_worker.TOKEN_BASE_URL",
|
|
"http://scheduler/token",
|
|
)
|
|
tokens = RegistrationTokens(b"secret\n")
|
|
nonce, url = await tokens.issue()
|
|
assert url == f"http://scheduler/token/{nonce}"
|
|
assert await tokens.consume(nonce) == b"secret"
|
|
assert await tokens.consume(nonce) is None
|
|
|
|
|
|
class FakeOpenSandbox:
|
|
def __init__(self):
|
|
self.created = None
|
|
self.deleted = []
|
|
|
|
async def create(self, **document):
|
|
self.created = document
|
|
return {"id": "sandbox-1"}
|
|
|
|
async def get(self, sandbox_id):
|
|
return {"status": {"state": "Terminated"}}
|
|
|
|
async def delete(self, sandbox_id):
|
|
self.deleted.append(sandbox_id)
|
|
|
|
|
|
async def test_scheduler_creates_monitors_and_deletes(monkeypatch):
|
|
monkeypatch.setattr(
|
|
"gitea_dynamic_runner.opensandbox_worker.TOKEN_BASE_URL",
|
|
"http://scheduler/token",
|
|
)
|
|
client = FakeOpenSandbox()
|
|
scheduler = OpenSandboxScheduler(client, RegistrationTokens(b"secret"))
|
|
assert await scheduler.create(request()) == "sandbox-1"
|
|
await scheduler.active[42]
|
|
assert client.created["pool"] == "ci-vm"
|
|
assert client.deleted == ["sandbox-1"]
|
|
|
|
|
|
async def test_scheduler_rejects_duplicate_active_job():
|
|
client = FakeOpenSandbox()
|
|
scheduler = OpenSandboxScheduler(client, RegistrationTokens(b"secret"))
|
|
scheduler.active[42] = asyncio.Future()
|
|
with pytest.raises(ValueError, match="already"):
|
|
await scheduler.create(request())
|