kiwi/tests/test_tasks/test_runner.py
pyr0ball c18bfec8f5
Some checks are pending
CI / Backend (Python) (push) Waiting to run
CI / Frontend (Vue) (push) Waiting to run
Mirror / mirror (push) Waiting to run
fix(lint): add ruff config, fix all lint errors for GitHub CI
- pyproject.toml: add [tool.ruff] config suppressing E402/W293 globally,
  F841/E741/E702 in tests, E741 in scripts
- inventory.py: split semicolon import (E702)
- recipes.py: fix logger -> log (F821 undefined name)
- shopping.py: rename l -> lnk in list comprehension (E741)
- format_conversion.py: noqa F841 on CUDA flag (used as future hook)
- backfill_keywords.py: rename done -> _done (F841)
- ingest_purplecarrot.py: drop == True comparison (E712)
- Auto-fix: I001 import sorting, F401 unused imports across all files
2026-07-06 02:49:02 -07:00

126 lines
4.4 KiB
Python

"""Tests for kiwi background task runner."""
from __future__ import annotations
import json
import sqlite3
from pathlib import Path
from unittest.mock import patch
import pytest
from app.tasks.runner import (
LLM_TASK_TYPES,
VRAM_BUDGETS,
insert_task,
run_task,
)
@pytest.fixture
def tmp_db(tmp_path: Path) -> Path:
db = tmp_path / "kiwi.db"
conn = sqlite3.connect(db)
conn.executescript("""
CREATE TABLE background_tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_type TEXT NOT NULL,
job_id INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'queued',
params TEXT,
error TEXT,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE inventory_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
expiry_date TEXT
);
INSERT INTO inventory_items (name, expiry_date) VALUES ('mystery tofu', NULL);
""")
conn.commit()
conn.close()
return db
def test_llm_task_types_defined():
assert "expiry_llm_fallback" in LLM_TASK_TYPES
def test_vram_budgets_defined():
assert "expiry_llm_fallback" in VRAM_BUDGETS
assert VRAM_BUDGETS["expiry_llm_fallback"] > 0
def test_insert_task_creates_row(tmp_db: Path):
task_id, is_new = insert_task(tmp_db, "expiry_llm_fallback", job_id=1)
assert is_new is True
conn = sqlite3.connect(tmp_db)
row = conn.execute("SELECT status FROM background_tasks WHERE id=?", (task_id,)).fetchone()
conn.close()
assert row[0] == "queued"
def test_insert_task_dedup(tmp_db: Path):
id1, new1 = insert_task(tmp_db, "expiry_llm_fallback", job_id=1)
id2, new2 = insert_task(tmp_db, "expiry_llm_fallback", job_id=1)
assert id1 == id2
assert new1 is True
assert new2 is False
def test_run_task_expiry_success(tmp_db: Path):
params = json.dumps({"product_name": "Tofu", "category": "protein", "location": "fridge"})
task_id, _ = insert_task(tmp_db, "expiry_llm_fallback", job_id=1, params=params)
with patch("app.tasks.runner.ExpirationPredictor") as MockPredictor:
instance = MockPredictor.return_value
instance._llm_predict_days.return_value = 7
run_task(tmp_db, task_id, "expiry_llm_fallback", 1, params)
conn = sqlite3.connect(tmp_db)
item = conn.execute("SELECT expiry_date FROM inventory_items WHERE id=1").fetchone()
task = conn.execute("SELECT status FROM background_tasks WHERE id=?", (task_id,)).fetchone()
conn.close()
assert item[0] is not None, "expiry_date should be set"
assert task[0] == "completed"
def test_run_task_expiry_llm_returns_none(tmp_db: Path):
"""If LLM returns None, task completes without writing expiry_date."""
params = json.dumps({"product_name": "Unknown widget", "location": "fridge"})
task_id, _ = insert_task(tmp_db, "expiry_llm_fallback", job_id=1, params=params)
with patch("app.tasks.runner.ExpirationPredictor") as MockPredictor:
instance = MockPredictor.return_value
instance._llm_predict_days.return_value = None
run_task(tmp_db, task_id, "expiry_llm_fallback", 1, params)
conn = sqlite3.connect(tmp_db)
item = conn.execute("SELECT expiry_date FROM inventory_items WHERE id=1").fetchone()
task = conn.execute("SELECT status FROM background_tasks WHERE id=?", (task_id,)).fetchone()
conn.close()
assert item[0] is None, "expiry_date should remain NULL when LLM returns None"
assert task[0] == "completed"
def test_run_task_missing_product_name_marks_failed(tmp_db: Path):
params = json.dumps({})
task_id, _ = insert_task(tmp_db, "expiry_llm_fallback", job_id=1, params=params)
run_task(tmp_db, task_id, "expiry_llm_fallback", 1, params)
conn = sqlite3.connect(tmp_db)
task = conn.execute("SELECT status, error FROM background_tasks WHERE id=?", (task_id,)).fetchone()
conn.close()
assert task[0] == "failed"
assert "product_name" in task[1]
def test_run_task_unknown_type_marks_failed(tmp_db: Path):
task_id, _ = insert_task(tmp_db, "expiry_llm_fallback", job_id=1)
run_task(tmp_db, task_id, "unknown_type", 1, None)
conn = sqlite3.connect(tmp_db)
task = conn.execute("SELECT status FROM background_tasks WHERE id=?", (task_id,)).fetchone()
conn.close()
assert task[0] == "failed"