Manager tests: replace assert.NoError() with require.NoError()

Back in the days when I wrote the code, I didn't know about the
`require` package yet. Using `require.NoError()` makes the test code
more straight-forward.

No functional changes, except that when tests fail, they now fail
without panicking.
This commit is contained in:
Sybren A. Stüvel 2024-03-16 11:09:18 +01:00
parent 1fee086cef
commit 3f4a9025fe
27 changed files with 432 additions and 506 deletions

@ -8,7 +8,7 @@ import (
"time"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
"projects.blender.org/studio/flamenco/pkg/api"
)
@ -52,7 +52,7 @@ func TestQueryJobs(t *testing.T) {
Return([]*persistence.Job{&activeJob, &deletionQueuedJob}, nil)
err := mf.flamenco.QueryJobs(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
expectedJobs := api.JobsQueryResult{
Jobs: []api.Job{
@ -160,7 +160,7 @@ func TestFetchTask(t *testing.T) {
Return([]*persistence.Worker{&taskWorker}, nil)
err := mf.flamenco.FetchTask(echoCtx, taskUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echoCtx, http.StatusOK, expectAPITask)
}

@ -88,7 +88,7 @@ func TestSubmitJobWithoutSettings(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.SubmitJob(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
}
func TestSubmitJobWithSettings(t *testing.T) {
@ -177,7 +177,7 @@ func TestSubmitJobWithSettings(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.SubmitJob(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
}
func TestSubmitJobWithEtag(t *testing.T) {
@ -202,7 +202,7 @@ func TestSubmitJobWithEtag(t *testing.T) {
{
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
err := mf.flamenco.SubmitJob(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echoCtx,
http.StatusPreconditionFailed, "rejecting job because its settings are outdated, refresh the job type")
}
@ -240,7 +240,7 @@ func TestSubmitJobWithEtag(t *testing.T) {
submittedJob.TypeEtag = ptr("correct etag")
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
err := mf.flamenco.SubmitJob(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
}
}
@ -318,7 +318,7 @@ func TestSubmitJobWithShamanCheckoutID(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.SubmitJob(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
}
func TestSubmitJobWithWorkerTag(t *testing.T) {
@ -437,7 +437,7 @@ func TestGetJobTypeHappy(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.GetJobType(echoCtx, "test-job-type")
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echoCtx, http.StatusOK, jt)
}
@ -453,7 +453,7 @@ func TestGetJobTypeUnknown(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.GetJobType(echoCtx, "nonexistent-type")
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echoCtx, http.StatusNotFound, api.Error{
Code: http.StatusNotFound,
Message: "no such job type known",
@ -482,7 +482,7 @@ func TestSubmitJobCheckWithEtag(t *testing.T) {
{
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
err := mf.flamenco.SubmitJobCheck(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echoCtx,
http.StatusPreconditionFailed, "rejecting job because its settings are outdated, refresh the job type")
}
@ -502,7 +502,7 @@ func TestSubmitJobCheckWithEtag(t *testing.T) {
submittedJob.TypeEtag = ptr("correct etag")
echoCtx := mf.prepareMockedJSONRequest(submittedJob)
err := mf.flamenco.SubmitJobCheck(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
}
}
@ -516,7 +516,7 @@ func TestGetJobTypeError(t *testing.T) {
Return(api.AvailableJobType{}, errors.New("didn't expect this"))
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.GetJobType(echoCtx, "error")
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echoCtx, http.StatusInternalServerError, "error getting job type")
}
@ -537,7 +537,7 @@ func TestSetJobStatus_nonexistentJob(t *testing.T) {
// Do the call.
echoCtx := mf.prepareMockedJSONRequest(statusUpdate)
err := mf.flamenco.SetJobStatus(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echoCtx, http.StatusNotFound, "no such job")
}
@ -571,7 +571,7 @@ func TestSetJobStatus_happy(t *testing.T) {
// Do the call.
echoCtx := mf.prepareMockedJSONRequest(statusUpdate)
err := mf.flamenco.SetJobStatus(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -592,7 +592,7 @@ func TestSetJobPrio_nonexistentJob(t *testing.T) {
// Do the call.
echoCtx := mf.prepareMockedJSONRequest(prioUpdate)
err := mf.flamenco.SetJobStatus(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echoCtx, http.StatusNotFound, "no such job")
}
@ -634,7 +634,7 @@ func TestSetJobPrio(t *testing.T) {
mf.broadcaster.EXPECT().BroadcastJobUpdate(expectUpdate)
err := mf.flamenco.SetJobPriority(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -668,7 +668,7 @@ func TestSetJobStatusFailedToRequeueing(t *testing.T) {
// Do the call.
err := mf.flamenco.SetJobStatus(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -714,7 +714,7 @@ func TestSetTaskStatusQueued(t *testing.T) {
// Do the call.
err := mf.flamenco.SetTaskStatus(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -748,7 +748,7 @@ func TestFetchTaskLogTail(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchTaskLogTail(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
// Check that a 204 No Content is also returned when the task log file on disk exists, but is empty.
@ -758,7 +758,7 @@ func TestFetchTaskLogTail(t *testing.T) {
echoCtx = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchTaskLogTail(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -794,7 +794,7 @@ func TestFetchTaskLogInfo(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchTaskLogInfo(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
// Check that a 204 No Content is also returned when the task log file on disk exists, but is empty.
@ -803,7 +803,7 @@ func TestFetchTaskLogInfo(t *testing.T) {
echoCtx = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchTaskLogInfo(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
// Check that otherwise we actually get the info.
@ -813,7 +813,7 @@ func TestFetchTaskLogInfo(t *testing.T) {
echoCtx = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchTaskLogInfo(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echoCtx, http.StatusOK, api.TaskLogInfo{
JobId: jobID,
TaskId: taskID,
@ -842,7 +842,7 @@ func TestFetchJobLastRenderedInfo(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchJobLastRenderedInfo(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
expectBody := api.JobLastRenderedImageInfo{
Base: "/job-files/relative/path",
@ -857,7 +857,7 @@ func TestFetchJobLastRenderedInfo(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchJobLastRenderedInfo(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
}
@ -876,7 +876,7 @@ func TestFetchGlobalLastRenderedInfo(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchGlobalLastRenderedInfo(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -893,7 +893,7 @@ func TestFetchGlobalLastRenderedInfo(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchGlobalLastRenderedInfo(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
expectBody := api.JobLastRenderedImageInfo{
Base: "/job-files/relative/path",
@ -927,7 +927,7 @@ func TestDeleteJob(t *testing.T) {
// Do the call.
err := mf.flamenco.DeleteJob(echoCtx, jobID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}

@ -43,7 +43,7 @@ func TestGetVariables(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.GetVariables(echoCtx, api.ManagerVariableAudienceWorkers, "linux")
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echoCtx, http.StatusOK, api.ManagerVariables{
AdditionalProperties: map[string]api.ManagerVariable{
"blender": {Value: "/usr/local/blender", IsTwoway: false},
@ -61,7 +61,7 @@ func TestGetVariables(t *testing.T) {
echoCtx := mf.prepareMockedRequest(nil)
err := mf.flamenco.GetVariables(echoCtx, api.ManagerVariableAudienceUsers, "troll")
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echoCtx, http.StatusOK, api.ManagerVariables{})
}
}
@ -208,9 +208,7 @@ func TestCheckSharedStoragePath(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(
api.PathCheckInput{Path: path})
err := mf.flamenco.CheckSharedStoragePath(echoCtx)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
return echoCtx
}
@ -230,9 +228,8 @@ func TestCheckSharedStoragePath(t *testing.T) {
Cause: "Directory checked successfully",
})
files, err := filepath.Glob(filepath.Join(mf.tempdir, "*"))
if assert.NoError(t, err) {
assert.Empty(t, files, "After a query, there should not be any leftovers")
}
require.NoError(t, err)
assert.Empty(t, files, "After a query, there should not be any leftovers")
// Test inaccessible path.
// For some reason, this doesn't work on Windows, and creating a file in
@ -253,12 +250,9 @@ func TestCheckSharedStoragePath(t *testing.T) {
parentPath := filepath.Join(mf.tempdir, "deep")
testPath := filepath.Join(parentPath, "nesting")
if err := os.Mkdir(parentPath, fs.ModePerm); !assert.NoError(t, err) {
t.FailNow()
}
if err := os.Mkdir(testPath, fs.FileMode(0)); !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, os.Mkdir(parentPath, fs.ModePerm))
require.NoError(t, os.Mkdir(testPath, fs.FileMode(0)))
echoCtx := doTest(testPath)
result := api.PathCheckResult{}
getResponseJSON(t, echoCtx, http.StatusOK, &result)
@ -295,9 +289,7 @@ func TestSaveSetupAssistantConfig(t *testing.T) {
// Call the API.
echoCtx := mf.prepareMockedJSONRequest(body)
err := mf.flamenco.SaveSetupAssistantConfig(echoCtx)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
return savedConfig
@ -378,9 +370,7 @@ func metaTestFixtures(t *testing.T) (mockedFlamenco, func()) {
mf := newMockedFlamenco(mockCtrl)
tempdir, err := os.MkdirTemp("", "test-temp-dir")
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
mf.tempdir = tempdir
finish := func() {

@ -16,6 +16,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/api_impl/mocks"
"projects.blender.org/studio/flamenco/internal/manager/config"
@ -182,14 +183,10 @@ func getResponseJSON(t *testing.T, echoCtx echo.Context, expectStatusCode int, a
}
actualJSON, err := io.ReadAll(resp.Body)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
err = json.Unmarshal(actualJSON, actualPayloadPtr)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
}
// assertResponseJSON asserts that a recorded response is JSON with the given HTTP status code.
@ -204,14 +201,10 @@ func assertResponseJSON(t *testing.T, echoCtx echo.Context, expectStatusCode int
}
expectJSON, err := json.Marshal(expectBody)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
actualJSON, err := io.ReadAll(resp.Body)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assert.JSONEq(t, string(expectJSON), string(actualJSON))
}

@ -33,7 +33,7 @@ func TestFetchWorkers(t *testing.T) {
echo := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchWorkers(echo)
assert.NoError(t, err)
require.NoError(t, err)
// Check the response
workers := api.WorkerList{
@ -74,7 +74,7 @@ func TestFetchWorker(t *testing.T) {
Return(nil, fmt.Errorf("wrapped: %w", persistence.ErrWorkerNotFound))
echo := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchWorker(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusNotFound, fmt.Sprintf("worker %q not found", workerUUID))
// Test database error fetching worker.
@ -82,7 +82,7 @@ func TestFetchWorker(t *testing.T) {
Return(nil, errors.New("some unknown error"))
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchWorker(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusInternalServerError, "error fetching worker: some unknown error")
// Test with worker that does NOT have a status change requested, and DOES have an assigned task.
@ -97,7 +97,7 @@ func TestFetchWorker(t *testing.T) {
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchWorker(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.Worker{
WorkerSummary: api.WorkerSummary{
Id: workerUUID,
@ -126,7 +126,7 @@ func TestFetchWorker(t *testing.T) {
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchWorker(echo, worker.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.Worker{
WorkerSummary: api.WorkerSummary{
Id: workerUUID,
@ -155,7 +155,7 @@ func TestDeleteWorker(t *testing.T) {
Return(nil, fmt.Errorf("wrapped: %w", persistence.ErrWorkerNotFound))
echo := mf.prepareMockedRequest(nil)
err := mf.flamenco.DeleteWorker(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusNotFound, fmt.Sprintf("worker %q not found", workerUUID))
// Test with existing worker.
@ -176,7 +176,7 @@ func TestDeleteWorker(t *testing.T) {
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.DeleteWorker(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
@ -214,7 +214,7 @@ func TestRequestWorkerStatusChange(t *testing.T) {
IsLazy: true,
})
err := mf.flamenco.RequestWorkerStatusChange(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
@ -258,7 +258,7 @@ func TestRequestWorkerStatusChangeRevert(t *testing.T) {
IsLazy: true,
})
err := mf.flamenco.RequestWorkerStatusChange(echo, workerUUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}

@ -8,6 +8,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/config"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
@ -77,7 +78,7 @@ func TestTaskUpdate(t *testing.T) {
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
// Check the saved task.
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, mockTask.UUID, statusChangedtask.UUID)
assert.Equal(t, mockTask.UUID, actUpdatedTask.UUID)
assert.Equal(t, mockTask.UUID, touchedTask.UUID)
@ -148,7 +149,7 @@ func TestTaskUpdateFailed(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(taskUpdate)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -164,7 +165,7 @@ func TestTaskUpdateFailed(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(taskUpdate)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
}
@ -248,7 +249,7 @@ func TestBlockingAfterFailure(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(taskUpdate)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -279,7 +280,7 @@ func TestBlockingAfterFailure(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(taskUpdate)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
@ -314,7 +315,7 @@ func TestBlockingAfterFailure(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(taskUpdate)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}
}
@ -381,6 +382,6 @@ func TestJobFailureAfterWorkerTaskFailure(t *testing.T) {
echoCtx := mf.prepareMockedJSONRequest(taskUpdate)
requestWorkerStore(echoCtx, &worker)
err := mf.flamenco.TaskUpdate(echoCtx, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echoCtx)
}

@ -12,6 +12,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/config"
"projects.blender.org/studio/flamenco/internal/manager/last_rendered"
@ -61,7 +62,7 @@ func TestTaskScheduleHappy(t *testing.T) {
mf.broadcaster.EXPECT().BroadcastWorkerUpdate(gomock.Any())
err := mf.flamenco.ScheduleTask(echo)
assert.NoError(t, err)
require.NoError(t, err)
// Check the response
assignedTask := api.AssignedTask{
@ -98,7 +99,7 @@ func TestTaskScheduleNoTaskAvailable(t *testing.T) {
mf.persistence.EXPECT().WorkerSeen(bgCtx, &worker)
err := mf.flamenco.ScheduleTask(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
@ -119,7 +120,7 @@ func TestTaskScheduleNonActiveStatus(t *testing.T) {
mf.persistence.EXPECT().WorkerSeen(bgCtx, &worker)
err := mf.flamenco.ScheduleTask(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
resp := getRecordedResponse(echoCtx)
assert.Equal(t, http.StatusConflict, resp.StatusCode)
@ -142,7 +143,7 @@ func TestTaskScheduleOtherStatusRequested(t *testing.T) {
mf.persistence.EXPECT().WorkerSeen(bgCtx, &worker)
err := mf.flamenco.ScheduleTask(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
expectBody := api.WorkerStateChange{StatusRequested: api.WorkerStatusAsleep}
assertResponseJSON(t, echoCtx, http.StatusLocked, expectBody)
@ -169,7 +170,7 @@ func TestTaskScheduleOtherStatusRequestedAndBadState(t *testing.T) {
mf.persistence.EXPECT().WorkerSeen(bgCtx, &worker)
err := mf.flamenco.ScheduleTask(echoCtx)
assert.NoError(t, err)
require.NoError(t, err)
expectBody := api.WorkerStateChange{StatusRequested: api.WorkerStatusAwake}
assertResponseJSON(t, echoCtx, http.StatusLocked, expectBody)
@ -206,7 +207,7 @@ func TestWorkerSignOn(t *testing.T) {
})
requestWorkerStore(echo, &worker)
err := mf.flamenco.SignOn(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.WorkerStateChange{
StatusRequested: api.WorkerStatusAsleep,
@ -253,7 +254,7 @@ func TestWorkerSignoffTaskRequeue(t *testing.T) {
})
err := mf.flamenco.SignOff(echo)
assert.NoError(t, err)
require.NoError(t, err)
resp := getRecordedResponse(echo)
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
@ -292,7 +293,7 @@ func TestWorkerRememberPreviousStatus(t *testing.T) {
echo := mf.prepareMockedRequest(nil)
requestWorkerStore(echo, &worker)
err := mf.flamenco.SignOff(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
assert.Equal(t, api.WorkerStatusAwake, worker.StatusRequested)
@ -329,7 +330,7 @@ func TestWorkerDontRememberPreviousStatus(t *testing.T) {
echo := mf.prepareMockedRequest(nil)
requestWorkerStore(echo, &worker)
err := mf.flamenco.SignOff(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
@ -347,9 +348,8 @@ func TestWorkerState(t *testing.T) {
echo := mf.prepareMockedRequest(nil)
requestWorkerStore(echo, &worker)
err := mf.flamenco.WorkerState(echo)
if assert.NoError(t, err) {
assertResponseNoContent(t, echo)
}
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
// State change requested.
@ -361,11 +361,10 @@ func TestWorkerState(t *testing.T) {
requestWorkerStore(echo, &worker)
err := mf.flamenco.WorkerState(echo)
if assert.NoError(t, err) {
assertResponseJSON(t, echo, http.StatusOK, api.WorkerStateChange{
StatusRequested: requestStatus,
})
}
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.WorkerStateChange{
StatusRequested: requestStatus,
})
}
}
@ -402,7 +401,7 @@ func TestWorkerStateChanged(t *testing.T) {
})
requestWorkerStore(echo, &worker)
err := mf.flamenco.WorkerStateChanged(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
@ -445,7 +444,7 @@ func TestWorkerStateChangedAfterChangeRequest(t *testing.T) {
})
requestWorkerStore(echo, &worker)
err := mf.flamenco.WorkerStateChanged(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
@ -475,7 +474,7 @@ func TestWorkerStateChangedAfterChangeRequest(t *testing.T) {
})
requestWorkerStore(echo, &worker)
err := mf.flamenco.WorkerStateChanged(echo)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoContent(t, echo)
}
}
@ -514,7 +513,7 @@ func TestMayWorkerRun(t *testing.T) {
{
echo := prepareRequest()
err := mf.flamenco.MayWorkerRun(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.MayKeepRunning{
MayKeepRunning: false,
Reason: "task not assigned to this worker",
@ -529,7 +528,7 @@ func TestMayWorkerRun(t *testing.T) {
echo := prepareRequest()
task.WorkerID = &worker.ID
err := mf.flamenco.MayWorkerRun(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.MayKeepRunning{
MayKeepRunning: true,
})
@ -541,7 +540,7 @@ func TestMayWorkerRun(t *testing.T) {
task.WorkerID = &worker.ID
task.Status = api.TaskStatusCanceled
err := mf.flamenco.MayWorkerRun(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.MayKeepRunning{
MayKeepRunning: false,
Reason: "task is in non-runnable status \"canceled\"",
@ -555,7 +554,7 @@ func TestMayWorkerRun(t *testing.T) {
task.WorkerID = &worker.ID
task.Status = api.TaskStatusActive
err := mf.flamenco.MayWorkerRun(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.MayKeepRunning{
MayKeepRunning: false,
Reason: "worker status change requested",
@ -573,7 +572,7 @@ func TestMayWorkerRun(t *testing.T) {
task.WorkerID = &worker.ID
task.Status = api.TaskStatusActive
err := mf.flamenco.MayWorkerRun(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.MayKeepRunning{
MayKeepRunning: true,
})
@ -618,7 +617,7 @@ func TestTaskOutputProduced(t *testing.T) {
echo := prepareRequest(nil)
err := mf.flamenco.TaskOutputProduced(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusLengthRequired, "Content-Length header required")
}
@ -633,7 +632,7 @@ func TestTaskOutputProduced(t *testing.T) {
echo := prepareRequest(bytes.NewReader(bodyBytes))
err := mf.flamenco.TaskOutputProduced(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusRequestEntityTooLarge,
"image too large; should be max %v bytes", last_rendered.MaxImageSizeBytes)
}
@ -648,7 +647,7 @@ func TestTaskOutputProduced(t *testing.T) {
mf.lastRender.EXPECT().QueueImage(gomock.Any()).Return(last_rendered.ErrMimeTypeUnsupported)
err := mf.flamenco.TaskOutputProduced(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusUnsupportedMediaType, `unsupported mime type "image/openexr"`)
}
@ -661,7 +660,7 @@ func TestTaskOutputProduced(t *testing.T) {
mf.lastRender.EXPECT().QueueImage(gomock.Any()).Return(last_rendered.ErrQueueFull)
err := mf.flamenco.TaskOutputProduced(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusTooManyRequests, "image processing queue is full")
}
@ -687,7 +686,7 @@ func TestTaskOutputProduced(t *testing.T) {
})
err := mf.flamenco.TaskOutputProduced(echo, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertResponseNoBody(t, echo, http.StatusAccepted)
if assert.NotNil(t, actualPayload) {

@ -58,7 +58,7 @@ func exampleSubmittedJob() api.SubmittedJob {
func mockedClock(t *testing.T) clock.Clock {
c := clock.NewMock()
now, err := time.ParseInLocation("2006-01-02T15:04:05", "2006-01-02T15:04:05", time.Local)
assert.NoError(t, err)
require.NoError(t, err)
c.Set(now)
return c
}
@ -67,7 +67,7 @@ func TestSimpleBlenderRenderHappy(t *testing.T) {
c := mockedClock(t)
s, err := Load(c)
assert.NoError(t, err)
require.NoError(t, err)
// Compiling a job should be really fast.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
@ -172,7 +172,7 @@ func TestSimpleBlenderRenderWindowsPaths(t *testing.T) {
c := mockedClock(t)
s, err := Load(c)
assert.NoError(t, err)
require.NoError(t, err)
// Compiling a job should be really fast.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
@ -307,9 +307,8 @@ func TestEtag(t *testing.T) {
{ // Test without etag.
aj, err := s.Compile(ctx, sj)
if assert.NoError(t, err, "job without etag should always be accepted") {
assert.NotNil(t, aj)
}
require.NoError(t, err, "job without etag should always be accepted")
assert.NotNil(t, aj)
}
{ // Test with bad etag.
@ -321,9 +320,8 @@ func TestEtag(t *testing.T) {
{ // Test with correct etag.
sj.TypeEtag = ptr(expectEtag)
aj, err := s.Compile(ctx, sj)
if assert.NoError(t, err, "job with correct etag should be accepted") {
assert.NotNil(t, aj)
}
require.NoError(t, err, "job with correct etag should be accepted")
assert.NotNil(t, aj)
}
}

@ -6,11 +6,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFrameChunkerHappyBlenderStyle(t *testing.T) {
chunks, err := jsFrameChunker("1..10,20..25,40,3..8", 4)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []string{"1-4", "5-8", "9,10,20,21", "22-25", "40"}, chunks)
}
@ -21,24 +22,24 @@ func TestFrameChunkerHappySmallInput(t *testing.T) {
// Just one frame.
chunks, err := jsFrameChunker("47", 4)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []string{"47"}, chunks)
// Just one range of exactly one chunk.
chunks, err = jsFrameChunker("1-3", 3)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []string{"1-3"}, chunks)
}
func TestFrameChunkerHappyRegularStyle(t *testing.T) {
chunks, err := jsFrameChunker("1-10,20-25,40", 4)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []string{"1-4", "5-8", "9,10,20,21", "22-25", "40"}, chunks)
}
func TestFrameChunkerHappyExtraWhitespace(t *testing.T) {
chunks, err := jsFrameChunker(" 1 .. 10,\t20..25\n,40 ", 4)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []string{"1-4", "5-8", "9,10,20,21", "22-25", "40"}, chunks)
}
@ -50,7 +51,7 @@ func TestFrameChunkerUnhappy(t *testing.T) {
func TestFrameRangeExplode(t *testing.T) {
frames, err := frameRangeExplode("1..10,20..25,40")
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []int{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
20, 21, 22, 23, 24, 25, 40,

@ -8,12 +8,13 @@ import (
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestLoadScriptsFrom_skip_nonjs(t *testing.T) {
thisDirFS := os.DirFS(".")
compilers, err := loadScriptsFrom(thisDirFS)
assert.NoError(t, err, "input without JS files should not cause errors")
require.NoError(t, err, "input without JS files should not cause errors")
assert.Empty(t, compilers)
}
@ -21,7 +22,7 @@ func TestLoadScriptsFrom_on_disk_js(t *testing.T) {
scriptsFS := os.DirFS("scripts-for-unittest")
compilers, err := loadScriptsFrom(scriptsFS)
assert.NoError(t, err)
require.NoError(t, err)
expectKeys := map[string]bool{
"echo-and-sleep": true,
"simple-blender-render": true,
@ -34,7 +35,7 @@ func TestLoadScriptsFrom_embedded(t *testing.T) {
initEmbeddedFS()
compilers, err := loadScriptsFrom(embeddedScriptsFS)
assert.NoError(t, err)
require.NoError(t, err)
expectKeys := map[string]bool{
"echo-sleep-test": true,
"simple-blender-render": true,
@ -48,7 +49,7 @@ func BenchmarkLoadScripts_fromEmbedded(b *testing.B) {
for i := 0; i < b.N; i++ {
compilers, err := loadScriptsFrom(embeddedScriptsFS)
assert.NoError(b, err)
require.NoError(b, err)
assert.NotEmpty(b, compilers)
}
}
@ -59,7 +60,7 @@ func BenchmarkLoadScripts_fromDisk(b *testing.B) {
onDiskFS := os.DirFS("scripts-for-unittest")
for i := 0; i < b.N; i++ {
compilers, err := loadScriptsFrom(onDiskFS)
assert.NoError(b, err)
require.NoError(b, err)
assert.NotEmpty(b, compilers)
}
}

@ -9,6 +9,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/job_deleter/mocks"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
"projects.blender.org/studio/flamenco/pkg/shaman"
@ -32,16 +33,16 @@ func TestQueueJobDeletion(t *testing.T) {
job1 := &persistence.Job{UUID: "2f7d910f-08a6-4b0f-8ecb-b3946939ed1b"}
mocks.persist.EXPECT().RequestJobDeletion(mocks.ctx, job1)
assert.NoError(t, s.QueueJobDeletion(mocks.ctx, job1))
require.NoError(t, s.QueueJobDeletion(mocks.ctx, job1))
// Call twice more to overflow the queue.
job2 := &persistence.Job{UUID: "e8fbe41c-ed24-46df-ba63-8d4f5524071b"}
mocks.persist.EXPECT().RequestJobDeletion(mocks.ctx, job2)
assert.NoError(t, s.QueueJobDeletion(mocks.ctx, job2))
require.NoError(t, s.QueueJobDeletion(mocks.ctx, job2))
job3 := &persistence.Job{UUID: "deeab6ba-02cd-42c0-b7bc-2367a2f04c7d"}
mocks.persist.EXPECT().RequestJobDeletion(mocks.ctx, job3)
assert.NoError(t, s.QueueJobDeletion(mocks.ctx, job3))
require.NoError(t, s.QueueJobDeletion(mocks.ctx, job3))
if assert.Len(t, s.queue, 2, "the first two job UUID should be queued") {
assert.Equal(t, job1.UUID, <-s.queue)
@ -111,7 +112,7 @@ func TestDeleteJobWithoutShaman(t *testing.T) {
mocks.persist.EXPECT().DeleteJob(mocks.ctx, jobUUID)
mocks.persist.EXPECT().RequestIntegrityCheck()
mocks.broadcaster.EXPECT().BroadcastJobUpdate(gomock.Any())
assert.NoError(t, s.deleteJob(mocks.ctx, jobUUID))
require.NoError(t, s.deleteJob(mocks.ctx, jobUUID))
}
func TestDeleteJobWithShaman(t *testing.T) {
@ -163,7 +164,7 @@ func TestDeleteJobWithShaman(t *testing.T) {
mocks.persist.EXPECT().DeleteJob(mocks.ctx, jobUUID)
mocks.persist.EXPECT().RequestIntegrityCheck()
mocks.broadcaster.EXPECT().BroadcastJobUpdate(gomock.Any())
assert.NoError(t, s.deleteJob(mocks.ctx, jobUUID))
require.NoError(t, s.deleteJob(mocks.ctx, jobUUID))
}
func jobDeleterTestFixtures(t *testing.T) (*Service, func(), *JobDeleterMocks) {

@ -10,6 +10,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/local_storage"
)
@ -38,9 +39,9 @@ func TestQueueImage(t *testing.T) {
defer storage.MustErase()
lrp := New(storage)
assert.NoError(t, lrp.QueueImage(payload))
assert.NoError(t, lrp.QueueImage(payload))
assert.NoError(t, lrp.QueueImage(payload))
require.NoError(t, lrp.QueueImage(payload))
require.NoError(t, lrp.QueueImage(payload))
require.NoError(t, lrp.QueueImage(payload))
assert.ErrorIs(t, lrp.QueueImage(payload), ErrQueueFull)
}
@ -48,9 +49,7 @@ func TestProcessImage(t *testing.T) {
// Load the test image. Note that this intentionally has an approximate 21:9
// ratio, whereas the thumbnail specs define a 16:9 ratio.
imgBytes, err := os.ReadFile("last_rendered_test.jpg")
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
jobID := "e078438b-c9f5-43e6-9e86-52f8be91dd12"
payload := Payload{
@ -87,15 +86,11 @@ func TestProcessImage(t *testing.T) {
assertImageSize := func(spec Thumbspec) {
path := filepath.Join(jobdir, spec.Filename)
file, err := os.Open(path)
if !assert.NoError(t, err, "thumbnail %s should be openable", spec.Filename) {
return
}
require.NoError(t, err, "thumbnail %s should be openable", spec.Filename)
defer file.Close()
img, format, err := image.Decode(file)
if !assert.NoErrorf(t, err, "thumbnail %s should be decodable", spec.Filename) {
return
}
require.NoErrorf(t, err, "thumbnail %s should be decodable", spec.Filename)
assert.Equalf(t, "jpeg", format, "thumbnail %s not written in the expected format", spec.Filename)
assert.LessOrEqualf(t, img.Bounds().Dx(), spec.MaxWidth, "thumbnail %s has wrong width", spec.Filename)

@ -24,16 +24,14 @@ func TestNewNextToExe(t *testing.T) {
func TestNewNextToExe_noSubdir(t *testing.T) {
exePath, err := os.Executable()
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
exeName := filepath.Base(exePath)
// The filesystem in an empty "subdirectory" next to the executable should
// contain the executable.
si := NewNextToExe("")
_, err = os.Stat(filepath.Join(si.rootPath, exeName))
assert.NoErrorf(t, err, "should be able to stat this executable %s", exeName)
require.NoErrorf(t, err, "should be able to stat this executable %s", exeName)
}
func TestForJob(t *testing.T) {
@ -52,10 +50,10 @@ func TestErase(t *testing.T) {
jobPath := si.ForJob("08e126ef-d773-468b-8bab-19a8213cf2ff")
assert.NoDirExists(t, jobPath, "getting a path should not create it")
assert.NoError(t, os.MkdirAll(jobPath, os.ModePerm))
require.NoError(t, os.MkdirAll(jobPath, os.ModePerm))
assert.DirExists(t, jobPath, "os.MkdirAll is borked")
assert.NoError(t, si.Erase())
require.NoError(t, si.Erase())
assert.NoDirExists(t, si.rootPath, "Erase() should erase the root path, and everything in it")
}
@ -66,13 +64,13 @@ func TestRemoveJobStorage(t *testing.T) {
jobPath := si.ForJob(jobUUID)
assert.NoDirExists(t, jobPath, "getting a path should not create it")
assert.NoError(t, os.MkdirAll(jobPath, os.ModePerm))
require.NoError(t, os.MkdirAll(jobPath, os.ModePerm))
assert.DirExists(t, jobPath, "os.MkdirAll is borked")
taskFile := filepath.Join(jobPath, "task-07c33f32-b345-4da9-8834-9c91532cd97e.txt")
assert.NoError(t, os.WriteFile(taskFile, []byte("dummy task log"), 0o777))
require.NoError(t, os.WriteFile(taskFile, []byte("dummy task log"), 0o777))
assert.NoError(t, si.RemoveJobStorage(context.Background(), jobUUID))
require.NoError(t, si.RemoveJobStorage(context.Background(), jobUUID))
assert.NoDirExists(t, jobPath, "RemoveJobStorage() should erase the entire job-specific storage dir, and everything in it")
// See if the test assumption (that job dir is in another sub-dir of the root,
@ -91,13 +89,13 @@ func TestRemoveJobStorageWithoutJobUUID(t *testing.T) {
jobPath := si.ForJob("")
assert.NoDirExists(t, jobPath, "getting a path should not create it")
assert.NoError(t, os.MkdirAll(jobPath, os.ModePerm))
require.NoError(t, os.MkdirAll(jobPath, os.ModePerm))
assert.DirExists(t, jobPath, "os.MkdirAll is borked")
taskFile := filepath.Join(jobPath, "task-07c33f32-b345-4da9-8834-9c91532cd97e.txt")
assert.NoError(t, os.WriteFile(taskFile, []byte("dummy task log"), 0o777))
require.NoError(t, os.WriteFile(taskFile, []byte("dummy task log"), 0o777))
assert.NoError(t, si.RemoveJobStorage(context.Background(), ""))
require.NoError(t, si.RemoveJobStorage(context.Background(), ""))
assert.NoDirExists(t, jobPath, "RemoveJobStorage() should erase the entire job-specific storage dir, and everything in it")
// See if the test assumption (that a jobless dir is directly inside the root) still holds.

@ -18,11 +18,11 @@ func TestAddWorkerToJobBlocklist(t *testing.T) {
{
// Add a worker to the block list.
err := db.AddWorkerToJobBlocklist(ctx, job, worker, "blender")
assert.NoError(t, err)
require.NoError(t, err)
list := []JobBlock{}
tx := db.gormDB.Model(&JobBlock{}).Scan(&list)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
if assert.Len(t, list, 1) {
entry := list[0]
assert.Equal(t, entry.JobID, job.ID)
@ -34,11 +34,11 @@ func TestAddWorkerToJobBlocklist(t *testing.T) {
{
// Adding the same worker again should be a no-op.
err := db.AddWorkerToJobBlocklist(ctx, job, worker, "blender")
assert.NoError(t, err)
require.NoError(t, err)
list := []JobBlock{}
tx := db.gormDB.Model(&JobBlock{}).Scan(&list)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
assert.Len(t, list, 1, "No new entry should have been created")
}
}
@ -50,10 +50,10 @@ func TestFetchJobBlocklist(t *testing.T) {
// Add a worker to the block list.
worker := createWorker(ctx, t, db)
err := db.AddWorkerToJobBlocklist(ctx, job, worker, "blender")
assert.NoError(t, err)
require.NoError(t, err)
list, err := db.FetchJobBlocklist(ctx, job.UUID)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, list, 1) {
entry := list[0]
@ -73,17 +73,17 @@ func TestClearJobBlocklist(t *testing.T) {
// Add a worker and some entries to the block list.
worker := createWorker(ctx, t, db)
err := db.AddWorkerToJobBlocklist(ctx, job, worker, "blender")
assert.NoError(t, err)
require.NoError(t, err)
err = db.AddWorkerToJobBlocklist(ctx, job, worker, "ffmpeg")
assert.NoError(t, err)
require.NoError(t, err)
// Clear the blocklist.
err = db.ClearJobBlocklist(ctx, job)
assert.NoError(t, err)
require.NoError(t, err)
// Check that it is indeed empty.
list, err := db.FetchJobBlocklist(ctx, job.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, list)
}
@ -94,17 +94,17 @@ func TestRemoveFromJobBlocklist(t *testing.T) {
// Add a worker and some entries to the block list.
worker := createWorker(ctx, t, db)
err := db.AddWorkerToJobBlocklist(ctx, job, worker, "blender")
assert.NoError(t, err)
require.NoError(t, err)
err = db.AddWorkerToJobBlocklist(ctx, job, worker, "ffmpeg")
assert.NoError(t, err)
require.NoError(t, err)
// Remove an entry.
err = db.RemoveFromJobBlocklist(ctx, job.UUID, worker.UUID, "ffmpeg")
assert.NoError(t, err)
require.NoError(t, err)
// Check that the other entry is still there.
list, err := db.FetchJobBlocklist(ctx, job.UUID)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, list, 1) {
entry := list[0]
@ -120,7 +120,7 @@ func TestWorkersLeftToRun(t *testing.T) {
// No workers.
left, err := db.WorkersLeftToRun(ctx, job, "blender")
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, left)
worker1 := createWorker(ctx, t, db)
@ -146,30 +146,27 @@ func TestWorkersLeftToRun(t *testing.T) {
// Three workers, no blocklist.
left, err = db.WorkersLeftToRun(ctx, job, "blender")
if assert.NoError(t, err) {
assert.Equal(t, uuidMap(worker1, worker2, workerC1), left)
}
require.NoError(t, err)
assert.Equal(t, uuidMap(worker1, worker2, workerC1), left)
// Two workers, one blocked.
_ = db.AddWorkerToJobBlocklist(ctx, job, worker1, "blender")
left, err = db.WorkersLeftToRun(ctx, job, "blender")
if assert.NoError(t, err) {
assert.Equal(t, uuidMap(worker2, workerC1), left)
}
require.NoError(t, err)
assert.Equal(t, uuidMap(worker2, workerC1), left)
// All workers blocked.
_ = db.AddWorkerToJobBlocklist(ctx, job, worker2, "blender")
_ = db.AddWorkerToJobBlocklist(ctx, job, workerC1, "blender")
left, err = db.WorkersLeftToRun(ctx, job, "blender")
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, left)
// Two workers, unknown job.
fakeJob := Job{Model: Model{ID: 327}}
left, err = db.WorkersLeftToRun(ctx, &fakeJob, "blender")
if assert.NoError(t, err) {
assert.Equal(t, uuidMap(worker1, worker2, workerC1), left)
}
require.NoError(t, err)
assert.Equal(t, uuidMap(worker1, worker2, workerC1), left)
}
func TestWorkersLeftToRunWithTags(t *testing.T) {
@ -233,7 +230,7 @@ func TestWorkersLeftToRunWithTags(t *testing.T) {
// All taged workers blocked.
_ = db.AddWorkerToJobBlocklist(ctx, job, workerC13, "blender")
left, err = db.WorkersLeftToRun(ctx, job, "blender")
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, left)
}
@ -261,25 +258,21 @@ func TestCountTaskFailuresOfWorker(t *testing.T) {
// Multiple failures.
numBlender1, err := db.CountTaskFailuresOfWorker(ctx, dbJob, worker1, "blender")
if assert.NoError(t, err) {
assert.Equal(t, 2, numBlender1)
}
require.NoError(t, err)
assert.Equal(t, 2, numBlender1)
// Single failure, but multiple tasks exist of this type.
numBlender2, err := db.CountTaskFailuresOfWorker(ctx, dbJob, worker2, "blender")
if assert.NoError(t, err) {
assert.Equal(t, 1, numBlender2)
}
require.NoError(t, err)
assert.Equal(t, 1, numBlender2)
// Single failure, only one task of this type exists.
numFFMpeg1, err := db.CountTaskFailuresOfWorker(ctx, dbJob, worker1, "ffmpeg")
if assert.NoError(t, err) {
assert.Equal(t, 1, numFFMpeg1)
}
require.NoError(t, err)
assert.Equal(t, 1, numFFMpeg1)
// No failure.
numFFMpeg2, err := db.CountTaskFailuresOfWorker(ctx, dbJob, worker2, "ffmpeg")
if assert.NoError(t, err) {
assert.Equal(t, 0, numFFMpeg2)
}
require.NoError(t, err)
assert.Equal(t, 0, numFFMpeg2)
}

@ -29,14 +29,14 @@ func TestSimpleQuery(t *testing.T) {
result, err := db.QueryJobs(ctx, api.JobsQuery{
StatusIn: &[]api.JobStatus{api.JobStatusActive, api.JobStatusCanceled},
})
assert.NoError(t, err)
require.NoError(t, err)
assert.Len(t, result, 0)
// Check job was returned properly on correct status.
result, err = db.QueryJobs(ctx, api.JobsQuery{
StatusIn: &[]api.JobStatus{api.JobStatusUnderConstruction, api.JobStatusCanceled},
})
assert.NoError(t, err)
require.NoError(t, err)
if !assert.Len(t, result, 1) {
t.FailNow()
}
@ -68,7 +68,7 @@ func TestQueryMetadata(t *testing.T) {
AdditionalProperties: map[string]string{
"project": "Secret Future Project",
}}})
assert.NoError(t, err)
require.NoError(t, err)
assert.Len(t, result, 0)
// Check job was returned properly when querying for the right project.
@ -77,7 +77,7 @@ func TestQueryMetadata(t *testing.T) {
AdditionalProperties: map[string]string{
"project": testJob.Metadata["project"],
}}})
assert.NoError(t, err)
require.NoError(t, err)
if !assert.Len(t, result, 1) {
t.FailNow()
}
@ -89,7 +89,7 @@ func TestQueryMetadata(t *testing.T) {
AdditionalProperties: map[string]string{
"project": otherJob.Metadata["project"],
}}})
assert.NoError(t, err)
require.NoError(t, err)
if !assert.Len(t, result, 1) {
t.FailNow()
}
@ -100,7 +100,7 @@ func TestQueryMetadata(t *testing.T) {
OrderBy: &[]string{"status"},
Metadata: &api.JobsQuery_Metadata{AdditionalProperties: map[string]string{}},
})
assert.NoError(t, err)
require.NoError(t, err)
if !assert.Len(t, result, 2) {
t.FailNow()
}
@ -132,12 +132,12 @@ func TestQueryJobTaskSummaries(t *testing.T) {
// Sanity check for the above code, there should be 6 tasks overall, 3 per job.
var numTasks int64
tx := db.gormDB.Model(&Task{}).Count(&numTasks)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
assert.Equal(t, int64(6), numTasks)
// Get the task summaries of a particular job.
summaries, err := db.QueryJobTaskSummaries(ctx, job.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Len(t, summaries, len(expectTaskUUIDs))
for _, summary := range summaries {

@ -24,10 +24,10 @@ func TestStoreAuthoredJob(t *testing.T) {
job := createTestAuthoredJobWithTasks()
err := db.StoreAuthoredJob(ctx, job)
assert.NoError(t, err)
require.NoError(t, err)
fetchedJob, err := db.FetchJob(ctx, job.JobID)
assert.NoError(t, err)
require.NoError(t, err)
assert.NotNil(t, fetchedJob)
// Test contents of fetched job
@ -43,10 +43,10 @@ func TestStoreAuthoredJob(t *testing.T) {
// Fetch tasks of job.
var dbJob Job
tx := db.gormDB.Where(&Job{UUID: job.JobID}).Find(&dbJob)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
var tasks []Task
tx = db.gormDB.Where("job_id = ?", dbJob.ID).Find(&tasks)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
if len(tasks) != 3 {
t.Fatalf("expected 3 tasks, got %d", len(tasks))
@ -170,7 +170,7 @@ func TestDeleteJobWithoutFK(t *testing.T) {
// Test the deletion did not happen.
_, err = db.FetchJob(ctx, authJob.JobID)
assert.NoError(t, err, "job should not have been deleted")
require.NoError(t, err, "job should not have been deleted")
}
func TestRequestJobDeletion(t *testing.T) {
@ -185,20 +185,20 @@ func TestRequestJobDeletion(t *testing.T) {
db.gormDB.NowFunc = func() time.Time { return mockNow }
err := db.RequestJobDeletion(ctx, job1)
assert.NoError(t, err)
require.NoError(t, err)
assert.True(t, job1.DeleteRequested())
assert.True(t, job1.DeleteRequestedAt.Valid)
assert.Equal(t, job1.DeleteRequestedAt.Time, mockNow)
dbJob1, err := db.FetchJob(ctx, job1.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.True(t, job1.DeleteRequested())
assert.True(t, dbJob1.DeleteRequestedAt.Valid)
assert.WithinDuration(t, mockNow, dbJob1.DeleteRequestedAt.Time, time.Second)
// Other jobs shouldn't be touched.
dbJob2, err := db.FetchJob(ctx, authoredJob2.JobID)
assert.NoError(t, err)
require.NoError(t, err)
assert.False(t, dbJob2.DeleteRequested())
assert.False(t, dbJob2.DeleteRequestedAt.Valid)
}
@ -228,7 +228,7 @@ func TestRequestJobMassDeletion(t *testing.T) {
timeOfDeleteRequest := origGormNow()
db.gormDB.NowFunc = func() time.Time { return timeOfDeleteRequest }
uuids, err := db.RequestJobMassDeletion(ctx, job3.UpdatedAt)
assert.NoError(t, err)
require.NoError(t, err)
db.gormDB.NowFunc = origGormNow
@ -301,14 +301,14 @@ func TestFetchJobsDeletionRequested(t *testing.T) {
}
err := db.RequestJobDeletion(ctx, job1)
assert.NoError(t, err)
require.NoError(t, err)
err = db.RequestJobDeletion(ctx, job2)
assert.NoError(t, err)
require.NoError(t, err)
err = db.RequestJobDeletion(ctx, job3)
assert.NoError(t, err)
require.NoError(t, err)
actualUUIDs, err := db.FetchJobsDeletionRequested(ctx)
assert.NoError(t, err)
require.NoError(t, err)
assert.Len(t, actualUUIDs, 3, "3 out of 4 jobs were marked for deletion")
// Expect UUIDs in chronological order of deletion requests, so that the
@ -322,11 +322,11 @@ func TestJobHasTasksInStatus(t *testing.T) {
defer close()
hasTasks, err := db.JobHasTasksInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
require.NoError(t, err)
assert.True(t, hasTasks, "expected freshly-created job to have queued tasks")
hasTasks, err = db.JobHasTasksInStatus(ctx, job, api.TaskStatusActive)
assert.NoError(t, err)
require.NoError(t, err)
assert.False(t, hasTasks, "expected freshly-created job to have no active tasks")
}
@ -335,28 +335,28 @@ func TestCountTasksOfJobInStatus(t *testing.T) {
defer close()
numQueued, numTotal, err := db.CountTasksOfJobInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 3, numQueued)
assert.Equal(t, 3, numTotal)
// Make one task failed.
task, err := db.FetchTask(ctx, authoredJob.Tasks[0].UUID)
assert.NoError(t, err)
require.NoError(t, err)
task.Status = api.TaskStatusFailed
assert.NoError(t, db.SaveTask(ctx, task))
require.NoError(t, db.SaveTask(ctx, task))
numQueued, numTotal, err = db.CountTasksOfJobInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 2, numQueued)
assert.Equal(t, 3, numTotal)
numFailed, numTotal, err := db.CountTasksOfJobInStatus(ctx, job, api.TaskStatusFailed)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 1, numFailed)
assert.Equal(t, 3, numTotal)
numActive, numTotal, err := db.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 0, numActive)
assert.Equal(t, 3, numTotal)
}
@ -370,7 +370,7 @@ func TestCheckIfJobsHoldLargeNumOfTasks(t *testing.T) {
defer close()
numQueued, numTotal, err := db.CountTasksOfJobInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, numtasks, numQueued)
assert.Equal(t, numtasks, numTotal)
@ -392,22 +392,22 @@ func TestFetchJobsInStatus(t *testing.T) {
// Query single status
jobs, err := db.FetchJobsInStatus(ctx, api.JobStatusUnderConstruction)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []*Job{job1, job2, job3}, jobs)
// Query two statuses, where only one matches all jobs.
jobs, err = db.FetchJobsInStatus(ctx, api.JobStatusCanceled, api.JobStatusUnderConstruction)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []*Job{job1, job2, job3}, jobs)
// Update a job status, query for two of the three used statuses.
job1.Status = api.JobStatusQueued
assert.NoError(t, db.SaveJobStatus(ctx, job1))
require.NoError(t, db.SaveJobStatus(ctx, job1))
job2.Status = api.JobStatusRequeueing
assert.NoError(t, db.SaveJobStatus(ctx, job2))
require.NoError(t, db.SaveJobStatus(ctx, job2))
jobs, err = db.FetchJobsInStatus(ctx, api.JobStatusQueued, api.JobStatusUnderConstruction)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, jobs, 2) {
assert.Equal(t, job1.UUID, jobs[0].UUID)
assert.Equal(t, job3.UUID, jobs[1].UUID)
@ -419,35 +419,33 @@ func TestFetchTasksOfJobInStatus(t *testing.T) {
defer close()
allTasks, err := db.FetchTasksOfJob(ctx, job)
if !assert.NoError(t, err) {
return
}
require.NoError(t, err)
assert.Equal(t, job, allTasks[0].Job, "FetchTasksOfJob should set job pointer")
tasks, err := db.FetchTasksOfJobInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, allTasks, tasks)
assert.Equal(t, job, tasks[0].Job, "FetchTasksOfJobInStatus should set job pointer")
// Make one task failed.
task, err := db.FetchTask(ctx, authoredJob.Tasks[0].UUID)
assert.NoError(t, err)
require.NoError(t, err)
task.Status = api.TaskStatusFailed
assert.NoError(t, db.SaveTask(ctx, task))
require.NoError(t, db.SaveTask(ctx, task))
tasks, err = db.FetchTasksOfJobInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, []*Task{allTasks[1], allTasks[2]}, tasks)
// Check the failed task. This cannot directly compare to `allTasks[0]`
// because saving the task above changed some of its fields.
tasks, err = db.FetchTasksOfJobInStatus(ctx, job, api.TaskStatusFailed)
assert.NoError(t, err)
require.NoError(t, err)
assert.Len(t, tasks, 1)
assert.Equal(t, allTasks[0].ID, tasks[0].ID)
tasks, err = db.FetchTasksOfJobInStatus(ctx, job, api.TaskStatusActive)
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, tasks)
}
@ -456,10 +454,10 @@ func TestTaskAssignToWorker(t *testing.T) {
defer close()
task, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID)
assert.NoError(t, err)
require.NoError(t, err)
w := createWorker(ctx, t, db)
assert.NoError(t, db.TaskAssignToWorker(ctx, task, w))
require.NoError(t, db.TaskAssignToWorker(ctx, task, w))
if task.Worker == nil {
t.Error("task.Worker == nil")
@ -478,20 +476,20 @@ func TestFetchTasksOfWorkerInStatus(t *testing.T) {
defer close()
task, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID)
assert.NoError(t, err)
require.NoError(t, err)
w := createWorker(ctx, t, db)
assert.NoError(t, db.TaskAssignToWorker(ctx, task, w))
require.NoError(t, db.TaskAssignToWorker(ctx, task, w))
tasks, err := db.FetchTasksOfWorkerInStatus(ctx, w, task.Status)
assert.NoError(t, err)
require.NoError(t, err)
assert.Len(t, tasks, 1, "worker should have one task in status %q", task.Status)
assert.Equal(t, task.ID, tasks[0].ID)
assert.Equal(t, task.UUID, tasks[0].UUID)
assert.NotEqual(t, api.TaskStatusCanceled, task.Status)
tasks, err = db.FetchTasksOfWorkerInStatus(ctx, w, api.TaskStatusCanceled)
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, tasks, "worker should have no task in status %q", w)
}
@ -500,16 +498,16 @@ func TestTaskTouchedByWorker(t *testing.T) {
defer close()
task, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.True(t, task.LastTouchedAt.IsZero())
now := db.gormDB.NowFunc()
err = db.TaskTouchedByWorker(ctx, task)
assert.NoError(t, err)
require.NoError(t, err)
// Test the task instance as well as the database entry.
dbTask, err := db.FetchTask(ctx, task.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.WithinDuration(t, now, task.LastTouchedAt, time.Second)
assert.WithinDuration(t, now, dbTask.LastTouchedAt, time.Second)
}
@ -519,7 +517,7 @@ func TestAddWorkerToTaskFailedList(t *testing.T) {
defer close()
task, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID)
assert.NoError(t, err)
require.NoError(t, err)
worker1 := createWorker(ctx, t, db)
@ -528,30 +526,30 @@ func TestAddWorkerToTaskFailedList(t *testing.T) {
newWorker.ID = 0
newWorker.UUID = "89ed2b02-b51b-4cd4-b44a-4a1c8d01db85"
newWorker.Name = "Worker 2"
assert.NoError(t, db.SaveWorker(ctx, &newWorker))
require.NoError(t, db.SaveWorker(ctx, &newWorker))
worker2, err := db.FetchWorker(ctx, newWorker.UUID)
assert.NoError(t, err)
require.NoError(t, err)
// First failure should be registered just fine.
numFailed, err := db.AddWorkerToTaskFailedList(ctx, task, worker1)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 1, numFailed)
// Calling again should be a no-op and not cause any errors.
numFailed, err = db.AddWorkerToTaskFailedList(ctx, task, worker1)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 1, numFailed)
// Another worker should be able to fail this task as well.
numFailed, err = db.AddWorkerToTaskFailedList(ctx, task, worker2)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 2, numFailed)
// Deleting the task should also delete the failures.
assert.NoError(t, db.DeleteJob(ctx, authoredJob.JobID))
require.NoError(t, db.DeleteJob(ctx, authoredJob.JobID))
var num int64
tx := db.gormDB.Model(&TaskFailure{}).Count(&num)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
assert.Zero(t, num)
}
@ -569,9 +567,9 @@ func TestClearFailureListOfTask(t *testing.T) {
newWorker.ID = 0
newWorker.UUID = "89ed2b02-b51b-4cd4-b44a-4a1c8d01db85"
newWorker.Name = "Worker 2"
assert.NoError(t, db.SaveWorker(ctx, &newWorker))
require.NoError(t, db.SaveWorker(ctx, &newWorker))
worker2, err := db.FetchWorker(ctx, newWorker.UUID)
assert.NoError(t, err)
require.NoError(t, err)
// Store some failures for different tasks.
_, _ = db.AddWorkerToTaskFailedList(ctx, task1, worker1)
@ -579,10 +577,10 @@ func TestClearFailureListOfTask(t *testing.T) {
_, _ = db.AddWorkerToTaskFailedList(ctx, task2, worker1)
// Clearing should just update this one task.
assert.NoError(t, db.ClearFailureListOfTask(ctx, task1))
require.NoError(t, db.ClearFailureListOfTask(ctx, task1))
var failures = []TaskFailure{}
tx := db.gormDB.Model(&TaskFailure{}).Scan(&failures)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
if assert.Len(t, failures, 1) {
assert.Equal(t, task2.ID, failures[0].TaskID)
assert.Equal(t, worker1.ID, failures[0].WorkerID)
@ -615,10 +613,10 @@ func TestClearFailureListOfJob(t *testing.T) {
assert.Equal(t, 5, countTaskFailures(db))
// Clearing should be limited to the given job.
assert.NoError(t, db.ClearFailureListOfJob(ctx, dbJob1))
require.NoError(t, db.ClearFailureListOfJob(ctx, dbJob1))
var failures = []TaskFailure{}
tx := db.gormDB.Model(&TaskFailure{}).Scan(&failures)
assert.NoError(t, tx.Error)
require.NoError(t, tx.Error)
if assert.Len(t, failures, 2) {
assert.Equal(t, task2_1.ID, failures[0].TaskID)
assert.Equal(t, worker1.ID, failures[0].WorkerID)
@ -634,7 +632,7 @@ func TestFetchTaskFailureList(t *testing.T) {
// Test with non-existing task.
fakeTask := Task{Model: Model{ID: 327}}
failures, err := db.FetchTaskFailureList(ctx, &fakeTask)
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, failures)
task1_1, _ := db.FetchTask(ctx, authoredJob1.Tasks[1].UUID)
@ -642,7 +640,7 @@ func TestFetchTaskFailureList(t *testing.T) {
// Test without failures.
failures, err = db.FetchTaskFailureList(ctx, task1_1)
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, failures)
worker1 := createWorker(ctx, t, db)
@ -655,7 +653,7 @@ func TestFetchTaskFailureList(t *testing.T) {
// Fetch one task's failure list.
failures, err = db.FetchTaskFailureList(ctx, task1_1)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, failures, 2) {
assert.Equal(t, worker1.UUID, failures[0].UUID)
@ -854,7 +852,7 @@ func createWorker(ctx context.Context, t *testing.T, db *DB, updaters ...func(*W
if err != nil {
t.Fatalf("error creating worker: %v", err)
}
assert.NoError(t, err)
require.NoError(t, err)
fetchedWorker, err := db.FetchWorker(ctx, w.UUID)
if err != nil {
@ -874,14 +872,10 @@ func createWorkerFrom(ctx context.Context, t *testing.T, db *DB, worker Worker)
worker.Name += " (copy)"
err := db.SaveWorker(ctx, &worker)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
dbWorker, err := db.FetchWorker(ctx, worker.UUID)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
return dbWorker
}

@ -6,6 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSetLastRendered(t *testing.T) {
@ -15,7 +16,7 @@ func TestSetLastRendered(t *testing.T) {
authoredJob2 := authorTestJob("1295757b-e668-4c49-8b89-f73db8270e42", "just-a-job")
job2 := persistAuthoredJob(t, ctx, db, authoredJob2)
assert.NoError(t, db.SetLastRendered(ctx, job1))
require.NoError(t, db.SetLastRendered(ctx, job1))
{
entries := []LastRendered{}
db.gormDB.Model(&LastRendered{}).Scan(&entries)
@ -24,7 +25,7 @@ func TestSetLastRendered(t *testing.T) {
}
}
assert.NoError(t, db.SetLastRendered(ctx, job2))
require.NoError(t, db.SetLastRendered(ctx, job2))
{
entries := []LastRendered{}
db.gormDB.Model(&LastRendered{}).Scan(&entries)
@ -41,18 +42,16 @@ func TestGetLastRenderedJobUUID(t *testing.T) {
{
// Test without any renders.
lastUUID, err := db.GetLastRenderedJobUUID(ctx)
if assert.NoError(t, err, "absence of renders should not cause an error") {
assert.Empty(t, lastUUID)
}
require.NoError(t, err, "absence of renders should not cause an error")
assert.Empty(t, lastUUID)
}
{
// Test with first render.
assert.NoError(t, db.SetLastRendered(ctx, job1))
require.NoError(t, db.SetLastRendered(ctx, job1))
lastUUID, err := db.GetLastRenderedJobUUID(ctx)
if assert.NoError(t, err) {
assert.Equal(t, job1.UUID, lastUUID)
}
require.NoError(t, err)
assert.Equal(t, job1.UUID, lastUUID)
}
{
@ -60,10 +59,9 @@ func TestGetLastRenderedJobUUID(t *testing.T) {
authoredJob2 := authorTestJob("1295757b-e668-4c49-8b89-f73db8270e42", "just-a-job")
job2 := persistAuthoredJob(t, ctx, db, authoredJob2)
assert.NoError(t, db.SetLastRendered(ctx, job2))
require.NoError(t, db.SetLastRendered(ctx, job2))
lastUUID, err := db.GetLastRenderedJobUUID(ctx)
if assert.NoError(t, err) {
assert.Equal(t, job2.UUID, lastUUID)
}
require.NoError(t, err)
assert.Equal(t, job2.UUID, lastUUID)
}
}

@ -26,7 +26,7 @@ func TestNoTasks(t *testing.T) {
task, err := db.ScheduleTask(ctx, &w)
assert.Nil(t, task)
assert.NoError(t, err)
require.NoError(t, err)
}
func TestOneJobOneTask(t *testing.T) {
@ -40,7 +40,7 @@ func TestOneJobOneTask(t *testing.T) {
job := constructTestJob(ctx, t, db, atj)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
// Check the returned task.
if task == nil {
@ -55,7 +55,7 @@ func TestOneJobOneTask(t *testing.T) {
// Check the task in the database.
now := db.gormDB.NowFunc()
dbTask, err := db.FetchTask(context.Background(), authTask.UUID)
assert.NoError(t, err)
require.NoError(t, err)
if dbTask == nil {
t.Fatal("task cannot be fetched from database")
}
@ -84,7 +84,7 @@ func TestOneJobThreeTasksByPrio(t *testing.T) {
job := constructTestJob(ctx, t, db, atj)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}
@ -115,7 +115,7 @@ func TestOneJobThreeTasksByDependencies(t *testing.T) {
job := constructTestJob(ctx, t, db, atj)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}
@ -155,7 +155,7 @@ func TestTwoJobsThreeTasks(t *testing.T) {
job2 := constructTestJob(ctx, t, db, atj2)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}
@ -183,7 +183,7 @@ func TestSomeButNotAllDependenciesCompleted(t *testing.T) {
w := linuxWorker(t, db)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task != nil {
t.Fatalf("there should not be any task assigned, but received %q", task.Name)
}
@ -210,14 +210,14 @@ func TestAlreadyAssigned(t *testing.T) {
// This should make it get returned by the scheduler, even when there is
// another, higher-prio task to be done.
dbTask3, err := db.FetchTask(ctx, att3.UUID)
assert.NoError(t, err)
require.NoError(t, err)
dbTask3.WorkerID = &w.ID
dbTask3.Status = api.TaskStatusActive
err = db.SaveTask(ctx, dbTask3)
assert.NoError(t, err)
require.NoError(t, err)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}
@ -245,14 +245,14 @@ func TestAssignedToOtherWorker(t *testing.T) {
// Assign the high-prio task to the other worker. Because the task is queued,
// it shouldn't matter which worker it's assigned to.
dbTask2, err := db.FetchTask(ctx, att2.UUID)
assert.NoError(t, err)
require.NoError(t, err)
dbTask2.WorkerID = &w2.ID
dbTask2.Status = api.TaskStatusQueued
err = db.SaveTask(ctx, dbTask2)
assert.NoError(t, err)
require.NoError(t, err)
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}
@ -277,14 +277,14 @@ func TestPreviouslyFailed(t *testing.T) {
// Mimick that this worker already failed the first task.
tasks, err := db.FetchTasksOfJob(ctx, job)
assert.NoError(t, err)
require.NoError(t, err)
numFailed, err := db.AddWorkerToTaskFailedList(ctx, tasks[0], &w)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, 1, numFailed)
// This should assign the 2nd task.
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}
@ -391,11 +391,11 @@ func TestBlocklisted(t *testing.T) {
// Mimick that this worker was already blocked for 'blender' tasks of this job.
err := db.AddWorkerToJobBlocklist(ctx, job, &w, "blender")
assert.NoError(t, err)
require.NoError(t, err)
// This should assign the 2nd task.
task, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
if task == nil {
t.Fatal("task is nil")
}

@ -7,6 +7,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var emptyToD = TimeOfDay{timeOfDayNoValue, timeOfDayNoValue}
@ -60,53 +61,56 @@ func TestOnDate(t *testing.T) {
}
func TestValue(t *testing.T) {
// Test zero -> "00:00"
tod := TimeOfDay{}
if value, err := tod.Value(); assert.NoError(t, err) {
{ // Test zero -> "00:00"
tod := TimeOfDay{}
value, err := tod.Value()
require.NoError(t, err)
assert.Equal(t, "00:00", value)
}
// Test 22:47 -> "22:47"
tod = TimeOfDay{22, 47}
if value, err := tod.Value(); assert.NoError(t, err) {
{ // Test 22:47 -> "22:47"
tod := TimeOfDay{22, 47}
value, err := tod.Value()
require.NoError(t, err)
assert.Equal(t, "22:47", value)
}
// Test empty -> ""
tod = emptyToD
if value, err := tod.Value(); assert.NoError(t, err) {
{ // Test empty -> ""
tod := emptyToD
value, err := tod.Value()
require.NoError(t, err)
assert.Equal(t, "", value)
}
}
func TestScan(t *testing.T) {
// Test zero -> empty
tod := TimeOfDay{}
if assert.NoError(t, tod.Scan("")) {
{ // Test zero -> empty
tod := TimeOfDay{}
require.NoError(t, tod.Scan(""))
assert.Equal(t, emptyToD, tod)
}
// Test 22:47 -> empty
tod = TimeOfDay{22, 47}
if assert.NoError(t, tod.Scan("")) {
{ // Test 22:47 -> empty
tod := TimeOfDay{22, 47}
require.NoError(t, tod.Scan(""))
assert.Equal(t, emptyToD, tod)
}
// Test 22:47 -> 12:34
tod = TimeOfDay{22, 47}
if assert.NoError(t, tod.Scan("12:34")) {
{ // Test 22:47 -> 12:34
tod := TimeOfDay{22, 47}
require.NoError(t, tod.Scan("12:34"))
assert.Equal(t, TimeOfDay{12, 34}, tod)
}
// Test empty -> empty
tod = emptyToD
if assert.NoError(t, tod.Scan("")) {
{ // Test empty -> empty
tod := emptyToD
require.NoError(t, tod.Scan(""))
assert.Equal(t, emptyToD, tod)
}
// Test empty -> 12:34
tod = emptyToD
if assert.NoError(t, tod.Scan("12:34")) {
{ // Test empty -> 12:34
tod := emptyToD
require.NoError(t, tod.Scan("12:34"))
assert.Equal(t, TimeOfDay{12, 34}, tod)
}
}

@ -5,6 +5,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/pkg/api"
)
@ -15,9 +16,7 @@ func TestFetchTimedOutTasks(t *testing.T) {
defer close()
tasks, err := db.FetchTasksOfJob(ctx, job)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
now := db.gormDB.NowFunc()
deadline := now.Add(-5 * time.Minute)
@ -25,23 +24,23 @@ func TestFetchTimedOutTasks(t *testing.T) {
// Mark the task as last touched before the deadline, i.e. old enough for a timeout.
task := tasks[0]
task.LastTouchedAt = deadline.Add(-1 * time.Minute)
assert.NoError(t, db.SaveTask(ctx, task))
require.NoError(t, db.SaveTask(ctx, task))
w := createWorker(ctx, t, db)
assert.NoError(t, db.TaskAssignToWorker(ctx, task, w))
require.NoError(t, db.TaskAssignToWorker(ctx, task, w))
// The task should still not be returned, as it's not in 'active' state.
timedout, err := db.FetchTimedOutTasks(ctx, deadline)
assert.NoError(t, err)
require.NoError(t, err)
assert.Empty(t, timedout)
// Mark as Active:
task.Status = api.TaskStatusActive
assert.NoError(t, db.SaveTask(ctx, task))
require.NoError(t, db.SaveTask(ctx, task))
// Now it should time out:
timedout, err = db.FetchTimedOutTasks(ctx, deadline)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, timedout, 1) {
// Other fields will be different, like the 'UpdatedAt' field -- this just
// tests that the expected task is returned.
@ -92,15 +91,13 @@ func TestFetchTimedOutWorkers(t *testing.T) {
workers := []*Worker{&worker0, &worker1, &worker2, &worker3, &worker4}
for _, worker := range workers {
err := db.CreateWorker(ctx, worker)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
}
timedout, err := db.FetchTimedOutWorkers(ctx, timeoutDeadline)
if assert.NoError(t, err) && assert.Len(t, timedout, 3) {
assert.Equal(t, worker1.UUID, timedout[0].UUID)
assert.Equal(t, worker2.UUID, timedout[1].UUID)
assert.Equal(t, worker3.UUID, timedout[2].UUID)
}
require.NoError(t, err)
require.Len(t, timedout, 3)
assert.Equal(t, worker1.UUID, timedout[0].UUID)
assert.Equal(t, worker2.UUID, timedout[1].UUID)
assert.Equal(t, worker3.UUID, timedout[2].UUID)
}

@ -26,18 +26,16 @@ func TestFetchWorkerSleepSchedule(t *testing.T) {
SupportedTaskTypes: "blender,ffmpeg,file-management",
}
err := db.CreateWorker(ctx, &linuxWorker)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
// Not an existing Worker.
fetched, err := db.FetchWorkerSleepSchedule(ctx, "2cf6153a-3d4e-49f4-a5c0-1c9fc176e155")
assert.NoError(t, err, "non-existent worker should not cause an error")
require.NoError(t, err, "non-existent worker should not cause an error")
assert.Nil(t, fetched)
// No sleep schedule.
fetched, err = db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
assert.NoError(t, err, "non-existent schedule should not cause an error")
require.NoError(t, err, "non-existent schedule should not cause an error")
assert.Nil(t, fetched)
// Create a sleep schedule.
@ -51,12 +49,10 @@ func TestFetchWorkerSleepSchedule(t *testing.T) {
EndTime: TimeOfDay{9, 0},
}
tx := db.gormDB.Create(&created)
if !assert.NoError(t, tx.Error) {
t.FailNow()
}
require.NoError(t, tx.Error)
fetched, err = db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assertEqualSleepSchedule(t, linuxWorker.ID, created, *fetched)
}
@ -74,9 +70,7 @@ func TestFetchSleepScheduleWorker(t *testing.T) {
SupportedTaskTypes: "blender,ffmpeg,file-management",
}
err := db.CreateWorker(ctx, &linuxWorker)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
// Create a sleep schedule.
created := SleepSchedule{
@ -89,16 +83,14 @@ func TestFetchSleepScheduleWorker(t *testing.T) {
EndTime: TimeOfDay{9, 0},
}
tx := db.gormDB.Create(&created)
if !assert.NoError(t, tx.Error) {
t.FailNow()
}
require.NoError(t, tx.Error)
dbSchedule, err := db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Nil(t, dbSchedule.Worker, "worker should be nil when fetching schedule")
err = db.FetchSleepScheduleWorker(ctx, dbSchedule)
assert.NoError(t, err)
require.NoError(t, err)
if assert.NotNil(t, dbSchedule.Worker) {
// Compare a few fields. If these are good, the correct worker has been fetched.
assert.Equal(t, linuxWorker.ID, dbSchedule.Worker.ID)
@ -125,9 +117,7 @@ func TestSetWorkerSleepSchedule(t *testing.T) {
SupportedTaskTypes: "blender,ffmpeg,file-management",
}
err := db.CreateWorker(ctx, &linuxWorker)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
schedule := SleepSchedule{
WorkerID: linuxWorker.ID,
@ -145,13 +135,9 @@ func TestSetWorkerSleepSchedule(t *testing.T) {
// Create the sleep schedule.
err = db.SetWorkerSleepSchedule(ctx, linuxWorker.UUID, &schedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
fetched, err := db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assertEqualSleepSchedule(t, linuxWorker.ID, schedule, *fetched)
// Overwrite the schedule with one that already has a database ID.
@ -161,13 +147,9 @@ func TestSetWorkerSleepSchedule(t *testing.T) {
newSchedule.StartTime = TimeOfDay{2, 0}
newSchedule.EndTime = TimeOfDay{6, 0}
err = db.SetWorkerSleepSchedule(ctx, linuxWorker.UUID, &newSchedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
fetched, err = db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assertEqualSleepSchedule(t, linuxWorker.ID, newSchedule, *fetched)
// Overwrite the schedule with a freshly constructed one.
@ -181,13 +163,9 @@ func TestSetWorkerSleepSchedule(t *testing.T) {
EndTime: TimeOfDay{15, 0},
}
err = db.SetWorkerSleepSchedule(ctx, linuxWorker.UUID, &newerSchedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
fetched, err = db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assertEqualSleepSchedule(t, linuxWorker.ID, newerSchedule, *fetched)
// Clear the sleep schedule.
@ -201,13 +179,9 @@ func TestSetWorkerSleepSchedule(t *testing.T) {
EndTime: emptyToD,
}
err = db.SetWorkerSleepSchedule(ctx, linuxWorker.UUID, &emptySchedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
fetched, err = db.FetchWorkerSleepSchedule(ctx, linuxWorker.UUID)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assertEqualSleepSchedule(t, linuxWorker.ID, emptySchedule, *fetched)
}
@ -236,14 +210,10 @@ func TestSetWorkerSleepScheduleNextCheck(t *testing.T) {
schedule.NextCheck = future
err := db.SetWorkerSleepScheduleNextCheck(ctx, &schedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
fetched, err := db.FetchWorkerSleepSchedule(ctx, schedule.Worker.UUID)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
assertEqualSleepSchedule(t, schedule.Worker.ID, schedule, *fetched)
}
@ -322,12 +292,13 @@ func TestFetchSleepSchedulesToCheck(t *testing.T) {
}
toCheck, err := db.FetchSleepSchedulesToCheck(ctx)
if assert.NoError(t, err) && assert.Len(t, toCheck, 2) {
assertEqualSleepSchedule(t, schedule0.Worker.ID, schedule0, *toCheck[0])
assert.Nil(t, toCheck[0].Worker, "the Worker should NOT be fetched")
assertEqualSleepSchedule(t, schedule2.Worker.ID, schedule1, *toCheck[1])
assert.Nil(t, toCheck[1].Worker, "the Worker should NOT be fetched")
}
require.NoError(t, err)
require.Len(t, toCheck, 2)
assertEqualSleepSchedule(t, schedule0.Worker.ID, schedule0, *toCheck[0])
assert.Nil(t, toCheck[0].Worker, "the Worker should NOT be fetched")
assertEqualSleepSchedule(t, schedule2.Worker.ID, schedule1, *toCheck[1])
assert.Nil(t, toCheck[1].Worker, "the Worker should NOT be fetched")
}
func assertEqualSleepSchedule(t *testing.T, workerID uint, expect, actual SleepSchedule) {

@ -36,10 +36,10 @@ func TestCreateFetchWorker(t *testing.T) {
}
err = db.CreateWorker(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
fetchedWorker, err = db.FetchWorker(ctx, w.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.NotNil(t, fetchedWorker)
// Test contents of fetched job
@ -69,15 +69,12 @@ func TestFetchWorkerTask(t *testing.T) {
}
err := db.CreateWorker(ctx, &w)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
{ // Test without any task assigned.
task, err := db.FetchWorkerTask(ctx, &w)
if assert.NoError(t, err) {
assert.Nil(t, task)
}
require.NoError(t, err)
assert.Nil(t, task)
}
// Create a job with tasks.
@ -88,52 +85,51 @@ func TestFetchWorkerTask(t *testing.T) {
constructTestJob(ctx, t, db, atj)
assignedTask, err := db.ScheduleTask(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
{ // Assigned task should be returned.
foundTask, err := db.FetchWorkerTask(ctx, &w)
if assert.NoError(t, err) && assert.NotNil(t, foundTask) {
assert.Equal(t, assignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
require.NoError(t, err)
require.NotNil(t, foundTask)
assert.Equal(t, assignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
// Set the task to 'completed'.
assignedTask.Status = api.TaskStatusCompleted
assert.NoError(t, db.SaveTaskStatus(ctx, assignedTask))
require.NoError(t, db.SaveTaskStatus(ctx, assignedTask))
{ // Completed-but-last-assigned task should be returned.
foundTask, err := db.FetchWorkerTask(ctx, &w)
if assert.NoError(t, err) && assert.NotNil(t, foundTask) {
assert.Equal(t, assignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
require.NoError(t, err)
require.NotNil(t, foundTask)
assert.Equal(t, assignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
// Assign another task.
newlyAssignedTask, err := db.ScheduleTask(ctx, &w)
if !assert.NoError(t, err) || !assert.NotNil(t, newlyAssignedTask) {
t.FailNow()
}
require.NoError(t, err)
require.NotNil(t, newlyAssignedTask)
{ // Newly assigned task should be returned.
foundTask, err := db.FetchWorkerTask(ctx, &w)
if assert.NoError(t, err) && assert.NotNil(t, foundTask) {
assert.Equal(t, newlyAssignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
require.NoError(t, err)
require.NotNil(t, foundTask)
assert.Equal(t, newlyAssignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
// Set the new task to 'completed'.
newlyAssignedTask.Status = api.TaskStatusCompleted
assert.NoError(t, db.SaveTaskStatus(ctx, newlyAssignedTask))
require.NoError(t, db.SaveTaskStatus(ctx, newlyAssignedTask))
{ // Completed-but-last-assigned task should be returned.
foundTask, err := db.FetchWorkerTask(ctx, &w)
if assert.NoError(t, err) && assert.NotNil(t, foundTask) {
assert.Equal(t, newlyAssignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
require.NoError(t, err)
require.NotNil(t, foundTask)
assert.Equal(t, newlyAssignedTask.UUID, foundTask.UUID)
assert.Equal(t, jobUUID, foundTask.Job.UUID, "the job UUID should be returned as well")
}
}
@ -153,10 +149,10 @@ func TestSaveWorker(t *testing.T) {
}
err := db.CreateWorker(ctx, &w)
assert.NoError(t, err)
require.NoError(t, err)
fetchedWorker, err := db.FetchWorker(ctx, w.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.NotNil(t, fetchedWorker)
// Update all updatable fields of the Worker
@ -170,23 +166,23 @@ func TestSaveWorker(t *testing.T) {
// Saving only the status should just do that.
err = db.SaveWorkerStatus(ctx, &updatedWorker)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, "7 မှ 9", updatedWorker.Name, "Saving status should not touch the name")
// Check saved worker
fetchedWorker, err = db.FetchWorker(ctx, w.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.NotNil(t, fetchedWorker)
assert.Equal(t, updatedWorker.Status, fetchedWorker.Status, "new status should have been saved")
assert.NotEqual(t, updatedWorker.Name, fetchedWorker.Name, "non-status fields should not have been updated")
// Saving the entire worker should save everything.
err = db.SaveWorker(ctx, &updatedWorker)
assert.NoError(t, err)
require.NoError(t, err)
// Check saved worker
fetchedWorker, err = db.FetchWorker(ctx, w.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.NotNil(t, fetchedWorker)
assert.Equal(t, updatedWorker.Status, fetchedWorker.Status, "new status should have been saved")
assert.Equal(t, updatedWorker.Name, fetchedWorker.Name, "non-status fields should also have been updated")
@ -199,10 +195,8 @@ func TestFetchWorkers(t *testing.T) {
// No workers
workers, err := db.FetchWorkers(ctx)
if !assert.NoError(t, err) {
t.Fatal("error fetching empty list of workers, no use in continuing the test")
}
assert.Empty(t, workers)
require.NoError(t, err)
require.Empty(t, workers)
linuxWorker := Worker{
UUID: uuid.New(),
@ -216,12 +210,12 @@ func TestFetchWorkers(t *testing.T) {
// One worker:
err = db.CreateWorker(ctx, &linuxWorker)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, time.Now().UTC().Location(), linuxWorker.CreatedAt.Location(),
"Timestamps should be using UTC timezone")
workers, err = db.FetchWorkers(ctx)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, workers, 1) {
// FIXME: this fails, because the fetched timestamps have nil location instead of UTC.
// assert.Equal(t, time.Now().UTC().Location(), workers[0].CreatedAt.Location(),
@ -245,10 +239,10 @@ func TestFetchWorkers(t *testing.T) {
SupportedTaskTypes: "blender,ffmpeg,file-management",
}
err = db.CreateWorker(ctx, &windowsWorker)
assert.NoError(t, err)
require.NoError(t, err)
workers, err = db.FetchWorkers(ctx)
assert.NoError(t, err)
require.NoError(t, err)
if assert.Len(t, workers, 2) {
assert.Equal(t, linuxWorker.UUID, workers[0].UUID)
assert.Equal(t, windowsWorker.UUID, workers[1].UUID)
@ -275,11 +269,11 @@ func TestDeleteWorker(t *testing.T) {
Status: api.WorkerStatusOffline,
}
assert.NoError(t, db.CreateWorker(ctx, &w1))
assert.NoError(t, db.CreateWorker(ctx, &w2))
require.NoError(t, db.CreateWorker(ctx, &w1))
require.NoError(t, db.CreateWorker(ctx, &w2))
// Delete the 2nd worker, just to have a test with ID != 1.
assert.NoError(t, db.DeleteWorker(ctx, w2.UUID))
require.NoError(t, db.DeleteWorker(ctx, w2.UUID))
// The deleted worker should now no longer be found.
{
@ -291,7 +285,7 @@ func TestDeleteWorker(t *testing.T) {
// The other worker should still exist.
{
fetchedWorker, err := db.FetchWorker(ctx, w1.UUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, w1.UUID, fetchedWorker.UUID)
}
@ -301,18 +295,18 @@ func TestDeleteWorker(t *testing.T) {
taskUUID := authJob.Tasks[0].UUID
{
task, err := db.FetchTask(ctx, taskUUID)
assert.NoError(t, err)
require.NoError(t, err)
task.Worker = &w1
assert.NoError(t, db.SaveTask(ctx, task))
require.NoError(t, db.SaveTask(ctx, task))
}
// Delete the worker.
assert.NoError(t, db.DeleteWorker(ctx, w1.UUID))
require.NoError(t, db.DeleteWorker(ctx, w1.UUID))
// Check the task after deletion of the Worker.
{
fetchedTask, err := db.FetchTask(ctx, taskUUID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, taskUUID, fetchedTask.UUID)
assert.Equal(t, w1.UUID, fetchedTask.Worker.UUID)
assert.NotZero(t, fetchedTask.Worker.DeletedAt.Time)

@ -10,6 +10,7 @@ import (
"github.com/benbjohnson/clock"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
"projects.blender.org/studio/flamenco/internal/manager/sleep_scheduler/mocks"
@ -24,9 +25,8 @@ func TestFetchSchedule(t *testing.T) {
mocks.persist.EXPECT().FetchWorkerSleepSchedule(ctx, workerUUID).Return(&dbSched, nil)
sched, err := ss.FetchSchedule(ctx, workerUUID)
if assert.NoError(t, err) {
assert.Equal(t, &dbSched, sched)
}
require.NoError(t, err)
assert.Equal(t, &dbSched, sched)
}
func TestSetSchedule(t *testing.T) {
@ -59,7 +59,7 @@ func TestSetSchedule(t *testing.T) {
mocks.broadcaster.EXPECT().BroadcastWorkerUpdate(gomock.Any())
err := ss.SetSchedule(ctx, workerUUID, &sched)
assert.NoError(t, err)
require.NoError(t, err)
}
func TestSetScheduleSwappedStartEnd(t *testing.T) {
@ -92,7 +92,7 @@ func TestSetScheduleSwappedStartEnd(t *testing.T) {
mocks.persist.EXPECT().SetWorkerSleepSchedule(ctx, workerUUID, &expectSavedSchedule)
err := ss.SetSchedule(ctx, workerUUID, &sched)
assert.NoError(t, err)
require.NoError(t, err)
}
// Test that a sleep check that happens at shutdown of the Manager doesn't cause any panics.
@ -157,9 +157,7 @@ func TestApplySleepSchedule(t *testing.T) {
// Actually apply the sleep schedule.
err := ss.ApplySleepSchedule(ctx, &testSchedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
// Check the SocketIO broadcast.
if sioUpdate.Id != "" {
@ -220,9 +218,7 @@ func TestApplySleepScheduleNoStatusChange(t *testing.T) {
// Apply the sleep schedule. This should not trigger any persistence or broadcasts.
err := ss.ApplySleepSchedule(ctx, &testSchedule)
if !assert.NoError(t, err) {
t.FailNow()
}
require.NoError(t, err)
}
// Move the clock to the middle of the sleep schedule, so the schedule always

@ -12,11 +12,12 @@ import (
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func setUpTest(t *testing.T) string {
temppath, err := ioutil.TempDir("", "testlogs")
assert.NoError(t, err)
require.NoError(t, err)
return temppath
}
@ -55,7 +56,7 @@ func TestNoFiles(t *testing.T) {
filepath := filepath.Join(temppath, "nonexisting.txt")
err := rotateLogFile(zerolog.Nop(), filepath)
assert.NoError(t, err)
require.NoError(t, err)
assert.False(t, fileExists(filepath))
}
@ -67,7 +68,7 @@ func TestOneFile(t *testing.T) {
fileTouch(filepath)
err := rotateLogFile(zerolog.Nop(), filepath)
assert.NoError(t, err)
require.NoError(t, err)
assert.False(t, fileExists(filepath))
assert.True(t, fileExists(filepath+".1"))
}
@ -77,16 +78,16 @@ func TestMultipleFilesWithHoles(t *testing.T) {
defer tearDownTest(temppath)
filepath := filepath.Join(temppath, "existing.txt")
assert.NoError(t, ioutil.WriteFile(filepath, []byte("thefile"), 0666))
assert.NoError(t, ioutil.WriteFile(filepath+".1", []byte("file .1"), 0666))
assert.NoError(t, ioutil.WriteFile(filepath+".2", []byte("file .2"), 0666))
assert.NoError(t, ioutil.WriteFile(filepath+".3", []byte("file .3"), 0666))
assert.NoError(t, ioutil.WriteFile(filepath+".5", []byte("file .5"), 0666))
assert.NoError(t, ioutil.WriteFile(filepath+".7", []byte("file .7"), 0666))
require.NoError(t, ioutil.WriteFile(filepath, []byte("thefile"), 0666))
require.NoError(t, ioutil.WriteFile(filepath+".1", []byte("file .1"), 0666))
require.NoError(t, ioutil.WriteFile(filepath+".2", []byte("file .2"), 0666))
require.NoError(t, ioutil.WriteFile(filepath+".3", []byte("file .3"), 0666))
require.NoError(t, ioutil.WriteFile(filepath+".5", []byte("file .5"), 0666))
require.NoError(t, ioutil.WriteFile(filepath+".7", []byte("file .7"), 0666))
err := rotateLogFile(zerolog.Nop(), filepath)
assert.NoError(t, err)
require.NoError(t, err)
assert.False(t, fileExists(filepath))
assert.True(t, fileExists(filepath+".1"))
assert.True(t, fileExists(filepath+".2"))
@ -100,7 +101,7 @@ func TestMultipleFilesWithHoles(t *testing.T) {
read := func(filename string) string {
content, err := ioutil.ReadFile(filename)
assert.NoError(t, err)
require.NoError(t, err)
return string(content)
}

@ -19,6 +19,7 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/task_logs/mocks"
)
@ -36,14 +37,14 @@ func TestLogWriting(t *testing.T) {
mocks.localStorage.EXPECT().ForJob(jobUUID).Times(numWriteCalls).Return(jobDir)
err := s.Write(zerolog.Nop(), jobUUID, taskUUID, "Ovo je priča")
assert.NoError(t, err)
require.NoError(t, err)
err = s.Write(zerolog.Nop(), jobUUID, taskUUID, "Ima dvije linije")
assert.NoError(t, err)
require.NoError(t, err)
filename := filepath.Join(jobDir, "task-20ff9d06-53ec-4019-9e2e-1774f05f170a.txt")
contents, err := ioutil.ReadFile(filename)
assert.NoError(t, err, "the log file should exist")
require.NoError(t, err, "the log file should exist")
assert.Equal(t, "Ovo je priča\nIma dvije linije\n", string(contents))
}
@ -59,7 +60,7 @@ func TestLogRotation(t *testing.T) {
mocks.localStorage.EXPECT().ForJob(jobUUID).Return(jobDir).AnyTimes()
err := s.Write(zerolog.Nop(), jobUUID, taskUUID, "Ovo je priča")
assert.NoError(t, err)
require.NoError(t, err)
s.RotateFile(zerolog.Nop(), jobUUID, taskUUID)
@ -67,7 +68,7 @@ func TestLogRotation(t *testing.T) {
rotatedFilename := filename + ".1"
contents, err := ioutil.ReadFile(rotatedFilename)
assert.NoError(t, err, "the rotated log file should exist")
require.NoError(t, err, "the rotated log file should exist")
assert.Equal(t, "Ovo je priča\n", string(contents))
_, err = os.Stat(filename)
@ -97,16 +98,16 @@ func TestLogTailAndSize(t *testing.T) {
// Test a single line.
err = s.Write(zerolog.Nop(), jobID, taskID, "Just a single line")
assert.NoError(t, err)
require.NoError(t, err)
contents, err = s.Tail(jobID, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, "Just a single line\n", string(contents))
// A short file shouldn't do any line stripping.
err = s.Write(zerolog.Nop(), jobID, taskID, "And another line!")
assert.NoError(t, err)
require.NoError(t, err)
contents, err = s.Tail(jobID, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, "Just a single line\nAnd another line!\n", string(contents))
bigString := ""
@ -114,18 +115,17 @@ func TestLogTailAndSize(t *testing.T) {
bigString += fmt.Sprintf("This is line #%d\n", lineNum)
}
err = s.Write(zerolog.Nop(), jobID, taskID, bigString)
assert.NoError(t, err)
require.NoError(t, err)
// Check the log size, it should be the entire bigString plus what was written before that.
size, err = s.TaskLogSize(jobID, taskID)
if assert.NoError(t, err) {
expect := int64(len("Just a single line\nAnd another line!\n" + bigString))
assert.Equal(t, expect, size)
}
require.NoError(t, err)
expect := int64(len("Just a single line\nAnd another line!\n" + bigString))
assert.Equal(t, expect, size)
// Check the tail, it should only be the few last lines of bigString.
contents, err = s.Tail(jobID, taskID)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t,
"This is line #887\nThis is line #888\nThis is line #889\nThis is line #890\nThis is line #891\n"+
"This is line #892\nThis is line #893\nThis is line #894\nThis is line #895\nThis is line #896\n"+
@ -183,7 +183,7 @@ func TestLogWritingParallel(t *testing.T) {
}
logText := strings.Repeat(string(letter), runLength)
assert.NoError(t, s.Write(logger, jobID, taskID, logText))
require.NoError(t, s.Write(logger, jobID, taskID, logText))
}(int32(i))
}
wg.Wait()
@ -191,7 +191,7 @@ func TestLogWritingParallel(t *testing.T) {
// Test that the final log contains 1000 lines of of 100 characters, without
// any run getting interrupted by another one.
contents, err := os.ReadFile(s.Filepath(jobID, taskID))
assert.NoError(t, err)
require.NoError(t, err)
lines := strings.Split(string(contents), "\n")
assert.Equal(t, numGoroutines+1, len(lines),
"each goroutine should have written a single line, and the file should have a newline at the end")

@ -10,6 +10,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
"projects.blender.org/studio/flamenco/internal/manager/task_state_machine/mocks"
@ -37,7 +38,7 @@ func TestTaskStatusChangeQueuedToActive(t *testing.T) {
mocks.expectBroadcastJobChange(task.Job, api.JobStatusQueued, api.JobStatusActive)
mocks.expectBroadcastTaskChange(task, api.TaskStatusQueued, api.TaskStatusActive)
assert.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusActive))
require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusActive))
}
func TestTaskStatusChangeSaveTaskAfterJobChangeFailure(t *testing.T) {
@ -75,20 +76,20 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) {
mocks.expectWriteTaskLogTimestamped(t, task, "task changed status active -> completed")
mocks.expectBroadcastTaskChange(task, api.TaskStatusActive, api.TaskStatusCompleted)
mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(1, 3, nil) // 1 of 3 complete.
assert.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCompleted))
require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCompleted))
// Second task hickup: T: active > soft-failed --> J: active > active
mocks.expectSaveTaskWithStatus(t, task2, api.TaskStatusSoftFailed)
mocks.expectWriteTaskLogTimestamped(t, task2, "task changed status active -> soft-failed")
mocks.expectBroadcastTaskChange(task2, api.TaskStatusActive, api.TaskStatusSoftFailed)
assert.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusSoftFailed))
require.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusSoftFailed))
// Second task completing: T: soft-failed > completed --> J: active > active
mocks.expectSaveTaskWithStatus(t, task2, api.TaskStatusCompleted)
mocks.expectWriteTaskLogTimestamped(t, task2, "task changed status soft-failed -> completed")
mocks.expectBroadcastTaskChange(task2, api.TaskStatusSoftFailed, api.TaskStatusCompleted)
mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(2, 3, nil) // 2 of 3 complete.
assert.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusCompleted))
require.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusCompleted))
// Third task completing: T: active > completed --> J: active > completed
mocks.expectSaveTaskWithStatus(t, task3, api.TaskStatusCompleted)
@ -98,7 +99,7 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) {
mocks.expectSaveJobWithStatus(t, task.Job, api.JobStatusCompleted)
mocks.expectBroadcastJobChange(task.Job, api.JobStatusActive, api.JobStatusCompleted)
assert.NoError(t, sm.TaskStatusChange(ctx, task3, api.TaskStatusCompleted))
require.NoError(t, sm.TaskStatusChange(ctx, task3, api.TaskStatusCompleted))
}
func TestTaskStatusChangeQueuedToFailed(t *testing.T) {
@ -114,7 +115,7 @@ func TestTaskStatusChangeQueuedToFailed(t *testing.T) {
mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusFailed).Return(1, 100, nil) // 1 out of 100 failed.
mocks.expectBroadcastJobChange(task.Job, api.JobStatusQueued, api.JobStatusActive)
assert.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusFailed))
require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusFailed))
}
func TestTaskStatusChangeActiveToFailedFailJob(t *testing.T) {
@ -144,7 +145,7 @@ func TestTaskStatusChangeActiveToFailedFailJob(t *testing.T) {
"Manager cancelled this task because the job got status \"failed\".",
)
assert.NoError(t, sm.TaskStatusChange(ctx, task1, api.TaskStatusFailed))
require.NoError(t, sm.TaskStatusChange(ctx, task1, api.TaskStatusFailed))
}
func TestTaskStatusChangeRequeueOnCompletedJob(t *testing.T) {
@ -168,7 +169,7 @@ func TestTaskStatusChangeRequeueOnCompletedJob(t *testing.T) {
)
mocks.expectSaveJobWithStatus(t, task.Job, api.JobStatusQueued)
assert.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusQueued))
require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusQueued))
}
func TestTaskStatusChangeCancelSingleTask(t *testing.T) {
@ -186,7 +187,7 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) {
mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job,
api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed).
Return(1, 2, nil)
assert.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCanceled))
require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCanceled))
// T2: queued > cancelled --> J: cancel-requested > canceled
mocks.expectSaveTaskWithStatus(t, task2, api.TaskStatusCanceled)
@ -198,7 +199,7 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) {
mocks.expectSaveJobWithStatus(t, job, api.JobStatusCanceled)
mocks.expectBroadcastJobChange(task.Job, api.JobStatusCancelRequested, api.JobStatusCanceled)
assert.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusCanceled))
require.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusCanceled))
}
func TestTaskStatusChangeCancelSingleTaskWithOtherFailed(t *testing.T) {
@ -222,7 +223,7 @@ func TestTaskStatusChangeCancelSingleTaskWithOtherFailed(t *testing.T) {
// The paused task just stays paused, so don't expectBroadcastTaskChange(task3).
assert.NoError(t, sm.TaskStatusChange(ctx, task1, api.TaskStatusCanceled))
require.NoError(t, sm.TaskStatusChange(ctx, task1, api.TaskStatusCanceled))
}
func TestTaskStatusChangeUnknownStatus(t *testing.T) {
@ -235,7 +236,7 @@ func TestTaskStatusChangeUnknownStatus(t *testing.T) {
mocks.expectWriteTaskLogTimestamped(t, task, "task changed status queued -> borked")
mocks.expectBroadcastTaskChange(task, api.TaskStatusQueued, api.TaskStatus("borked"))
assert.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatus("borked")))
require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatus("borked")))
}
func TestJobRequeueWithSomeCompletedTasks(t *testing.T) {
@ -269,7 +270,7 @@ func TestJobRequeueWithSomeCompletedTasks(t *testing.T) {
mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusActive, api.JobStatusRequeueing)
mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusRequeueing, api.JobStatusQueued)
assert.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusRequeueing, "someone wrote a unittest"))
require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusRequeueing, "someone wrote a unittest"))
}
func TestJobRequeueWithAllCompletedTasks(t *testing.T) {
@ -301,7 +302,7 @@ func TestJobRequeueWithAllCompletedTasks(t *testing.T) {
mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusCompleted, api.JobStatusRequeueing)
mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusRequeueing, api.JobStatusQueued)
assert.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusRequeueing, "someone wrote a unit test"))
require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusRequeueing, "someone wrote a unit test"))
}
func TestJobCancelWithSomeCompletedTasks(t *testing.T) {
@ -332,7 +333,7 @@ func TestJobCancelWithSomeCompletedTasks(t *testing.T) {
mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusActive, api.JobStatusCancelRequested)
mocks.expectBroadcastJobChange(job, api.JobStatusCancelRequested, api.JobStatusCanceled)
assert.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusCancelRequested, "someone wrote a unittest"))
require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusCancelRequested, "someone wrote a unittest"))
}
func TestCheckStuck(t *testing.T) {

@ -6,7 +6,7 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"projects.blender.org/studio/flamenco/internal/manager/persistence"
"projects.blender.org/studio/flamenco/pkg/api"
)
@ -66,5 +66,5 @@ func TestRequeueActiveTasksOfWorker(t *testing.T) {
})
err := sm.RequeueActiveTasksOfWorker(ctx, &worker, "worker had to test")
assert.NoError(t, err)
require.NoError(t, err)
}