8000 fix(ci): run cleanly on the self-hosted runner by adeelahmad · Pull Request #112 · adeelahmad/lense · GitHub
[go: up one dir, main page]

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
12 changes: 9 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,17 @@ jobs:
working-directory: ./fastapi_backend
env:
ACCESS_SECRET_KEY: ci-access-secret-key-0123456789abcdef
LENS_TEST_SURREAL_URL: ws://127.0.0.1:8000
# a self-hosted runner's Docker outlives the job: a name of its own and any free port, removed at the end
SURREAL_CONTAINER: lens-ci-surreal-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- uses: actions/checkout@v4
- name: Start SurrealDB
run: |
# surrealkv, not memory: the memory engine loses concurrent writes (SurrealDB 3.2.4)
docker run -d --name surreal -p 8000:8000 surrealdb/surrealdb:v3.2.4 start --user root --pass root surrealkv:/tmp/lens.db
for _ in $(seq 1 30); do curl -sf http://127.0.0.1:8000/health && break; sleep 1; done
docker run -d --name "$SURREAL_CONTAINER" -p 127.0.0.1::8000 surrealdb/surrealdb:v3.2.4 start --user root --pass root surrealkv:/tmp/lens.db
port=$(docker port "$SURREAL_CONTAINER" 8000/tcp | head -n1 | sed 's/.*://')
echo "LENS_TEST_SURREAL_URL=ws://127.0.0.1:$port" >> "$GITHUB_ENV"
for _ in $(seq 1 30); do curl -sf "http://127.0.0.1:$port/health" && break; sleep 1; done
# the packages are kept between runs: the mirror can be slow (LibreOffice is 170 MB)
# GitHub's cache only on GitHub's runners; a self-hosted one keeps ~/apt-archives on its disk
- name: Restore system packages
Expand Down Expand Up @@ -151,6 +154,9 @@ jobs:
- name: Tests against the server
timeout-minutes: 30
run: uv run pytest -n 4
- name: Remove SurrealDB
if: always()
run: docker rm -f "$SURREAL_CONTAINER" || true

frontend:
name: Next.js
Expand Down
2 changes: 1 addition & 1 deletion fastapi_backend/app/api/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def _proxy_hosts() -> tuple[str, ...]:
hit = _PROXY_HOSTS.get(name)
if not hit or time.monotonic() - hit[0] > 30:
try:
found = tuple(sorted({i[4][0] for i in socket.getaddrinfo(name, None)}))
found = tuple(sorted({str(i[4][0]) for i in socket.getaddrinfo(name, None)}))
except OSError:
found = ()
hit = _PROXY_HOSTS[name] = (time.monotonic(), found)
Expand Down
25 changes: 12 additions & 13 deletions fastapi_backend/app/domain/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,20 +295,19 @@ def _print(argv, env, url, seconds, settle_ms):
said = tempfile.TemporaryFile()
err = _high(os.dup(said.fileno()))
deadline, buf, n = time.monotonic() + seconds, b"", 0
file_actions = [
(os.POSIX_SPAWN_OPEN, 0, os.devnull, os.O_RDONLY, 0),
(os.POSIX_SPAWN_OPEN, 1, os.devnull, os.O_WRONLY, 0),
(os.POSIX_SPAWN_DUP2, err, 2),
(os.POSIX_SPAWN_DUP2, to_read, 3),
(os.POSIX_SPAWN_DUP2, from_write, 4),
]
try:
pid = os.posix_spawn(
argv[0],
[*argv, "--remote-debugging-pipe", "about:blank"],
env,
file_actions=[
(os.POSIX_SPAWN_OPEN, 0, os.devnull, os.O_RDONLY, 0),
(os.POSIX_SPAWN_OPEN, 1, os.devnull, os.O_WRONLY, 0),
(os.POSIX_SPAWN_DUP2, err, 2),
(os.POSIX_SPAWN_DUP2, to_read, 3),
(os.POSIX_SPAWN_DUP2, from_write, 4),
],
setsid=True, # its own process group, so that it goes with all its helpers
)
# its own process group, so that it goes with all its helpers
try:
pid = os.posix_spawn(argv[0], [*argv, "--remote-debugging-pipe", "about:blank"], env, file_actions=file_actions, setsid=True)
except NotImplementedError: # Pythons built against an old glibc (uv's own builds) have no setsid here
pid = os.posix_spawn(argv[0], [*argv, "--remote-debugging-pipe", "about:blank"], env, file_actions=file_actions, setpgroup=0)
finally:
for fd in (to_read, from_write, err):
os.close(fd)
Expand Down
8 changes: 6 additions & 2 deletions fastapi_backend/tests/api/test_fedora.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ def test_a_real_fedora(env):
"""Against a real Fedora (docker run -p 8080:8080 fcrepo/fcrepo:6.5.1-tomcat9, then
LENS_TEST_FEDORA_URL=http://127.0.0.1:8080/fcrepo/rest): everything is accepted, kept in step, and deleted."""
import os
import uuid
import urllib.request
import uuid

cfg, db = env.cfg, env.db
cfg["fedora"] = {
Expand Down Expand Up @@ -168,7 +168,11 @@ def test_set_up_in_settings(env):
body = {"url": url + "/", "user": "fedoraAdmin", "password": "secret", "root": "archive"}
assert c.put("/api/v1/settings/fedora", headers=h, json=body).status_code == 200
view = c.get("/api/v1/settings", headers=h).json()["fedora"]
assert view["values"]["url"] == url and view["values"]["password"]["set"] is True and "secret" not in str(view["values"]["password"].get("value")) # the secret isn't shown
assert (
view["values"]["url"] == url
and view["values"]["password"]["set"] is True
and "secret" not in str(view["values"]["password"].get("value"))
) # the secret isn't shown
assert c.put("/api/v1/settings/fedora", headers=h, json={"url": "ftp://x"}).status_code == 400
out = c.post("/api/v1/admin/fedora/sync", headers=h).json()
assert out["sent"] > 0 and "/rest/archive/pods" in F.store
Expand Down
7 changes: 7 additions & 0 deletions fastapi_backend/tests/api/test_mail_calendar_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import base64
import datetime as dt
import http.server
import socket
import threading
from email.message import EmailMessage

Expand Down Expand Up @@ -300,6 +301,12 @@ def health(url, password="feed password 1", **params):
assert [h for h, _ in _Feed.sent_auth if h.startswith("localhost")] == []
# without a password, a redirect is followed (and still only to addresses allowed)
_Feed.auth = None
real = socket.getaddrinfo # where localhost is ::1 too (Ubuntu), only its IPv4 address: the test server's
monkeypatch.setattr(
netguard.socket,
"getaddrinfo",
lambda host, *a, **k: real(host, *a, **({**k, "family": socket.AF_INET} if host == "localhost" else k)),
)
try:
assert health(feed.replace("/team.ics", "/elsewhere"), password=None)["ok"]
finally:
Expand Down
8 changes: 6 additions & 2 deletions fastapi_backend/tests/fake_fedora.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,14 @@ def do_PUT(self):
return self._reply(410)
if parent != "/rest" and parent not in Handler.store:
return self._reply(404, b"parent missing")
if self.headers.get("Content-Type") == "text/turtle" and 'handling=lenient' not in (self.headers.get("Prefer") or ""):
if self.headers.get("Content-Type") == "text/turtle" and "handling=lenient" not in (self.headers.get("Prefer") or ""):
return self._reply(412)
new = self.path not in Handler.store
Handler.store[self.path] = {"type": self.headers.get("Content-Type"), "body": body, "disposition": self.headers.get("Content-Disposition")}
Handler.store[self.path] = {
"type": self.headers.get("Content-Type"),
"body": body,
"disposition": self.headers.get("Content-Disposition"),
}
self._reply(201 if new else 204)

def do_DELETE(self):
Expand Down
2 changes: 2 additions & 0 deletions nextjs-frontend/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const config: Config = {
restoreMocks: true,
coverageProvider: "v8",
testEnvironment: "jsdom",
// the longer UI tests take over 5 s on a busy self-hosted runner
testTimeout: 20000,
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/$1",
},
Expand Down
Loading
0