Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
148 lines
3.7 KiB
Go
148 lines
3.7 KiB
Go
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)
|
|
}
|
|
}
|