feat: add container manager API, islop router, and container runtime files with vim/bot/d stealth clients
DevPlace CI / test (push) Failing after 38m17s

This commit is contained in:
2026-07-06 03:58:46 +00:00
parent 9a8046ab2a
commit 499f91e16a
88 changed files with 21337 additions and 0 deletions
+334
View File
@@ -0,0 +1,334 @@
# retoor <retoor@molodetz.nl>
from datetime import timedelta
import pytest
import requests
from tests.conftest import BASE_URL, run_async
from devplacepy.database import db, get_table, init_db, refresh_snapshot
from devplacepy.utils import generate_uid
from devplacepy import config, project_files
from devplacepy.services.containers import api, store, runtime
from devplacepy.services.containers.backend.base import Mount, PortMapping, RunSpec
from devplacepy.services.containers.backend.docker_cli import build_run_argv, parse_size
from devplacepy.services.containers.backend.fake import FakeBackend
from devplacepy.services.containers.service import ContainerService
from devplacepy.services.containers.api import INSTANCE_LABEL
from devplacepy.services.devii.tasks.schedule import Schedule, now_utc
_CONTAINER_TABLES = (
"instances",
"instance_events",
"instance_metrics",
"instance_schedules",
)
@pytest.fixture(autouse=True)
def _init_db_containers():
init_db()
yield
@pytest.fixture
def env(tmp_path, monkeypatch):
fake = FakeBackend()
runtime.set_backend(fake)
monkeypatch.setattr("devplacepy.config.CONTAINER_WORKSPACES_DIR", tmp_path / "ws")
pid = "ctest-p1"
project = {"uid": pid, "slug": "ctest", "title": "C", "user_uid": "ctest-u1"}
user = {"uid": "ctest-u1", "username": "ctestadmin"}
get_table("users").insert(
{
"uid": user["uid"],
"username": user["username"],
"email": "ctestadmin@example.com",
"api_key": generate_uid(),
"password_hash": "",
"role": "Member",
"is_active": True,
"level": 1,
"xp": 0,
"stars": 0,
"deleted_at": None,
"deleted_by": None,
}
)
refresh_snapshot()
project_files.write_text_file(pid, user, "app.py", "print(1)\n")
yield {"fake": fake, "project": project, "user": user}
runtime.set_backend(None)
get_table("users").delete(uid=user["uid"])
for table in _CONTAINER_TABLES:
if table in db.tables:
for row in [r for r in get_table(table).find()]:
if str(row.get("project_uid", "")).startswith("ctest"):
get_table(table).delete(uid=row["uid"])
for row in list(get_table("project_files").find()):
if str(row.get("project_uid", "")).startswith("ctest"):
get_table("project_files").delete(uid=row["uid"])
def _ready_instance(env, **kwargs):
return run_async(
api.create_instance(env["project"], name=kwargs.pop("name", "inst"), **kwargs)
)
def _promote_admin(username: str) -> None:
users = get_table("users")
user = users.find_one(username=username)
if user:
users.update({"uid": user["uid"], "role": "Admin"}, ["uid"])
def _api_key(username: str) -> str:
refresh_snapshot()
return get_table("users").find_one(username=username)["api_key"]
def test_build_run_argv_exact():
spec = RunSpec(
image="ppy:latest",
name="inst",
labels={INSTANCE_LABEL: "u1"},
env={"A": "B"},
cpu_limit="1.5",
mem_limit="512m",
ports=[PortMapping(8080, 80)],
mounts=[Mount("/ws", "/app")],
restart_policy="on-failure",
command=["python", "app.py"],
)
argv = build_run_argv(spec)
assert argv[:5] == ["docker", "run", "-d", "--name", "inst"]
assert "--label" in argv and f"{INSTANCE_LABEL}=u1" in argv
assert "--cpus" in argv and "1.5" in argv
assert "-p" in argv and "8080:80/tcp" in argv
assert "-v" in argv and "/ws:/app:rw" in argv
assert "--restart" in argv and "on-failure" in argv
assert argv[-3:] == ["ppy:latest", "python", "app.py"]
def test_never_policy_not_passed_to_docker():
spec = RunSpec(image="ppy:latest", name="n", restart_policy="never")
assert "--restart" not in build_run_argv(spec)
def test_parse_size():
assert parse_size("1.0GiB") == 1024**3
assert parse_size("512MB") == 512 * 1024**2
def test_create_instance_uses_shared_image(env):
inst = run_async(
api.create_instance(
env["project"], name="inst", actor=("user", env["user"]["uid"])
)
)
assert inst["name"] == "inst"
assert inst["owner_uid"] == "ctest-u1"
spec = api.run_spec_for(inst, config.CONTAINER_IMAGE)
assert spec.image == config.CONTAINER_IMAGE
assert any(m.container == "/app" for m in spec.mounts)
def test_create_instance_requires_built_image(env):
async def no_image(ref):
return False
env["fake"].image_exists = no_image
with pytest.raises(api.ContainerError):
run_async(api.create_instance(env["project"], name="inst"))
def test_reconcile_launches_and_stops(env):
inst = _ready_instance(env, restart_policy="never", autostart=True)
assert inst["desired_state"] == store.DESIRED_RUNNING
service = ContainerService()
run_async(service.run_once())
refresh_snapshot()
inst = store.get_instance(inst["uid"])
assert inst["status"] == store.ST_RUNNING and inst["container_id"]
assert [r.name for r in run_async(env["fake"].ps())] == [inst["slug"]]
api.set_desired_state(inst, store.DESIRED_STOPPED)
run_async(service.run_once())
refresh_snapshot()
assert store.get_instance(inst["uid"])["status"] == store.ST_STOPPED
def test_manual_start_relaunches_after_never_policy_exit(env):
fake = env["fake"]
inst = _ready_instance(env, restart_policy="never", autostart=True)
service = ContainerService()
run_async(service.run_once())
refresh_snapshot()
inst = store.get_instance(inst["uid"])
cid = inst["container_id"]
assert inst["status"] == store.ST_RUNNING and cid
fake._set_state(cid, "exited", 0)
run_async(service.run_once())
refresh_snapshot()
inst = store.get_instance(inst["uid"])
assert inst["status"] == store.ST_STOPPED
assert inst["desired_state"] == store.DESIRED_STOPPED
api.set_desired_state(inst, store.DESIRED_RUNNING)
refresh_snapshot()
run_async(service.run_once())
refresh_snapshot()
inst = store.get_instance(inst["uid"])
assert inst["status"] == store.ST_RUNNING
assert inst["desired_state"] == store.DESIRED_RUNNING
assert cid in fake.removed
assert inst["container_id"] and inst["container_id"] != cid
def test_reconcile_reaps_orphan(env):
fake = env["fake"]
run_async(
fake.run(
RunSpec(
image="ppy:latest", name="ghost", labels={INSTANCE_LABEL: "missing-uid"}
)
)
)
service = ContainerService()
run_async(service.run_once())
assert not run_async(fake.ps())
assert fake.removed
def test_reconcile_removes_marked_instance(env):
inst = _ready_instance(env, autostart=True)
service = ContainerService()
run_async(service.run_once())
refresh_snapshot()
inst = store.get_instance(inst["uid"])
api.mark_for_removal(inst)
run_async(service.run_once())
refresh_snapshot()
assert store.get_instance(inst["uid"]) is None
assert not run_async(env["fake"].ps())
def test_schedule_fires(env):
inst = _ready_instance(env, autostart=False)
assert inst["desired_state"] == store.DESIRED_STOPPED
past = Schedule(kind="once", run_at=now_utc() - timedelta(hours=1))
api.add_schedule(inst, "start", past)
service = ContainerService()
run_async(service._fire_schedules())
refresh_snapshot()
assert store.get_instance(inst["uid"])["desired_state"] == store.DESIRED_RUNNING
def test_ingress_validation(env):
from devplacepy.services.containers.backend.base import PortMapping
assert api.validate_ingress("zwoeks", 8899, [PortMapping(8899, 8899)]) == (
"zwoeks",
8899,
)
assert api.validate_ingress("", None, []) == ("", 0)
with pytest.raises(api.ContainerError):
api.validate_ingress("BAD SLUG", None, [PortMapping(80, 80)])
with pytest.raises(api.ContainerError):
api.validate_ingress("x", 9999, [PortMapping(80, 80)])
store.create_instance(
{
"uid": "z",
"project_uid": "ctest-p1",
"name": "z",
"ports_json": "[]",
"ingress_slug": "taken",
}
)
with pytest.raises(api.ContainerError):
api.validate_ingress("taken", None, [PortMapping(80, 80)])
def test_validate_boot_languages():
assert api.validate_boot("none", "ignored") == ("none", "")
assert api.validate_boot("python", "print(1)") == ("python", "print(1)")
with pytest.raises(api.ContainerError):
api.validate_boot("ruby", "puts 1")
with pytest.raises(api.ContainerError):
api.validate_boot("bash", " ")
def test_boot_script_precedence_in_run_spec(env):
inst = _ready_instance(
env,
boot_language="python",
boot_script="print('boot')\n",
boot_command="python other.py",
autostart=False,
)
spec = api.run_spec_for(inst, config.CONTAINER_IMAGE)
assert spec.command == ["python", "/app/.devplace_boot.py"]
inst2 = _ready_instance(
env, name="i2", boot_command="python serve.py", autostart=False
)
spec2 = api.run_spec_for(inst2, config.CONTAINER_IMAGE)
assert spec2.command == ["/bin/sh", "-c", "python serve.py"]
def test_materialize_boot_script_writes_file(env, tmp_path):
workspace = tmp_path / "boot-ws"
inst = _ready_instance(
env, name="boot", boot_language="bash", boot_script="echo hi\n", autostart=False
)
store.update_instance(inst["uid"], {"workspace_dir": str(workspace)})
inst = store.get_instance(inst["uid"])
api.materialize_boot_script(inst)
written = workspace / ".devplace_boot.sh"
assert written.is_file()
assert written.read_text() == "echo hi\n"
def test_run_as_uid_drives_pravda_env(env):
_promote_admin(env["user"]["username"])
key = _api_key(env["user"]["username"])
inst = _ready_instance(
env, name="runas", run_as_uid=env["user"]["uid"], autostart=False
)
pravda = api.pravda_env(inst)
assert pravda["PRAVDA_API_KEY"] == key
assert pravda["PRAVDA_USER_UID"] == env["user"]["uid"]
def test_run_as_uid_rejects_unknown_user(env):
with pytest.raises(api.ContainerError):
run_async(
api.create_instance(
env["project"], name="bad", run_as_uid="nope-uid", autostart=False
)
)
def test_start_on_boot_pass_forces_running(env):
inst = _ready_instance(env, name="boot", start_on_boot=True, autostart=False)
assert inst["desired_state"] == store.DESIRED_STOPPED
service = ContainerService()
service._boot_pass(store.all_instances())
refresh_snapshot()
assert store.get_instance(inst["uid"])["desired_state"] == store.DESIRED_RUNNING
def test_status_change_records_event(env):
inst = _ready_instance(env, name="hist", restart_policy="never", autostart=True)
service = ContainerService()
run_async(service.run_once())
refresh_snapshot()
inst = store.get_instance(inst["uid"])
api.set_desired_state(inst, store.DESIRED_STOPPED)
run_async(service.run_once())
refresh_snapshot()
events = [e["event"] for e in store.list_events(inst["uid"])]
assert "status_change" in events
def test_bidirectional_sync_newer_wins(env, tmp_path):
workspace = tmp_path / "sync-ws"
workspace.mkdir()
pid = env["project"]["uid"]
user = env["user"]
project_files.write_text_file(pid, user, "shared.txt", "from project\n")
fs_only = workspace / "fromfs.txt"
fs_only.write_text("from fs\n")
counts = project_files.sync_dir_bidirectional(pid, str(workspace), user)
assert counts["exported"] >= 1
assert counts["imported"] >= 1
assert (workspace / "shared.txt").read_text() == "from project\n"
imported = project_files.read_file(pid, "fromfs.txt")
assert imported["content"] == "from fs\n"
+28
View File
@@ -0,0 +1,28 @@
# retoor <retoor@molodetz.nl>
from devplacepy.services.jobs.isslop.badge import badge_html, badge_markdown, render_badge
def test_render_badge_with_grade():
svg = render_badge(87.5, "A", "https://devplace.example/tools/isslop/abc/report")
assert svg.startswith("<svg")
assert "88%" in svg or "87%" in svg
assert "authenticity" in svg
assert "https://devplace.example/tools/isslop/abc/report" in svg
def test_render_badge_pending():
svg = render_badge(None, None, "https://devplace.example/tools/isslop/abc/report")
assert "analyzing" in svg
def test_render_badge_escapes_url():
svg = render_badge(50.0, "C", 'https://x.example/"><script>')
assert "<script>" not in svg
def test_badge_snippets():
markdown = badge_markdown("https://x/badge.svg", "https://x/report")
assert markdown == "[![authenticity human score](https://x/badge.svg)](https://x/report)"
html = badge_html("https://x/badge.svg", "https://x/report")
assert '<img src="https://x/badge.svg"' in html
+31
View File
@@ -0,0 +1,31 @@
# retoor <retoor@molodetz.nl>
import json
from devplacepy.services.jobs.isslop.events import KIND_DONE, WorkerEvent
def test_event_roundtrip():
event = WorkerEvent(kind=KIND_DONE, message="Analysis complete", data={"grade": "A"})
parsed = WorkerEvent.parse(event.to_json())
assert parsed is not None
assert parsed.kind == KIND_DONE
assert parsed.message == "Analysis complete"
assert parsed.data == {"grade": "A"}
def test_parse_rejects_non_json_lines():
assert WorkerEvent.parse("") is None
assert WorkerEvent.parse("plain log output") is None
assert WorkerEvent.parse("{broken json") is None
def test_parse_rejects_missing_fields():
assert WorkerEvent.parse(json.dumps({"kind": "log"})) is None
assert WorkerEvent.parse(json.dumps({"message": "no kind"})) is None
def test_parse_tolerates_non_dict_data():
parsed = WorkerEvent.parse(json.dumps({"kind": "log", "message": "x", "data": [1, 2]}))
assert parsed is not None
assert parsed.data == {}
@@ -0,0 +1,87 @@
# retoor <retoor@molodetz.nl>
from pathlib import Path
from devplacepy.services.jobs.isslop.analysis.engine import _javascript_alias_prefixes
from devplacepy.services.jobs.isslop.analysis.signals import FileContext, RepoContext
from devplacepy.services.jobs.isslop.analysis.signals.hallucination import detect_hallucination
def _context(text: str, aliases: frozenset = frozenset(), deps: frozenset = frozenset({"next", "react", "@clerk/nextjs"})):
repo = RepoContext(
root=Path("/tmp"),
python_dependencies=frozenset(),
javascript_dependencies=deps,
local_python_modules=frozenset(),
has_python_manifest=False,
has_javascript_manifest=True,
javascript_alias_prefixes=aliases,
)
return FileContext(
path=Path("/tmp/x.tsx"),
relative="src/x.tsx",
language="typescript",
text=text,
lines=text.splitlines(),
comments=[],
metrics=None,
repo=repo,
fingerprint_only=False,
)
def test_path_aliases_are_never_unresolved():
text = (
"import { Sponsors } from '@/components/Sponsors';\n"
"import config from '~/config';\n"
"import db from '#app/db';\n"
"import { page } from '$app/stores';\n"
)
assert detect_hallucination(_context(text)) == []
def test_tsconfig_alias_prefixes_are_respected():
text = "import { helper } from 'src/utils/helper';\n"
assert len(detect_hallucination(_context(text))) == 1
assert detect_hallucination(_context(text, aliases=frozenset({"src/"}))) == []
def test_declared_package_subpaths_resolve():
text = (
"import Image from 'next/image';\n"
"import { auth } from '@clerk/nextjs/server';\n"
"import { useState } from 'react';\n"
)
assert detect_hallucination(_context(text)) == []
def test_node_builtins_and_schemes_resolve():
text = (
"import fs from 'node:fs';\n"
"import hooks from 'async_hooks';\n"
"import content from 'virtual:generated';\n"
)
assert detect_hallucination(_context(text)) == []
def test_genuinely_missing_package_is_flagged():
findings = detect_hallucination(_context("import magic from 'left-pad-ultra';\n"))
assert len(findings) == 1
assert findings[0].code == "DEP_UNRESOLVED"
assert "left-pad-ultra" in findings[0].title
def test_alias_prefix_parser_reads_jsonc(tmp_path):
(tmp_path / "tsconfig.json").write_text(
"""{
// path aliases
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"~lib/*": ["./lib/*"], /* legacy */
},
},
}""",
encoding="utf-8",
)
assert _javascript_alias_prefixes(tmp_path) == frozenset({"@/", "~lib/"})
@@ -0,0 +1,69 @@
# retoor <retoor@molodetz.nl>
from devplacepy.services.jobs.isslop.agent.classifier import AiVerdict
from devplacepy.services.jobs.isslop.agent.reporter import _summary_payload, fallback_report
from devplacepy.services.jobs.isslop.analysis.templates import TemplateEvidence
from devplacepy.services.jobs.isslop.analysis.scoring import FileScore, aggregate
from devplacepy.services.jobs.isslop.pipeline import apply_ai_verdicts
def _file(relative, sloc, origin, quality=10.0):
return FileScore(
relative=relative,
language="python",
sloc=sloc,
origin_score=origin,
quality_deficit=quality,
category="human-clean",
criticality=1.0,
signals=[],
)
def _verdict(path, probability):
return AiVerdict(
path=path,
origin_score=probability,
quality_deficit=10.0,
ai_probability=probability,
category="uncertain",
reasoning="",
notable_signals=[],
)
def test_apply_ai_verdicts_only_touches_reviewed_files():
scores = [_file("a.py", 500, 20.0), _file("b.py", 500, 20.0)]
adjusted = apply_ai_verdicts(scores, [_verdict("a.py", 80.0)])
assert adjusted[0].origin_score == round(0.6 * 20.0 + 0.4 * 80.0, 1)
assert adjusted[1].origin_score == 20.0
def test_hedging_verdicts_cannot_dominate_a_large_repo():
scores = [_file(f"f{i}.py", 200, 15.0) for i in range(100)]
verdicts = [_verdict(f"f{i}.py", 40.0) for i in range(12)]
static = aggregate(scores)
final = aggregate(apply_ai_verdicts(scores, verdicts))
assert static.ai_percent == 0.0
assert final.ai_percent < 5.0
assert final.human_percent > 95.0
def test_strong_verdict_on_heavy_file_moves_the_verdict():
scores = [_file("huge.py", 5000, 30.0)] + [_file(f"s{i}.py", 50, 15.0) for i in range(10)]
final = aggregate(apply_ai_verdicts(scores, [_verdict("huge.py", 95.0)]))
static = aggregate(scores)
assert final.ai_percent > static.ai_percent + 30.0
def test_report_payload_grade_matches_final_scores():
scores = [_file("a.py", 300, 60.0, 40.0), _file("b.py", 200, 20.0)]
verdicts = [_verdict("a.py", 90.0)]
adjusted = apply_ai_verdicts(scores, verdicts)
final = aggregate(adjusted)
payload = _summary_payload("https://x.example/repo", "git", final, adjusted, verdicts, 0, [], {}, TemplateEvidence())
assert payload["repo_scores"]["grade"] == final.grade
assert payload["repo_scores"]["human_percent"] == final.human_percent
markdown = fallback_report(payload)
assert f"grade **{final.grade}**" in markdown
assert f"**{final.human_percent}% human**" in markdown
@@ -0,0 +1,83 @@
# retoor <retoor@molodetz.nl>
from devplacepy.services.jobs.isslop.analysis.scoring import (
CATEGORY_HUMAN_CLEAN,
CATEGORY_HUMAN_MESSY,
CATEGORY_SLOP,
CATEGORY_SOPHISTICATED,
CATEGORY_UNCERTAIN,
categorize,
compose_slop_score,
grade_for,
)
def test_compose_slop_score_bounds():
assert compose_slop_score(0.0, 0.0) == 0.0
assert compose_slop_score(100.0, 100.0) == 100.0
assert 0.0 <= compose_slop_score(50.0, 50.0) <= 100.0
def test_compose_slop_score_weighs_ai_heavier_than_quality():
ai_heavy = compose_slop_score(80.0, 20.0)
quality_heavy = compose_slop_score(20.0, 80.0)
assert ai_heavy > quality_heavy
def test_grade_for_is_monotonic():
grades = [grade_for(value) for value in (0.0, 20.0, 40.0, 60.0, 80.0, 100.0)]
order = "ABCDF"
positions = [order.index(grade) for grade in grades]
assert positions == sorted(positions)
assert grades[0] == "A"
assert grades[-1] == "F"
def test_categorize_corners():
assert categorize(95.0, 95.0) == CATEGORY_SLOP
assert categorize(95.0, 5.0) == CATEGORY_SOPHISTICATED
assert categorize(5.0, 5.0) == CATEGORY_HUMAN_CLEAN
assert categorize(5.0, 95.0) == CATEGORY_HUMAN_MESSY
assert categorize(50.0, 50.0) == CATEGORY_UNCERTAIN
def test_ai_fraction_is_continuous_and_monotonic():
from devplacepy.services.jobs.isslop.analysis.scoring import ai_fraction
assert ai_fraction(0.0) == 0.0
assert ai_fraction(35.0) == 0.0
assert ai_fraction(50.0) == 0.5
assert ai_fraction(65.0) == 1.0
assert ai_fraction(100.0) == 1.0
samples = [ai_fraction(v) for v in range(30, 71)]
assert samples == sorted(samples)
steps = [b - a for a, b in zip(samples, samples[1:])]
assert max(steps) < 0.06
def test_adjust_for_images_recomputes_grade_consistently():
from devplacepy.services.jobs.isslop.analysis.scoring import (
RepoScores,
adjust_for_images,
compose_slop_score,
grade_for,
)
scores = RepoScores(
origin_score=10.0,
quality_deficit=10.0,
slop_score=compose_slop_score(2.0, 10.0),
grade=grade_for(compose_slop_score(2.0, 10.0)),
category="human-clean",
human_percent=98.0,
ai_percent=2.0,
confidence="medium",
strong_signal_count=0,
medium_signal_count=0,
files_scored=50,
)
adjusted = adjust_for_images(scores, 90.0)
assert adjusted.ai_percent == round(0.75 * 2.0 + 0.25 * 90.0, 1)
assert adjusted.human_percent == round(100.0 - adjusted.ai_percent, 1)
assert adjusted.slop_score == compose_slop_score(adjusted.ai_percent, scores.quality_deficit)
assert adjusted.grade == grade_for(adjusted.slop_score)
@@ -0,0 +1,79 @@
# retoor <retoor@molodetz.nl>
import json
from devplacepy.services.jobs.isslop.analysis.scoring import RepoScores, adjust_for_template, aggregate
from devplacepy.services.jobs.isslop.analysis.templates import detect_template
def _scores(ai=2.0, quality=20.0):
return RepoScores(
origin_score=20.0,
quality_deficit=quality,
slop_score=7.8,
grade="A",
category="human-clean",
human_percent=100.0 - ai,
ai_percent=ai,
confidence="medium",
strong_signal_count=0,
medium_signal_count=0,
files_scored=50,
)
def test_untouched_boilerplate_is_detected(tmp_path):
(tmp_path / "package.json").write_text(json.dumps({
"name": "next-js-boilerplate",
"author": "Ixartz (https://github.com/ixartz)",
}))
(tmp_path / "README.md").write_text(
"# Boilerplate and Starter for Next.js\n\nSponsors welcome. Demo at https://demo.nextjs-boilerplate.com\n"
)
for artifact in (".storybook", ".husky", ".devcontainer"):
(tmp_path / artifact).mkdir()
for artifact in ("commitlint.config.ts", "playwright.config.ts", "vitest.config.ts", "drizzle.config.ts", "crowdin.yml", "CHANGELOG.md"):
(tmp_path / artifact).write_text("")
evidence = detect_template(tmp_path)
assert evidence.score >= 70.0
assert any("known template" in marker for marker in evidence.markers)
adjusted = adjust_for_template(_scores(), evidence.score)
assert adjusted.grade in ("C", "D", "F")
assert adjusted.ai_percent >= 55.0
assert adjusted.category == "ai-slop"
def test_t3_scaffold_metadata_is_detected(tmp_path):
(tmp_path / "package.json").write_text(json.dumps({
"name": "my-cool-product",
"ct3aMetadata": {"initVersion": "7.39.0"},
}))
evidence = detect_template(tmp_path)
assert any("create-t3-app" in marker for marker in evidence.markers)
def test_genuine_project_produces_no_evidence(tmp_path):
(tmp_path / "package.json").write_text(json.dumps({
"name": "acme-billing-portal",
"description": "Internal billing portal for Acme",
}))
(tmp_path / "README.md").write_text("# Acme billing portal\n\nInternal tool, see the wiki for onboarding.\n")
(tmp_path / "Dockerfile").write_text("")
evidence = detect_template(tmp_path)
assert evidence.score < 35.0
assert adjust_for_template(_scores(), evidence.score) == _scores()
def test_weak_evidence_below_gate_never_adjusts():
base = _scores()
assert adjust_for_template(base, 34.9) == base
adjusted = adjust_for_template(base, 90.0)
assert adjusted.ai_percent == round(0.85 * 90.0, 1)
assert adjusted.human_percent == round(100.0 - adjusted.ai_percent, 1)
assert adjusted.category == "ai-slop"
def test_confident_but_partial_evidence_caps_category_at_uncertain():
adjusted = adjust_for_template(_scores(), 55.0)
assert adjusted.category == "uncertain"
assert adjusted.grade != "A"
+33
View File
@@ -0,0 +1,33 @@
# retoor <retoor@molodetz.nl>
from PIL import Image
from devplacepy.routers.tools.isslop import MEDIA_NAME_PATTERN
from devplacepy.services.jobs.isslop.agent.vision import make_thumbnail
def test_make_thumbnail_preserves_aspect_ratio(tmp_path):
source = tmp_path / "wide.png"
Image.new("RGB", (1600, 400), (255, 0, 0)).save(source)
name = make_thumbnail(source, tmp_path / "media", "assets/wide.png")
assert name is not None
assert MEDIA_NAME_PATTERN.match(name)
with Image.open(tmp_path / "media" / name) as thumb:
assert thumb.format == "WEBP"
assert thumb.width <= 480 and thumb.height <= 480
assert abs(thumb.width / thumb.height - 4.0) < 0.05
def test_make_thumbnail_is_deterministic_per_path(tmp_path):
source = tmp_path / "icon.png"
Image.new("RGBA", (256, 256), (0, 0, 255, 128)).save(source)
first = make_thumbnail(source, tmp_path / "media", "public/icon.png")
second = make_thumbnail(source, tmp_path / "media", "public/icon.png")
assert first == second
assert make_thumbnail(source, tmp_path / "media", "other/icon.png") != first
def test_make_thumbnail_fails_soft_on_unreadable(tmp_path):
source = tmp_path / "broken.png"
source.write_bytes(b"not an image")
assert make_thumbnail(source, tmp_path / "media", "broken.png") is None
@@ -0,0 +1,36 @@
# retoor <retoor@molodetz.nl>
import pytest
from devplacepy.services.jobs.isslop.acquisition.workspace import (
safe_relative_path,
slugify,
workspace_for,
)
def test_workspace_for_stays_inside_root(tmp_path):
workspace = workspace_for(tmp_path, "https://github.com/owner/repo", "abc123")
assert workspace.parent == tmp_path.resolve()
assert "github.com-owner-repo" in workspace.name
assert workspace.name.endswith("abc123")
def test_workspace_for_rejects_escaping_uid(tmp_path):
with pytest.raises(ValueError):
workspace_for(tmp_path, "https://example.com", "../../../outside/x")
def test_safe_relative_path_rejects_traversal(tmp_path):
resolved = safe_relative_path(tmp_path, "../../../etc/passwd")
assert resolved.is_relative_to(tmp_path.resolve())
def test_safe_relative_path_keeps_nested_files(tmp_path):
resolved = safe_relative_path(tmp_path, "assets/js/app.js")
assert resolved == tmp_path.resolve() / "assets" / "js" / "app.js"
def test_slugify_strips_scheme_and_specials():
assert slugify("https://Example.com/Owner/Repo.git") == "example.com-owner-repo.git"
assert slugify("!!!") == "source"