Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package processing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
func TestCleanupExpiredDeletesTerminalJobsAndCascadesProducts(t *testing.T) {
|
||||
dsn := os.Getenv("DATABASE_URL")
|
||||
if dsn == "" {
|
||||
t.Skip("DATABASE_URL not set")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
pg, err := pgxpool.New(ctx, dsn)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer pg.Close()
|
||||
|
||||
var companyID uuid.UUID
|
||||
err = pg.QueryRow(ctx, `
|
||||
SELECT company_id
|
||||
FROM raw_products
|
||||
WHERE company_id IS NOT NULL
|
||||
ORDER BY updated_at DESC
|
||||
LIMIT 1`).Scan(&companyID)
|
||||
if errorsIsNoRows(err) {
|
||||
t.Skip("no raw_products rows available")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var userID uuid.UUID
|
||||
err = pg.QueryRow(ctx, `SELECT id FROM users ORDER BY created_at DESC LIMIT 1`).Scan(&userID)
|
||||
if errorsIsNoRows(err) {
|
||||
t.Skip("no users rows available")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var rawID uuid.UUID
|
||||
err = pg.QueryRow(ctx, `
|
||||
SELECT id
|
||||
FROM raw_products
|
||||
WHERE company_id = $1
|
||||
ORDER BY updated_at DESC
|
||||
LIMIT 1`, companyID).Scan(&rawID)
|
||||
if errorsIsNoRows(err) {
|
||||
t.Skip("no raw_products for selected company")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
insertJob := func(status string, age string) uuid.UUID {
|
||||
t.Helper()
|
||||
var id uuid.UUID
|
||||
err := pg.QueryRow(ctx, `
|
||||
INSERT INTO processing_jobs (
|
||||
company_id, user_id, status, total_products, processed_products,
|
||||
processing_type, started_at, completed_at, updated_at, created_at
|
||||
) VALUES (
|
||||
$1, $2, $3, 1, 1, 'full',
|
||||
now() - interval '`+age+`',
|
||||
now() - interval '`+age+`',
|
||||
now() - interval '`+age+`',
|
||||
now() - interval '`+age+`'
|
||||
)
|
||||
RETURNING id`, companyID, userID, status).Scan(&id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
oldCompleted := insertJob("completed", "45 days")
|
||||
oldFailed := insertJob("failed", "45 days")
|
||||
oldRunning := insertJob("running", "45 days")
|
||||
freshCompleted := insertJob("completed", "1 day")
|
||||
|
||||
defer func() {
|
||||
for _, id := range []uuid.UUID{oldCompleted, oldFailed, oldRunning, freshCompleted} {
|
||||
_, _ = pg.Exec(context.Background(), `DELETE FROM processing_job_products WHERE job_id = $1`, id)
|
||||
_, _ = pg.Exec(context.Background(), `DELETE FROM processing_jobs WHERE id = $1`, id)
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err := pg.Exec(ctx, `
|
||||
INSERT INTO processing_job_products (job_id, raw_product_id, status, updated_at, created_at)
|
||||
VALUES ($1, $2, 'processed', now() - interval '45 days', now() - interval '45 days')`,
|
||||
oldCompleted, rawID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
res, err := CleanupExpired(ctx, pg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res.JobsDeleted < 2 {
|
||||
t.Fatalf("jobs_deleted=%d want >= 2", res.JobsDeleted)
|
||||
}
|
||||
|
||||
assertGone := func(id uuid.UUID, label string) {
|
||||
t.Helper()
|
||||
var n int
|
||||
if err := pg.QueryRow(ctx, `SELECT COUNT(*) FROM processing_jobs WHERE id = $1`, id).Scan(&n); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != 0 {
|
||||
t.Fatalf("%s job still present", label)
|
||||
}
|
||||
}
|
||||
assertPresent := func(id uuid.UUID, label string) {
|
||||
t.Helper()
|
||||
var n int
|
||||
if err := pg.QueryRow(ctx, `SELECT COUNT(*) FROM processing_jobs WHERE id = $1`, id).Scan(&n); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != 1 {
|
||||
t.Fatalf("%s job missing", label)
|
||||
}
|
||||
}
|
||||
|
||||
assertGone(oldCompleted, "old completed")
|
||||
assertGone(oldFailed, "old failed")
|
||||
assertPresent(oldRunning, "old running")
|
||||
assertPresent(freshCompleted, "fresh completed")
|
||||
|
||||
var productCount int
|
||||
if err := pg.QueryRow(ctx, `
|
||||
SELECT COUNT(*) FROM processing_job_products WHERE job_id = $1`, oldCompleted).Scan(&productCount); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if productCount != 0 {
|
||||
t.Fatalf("cascaded products remaining=%d want 0", productCount)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user