From 3bfd5a339f4ce5b46efc4b1b1afe974e43175665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 4 Mar 2022 12:12:10 +0100 Subject: [PATCH] Fix database tests getting interrupted The root cause was a 2nd `context.Context()` that was used in `constructTestJob()`, which cancelled when that function returned. The cancellation of the context caused an interrupt in the SQLite driver, which got into a race condition and could cause an interrupt on a subsequent database query. --- internal/manager/persistence/jobs_test.go | 21 ++++++---- .../persistence/task_scheduler_test.go | 39 +++++++++++-------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/internal/manager/persistence/jobs_test.go b/internal/manager/persistence/jobs_test.go index 9dce1e69..d94a0ff7 100644 --- a/internal/manager/persistence/jobs_test.go +++ b/internal/manager/persistence/jobs_test.go @@ -199,11 +199,19 @@ func TestTaskAssignToWorker(t *testing.T) { task, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID) assert.NoError(t, err) - w := createWorker(t, db) + w := createWorker(ctx, t, db) assert.NoError(t, db.TaskAssignToWorker(ctx, task, w)) - assert.Equal(t, w, task.Worker) - assert.Equal(t, w.ID, *task.WorkerID) + if task.Worker == nil { + t.Error("task.Worker == nil") + } else { + assert.Equal(t, w, task.Worker) + } + if task.WorkerID == nil { + t.Error("task.WorkerID == nil") + } else { + assert.Equal(t, w.ID, *task.WorkerID) + } } func TestFetchTasksOfWorkerInStatus(t *testing.T) { @@ -213,7 +221,7 @@ func TestFetchTasksOfWorkerInStatus(t *testing.T) { task, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID) assert.NoError(t, err) - w := createWorker(t, db) + w := createWorker(ctx, t, db) assert.NoError(t, db.TaskAssignToWorker(ctx, task, w)) tasks, err := db.FetchTasksOfWorkerInStatus(ctx, w, task.Status) @@ -313,10 +321,7 @@ func jobTasksTestFixtures(t *testing.T) (context.Context, context.CancelFunc, *D return ctx, cancel, db, dbJob, authoredJob } -func createWorker(t *testing.T, db *DB) *Worker { - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel() - +func createWorker(ctx context.Context, t *testing.T, db *DB) *Worker { w := Worker{ UUID: "f0a123a9-ab05-4ce2-8577-94802cfe74a4", Name: "дрон", diff --git a/internal/manager/persistence/task_scheduler_test.go b/internal/manager/persistence/task_scheduler_test.go index cc8eb770..57ef4bdb 100644 --- a/internal/manager/persistence/task_scheduler_test.go +++ b/internal/manager/persistence/task_scheduler_test.go @@ -32,10 +32,12 @@ import ( "git.blender.org/flamenco/pkg/api" ) +const testContextTimeout = 100 * time.Millisecond + func TestNoTasks(t *testing.T) { db, dbCloser := CreateTestDB(t) defer dbCloser() - ctx, ctxCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, ctxCancel := context.WithTimeout(context.Background(), testContextTimeout) defer ctxCancel() w := linuxWorker(t, db) @@ -48,14 +50,14 @@ func TestNoTasks(t *testing.T) { func TestOneJobOneTask(t *testing.T) { db, dbCloser := CreateTestDB(t) defer dbCloser() - ctx, ctxCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, ctxCancel := context.WithTimeout(context.Background(), testContextTimeout) defer ctxCancel() w := linuxWorker(t, db) authTask := authorTestTask("the task", "blender") atj := authorTestJob("b6a1d859-122f-4791-8b78-b943329a9989", "simple-blender-render", authTask) - job := constructTestJob(t, db, atj) + job := constructTestJob(ctx, t, db, atj) task, err := db.ScheduleTask(ctx, &w) assert.NoError(t, err) @@ -85,7 +87,7 @@ func TestOneJobOneTask(t *testing.T) { func TestOneJobThreeTasksByPrio(t *testing.T) { db, dbCloser := CreateTestDB(t) defer dbCloser() - ctx, ctxCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, ctxCancel := context.WithTimeout(context.Background(), testContextTimeout) defer ctxCancel() w := linuxWorker(t, db) @@ -99,7 +101,7 @@ func TestOneJobThreeTasksByPrio(t *testing.T) { "simple-blender-render", att1, att2, att3) - job := constructTestJob(t, db, atj) + job := constructTestJob(ctx, t, db, atj) task, err := db.ScheduleTask(ctx, &w) assert.NoError(t, err) @@ -118,7 +120,7 @@ func TestOneJobThreeTasksByPrio(t *testing.T) { func TestOneJobThreeTasksByDependencies(t *testing.T) { db, dbCloser := CreateTestDB(t) defer dbCloser() - ctx, ctxCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, ctxCancel := context.WithTimeout(context.Background(), testContextTimeout) defer ctxCancel() w := linuxWorker(t, db) @@ -132,7 +134,7 @@ func TestOneJobThreeTasksByDependencies(t *testing.T) { "1295757b-e668-4c49-8b89-f73db8270e42", "simple-blender-render", att1, att2, att3) - job := constructTestJob(t, db, atj) + job := constructTestJob(ctx, t, db, atj) task, err := db.ScheduleTask(ctx, &w) assert.NoError(t, err) @@ -146,7 +148,7 @@ func TestOneJobThreeTasksByDependencies(t *testing.T) { func TestTwoJobsThreeTasks(t *testing.T) { db, dbCloser := CreateTestDB(t) defer dbCloser() - ctx, ctxCancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + ctx, ctxCancel := context.WithTimeout(context.Background(), testContextTimeout) defer ctxCancel() w := linuxWorker(t, db) @@ -173,8 +175,8 @@ func TestTwoJobsThreeTasks(t *testing.T) { att2_1, att2_2, att2_3) atj2.Priority = 100 // Increase priority over job 1. - constructTestJob(t, db, atj1) - job2 := constructTestJob(t, db, atj2) + constructTestJob(ctx, t, db, atj1) + job2 := constructTestJob(ctx, t, db, atj2) task, err := db.ScheduleTask(ctx, &w) assert.NoError(t, err) @@ -190,21 +192,24 @@ func TestTwoJobsThreeTasks(t *testing.T) { // To test: variable replacement func constructTestJob( - t *testing.T, db *DB, authoredJob job_compilers.AuthoredJob, + ctx context.Context, t *testing.T, db *DB, authoredJob job_compilers.AuthoredJob, ) *Job { - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel() - err := db.StoreAuthoredJob(ctx, authoredJob) - assert.NoError(t, err) + if err != nil { + t.Fatalf("storing authored job: %v", err) + } dbJob, err := db.FetchJob(ctx, authoredJob.JobID) - assert.NoError(t, err) + if err != nil { + t.Fatalf("fetching authored job: %v", err) + } // Queue the job. dbJob.Status = api.JobStatusQueued err = db.SaveJobStatus(ctx, dbJob) - assert.NoError(t, err) + if err != nil { + t.Fatalf("queueing job: %v", err) + } return dbJob }