From 18891dda91c88c8af525adbdfcbedf2c30b799f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 3 May 2022 13:04:28 +0200 Subject: [PATCH] Manager: implement `FetchTask` OAPI endpoint --- internal/manager/api_impl/jobs.go | 39 ++++++++++ internal/manager/api_impl/jobs_query.go | 25 ++++++ internal/manager/api_impl/jobs_query_test.go | 81 ++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 internal/manager/api_impl/jobs_query_test.go diff --git a/internal/manager/api_impl/jobs.go b/internal/manager/api_impl/jobs.go index 9f9a427f..2950d5b6 100644 --- a/internal/manager/api_impl/jobs.go +++ b/internal/manager/api_impl/jobs.go @@ -246,3 +246,42 @@ func jobDBtoAPI(dbJob *persistence.Job) api.Job { return apiJob } + +func taskDBtoAPI(dbTask *persistence.Task) api.Task { + apiTask := api.Task{ + Id: dbTask.UUID, + Name: dbTask.Name, + Priority: dbTask.Priority, + TaskType: dbTask.Type, + Created: dbTask.CreatedAt, + Updated: dbTask.UpdatedAt, + Status: dbTask.Status, + Activity: dbTask.Activity, + Commands: make([]api.Command, len(dbTask.Commands)), + } + + if dbTask.Job != nil { + apiTask.JobId = dbTask.Job.UUID + } + + if dbTask.Worker != nil { + apiTask.Worker = &api.TaskWorker{ + Id: dbTask.Worker.UUID, + Name: dbTask.Worker.Name, + Address: dbTask.Worker.Address, + } + } + + for i := range dbTask.Commands { + apiTask.Commands[i] = commandDBtoAPI(dbTask.Commands[i]) + } + + return apiTask +} + +func commandDBtoAPI(dbCommand persistence.Command) api.Command { + return api.Command{ + Name: dbCommand.Name, + Parameters: dbCommand.Parameters, + } +} diff --git a/internal/manager/api_impl/jobs_query.go b/internal/manager/api_impl/jobs_query.go index b2b03097..c3e69509 100644 --- a/internal/manager/api_impl/jobs_query.go +++ b/internal/manager/api_impl/jobs_query.go @@ -87,6 +87,31 @@ func (f *Flamenco) FetchJobTasks(e echo.Context, jobID string) error { return e.JSON(http.StatusOK, result) } +func (f *Flamenco) FetchTask(e echo.Context, taskID string) error { + logger := requestLogger(e).With(). + Str("task", taskID). + Logger() + ctx := e.Request().Context() + + if _, err := uuid.Parse(taskID); err != nil { + logger.Debug().Msg("invalid job ID received") + return sendAPIError(e, http.StatusBadRequest, "job ID not valid") + } + + task, err := f.persist.FetchTask(ctx, taskID) + if err == persistence.ErrTaskNotFound { + logger.Debug().Msg("non-existent task requested") + return sendAPIError(e, http.StatusNotFound, "no such task") + } + if err != nil { + logger.Warn().Err(err).Msg("error fetching task") + return sendAPIError(e, http.StatusInternalServerError, "error fetching task") + } + + apiTask := taskDBtoAPI(task) + return e.JSON(http.StatusOK, apiTask) +} + func taskDBtoSummary(task *persistence.Task) api.TaskSummary { return api.TaskSummary{ Id: task.UUID, diff --git a/internal/manager/api_impl/jobs_query_test.go b/internal/manager/api_impl/jobs_query_test.go new file mode 100644 index 00000000..56c7a9c5 --- /dev/null +++ b/internal/manager/api_impl/jobs_query_test.go @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package api_impl + +import ( + "net/http" + "testing" + "time" + + "git.blender.org/flamenco/internal/manager/persistence" + "git.blender.org/flamenco/pkg/api" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "gorm.io/gorm" +) + +func TestFetchTask(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mf := newMockedFlamenco(mockCtrl) + + taskUUID := "19b62e32-564f-43a3-84fb-06e80ad36f16" + workerUUID := "b5725bb3-d540-4070-a2b6-7b4b26925f94" + jobUUID := "8b179118-0189-478a-b463-73798409898c" + + dbTask := persistence.Task{ + Model: gorm.Model{ + ID: 327, + CreatedAt: time.Now().Add(-30 * time.Second), + UpdatedAt: time.Now(), + }, + UUID: taskUUID, + Name: "симпатичная задача", + Type: "misc", + JobID: 0, + Job: &persistence.Job{UUID: jobUUID}, + Priority: 47, + Status: api.TaskStatusQueued, + WorkerID: new(uint), + Worker: &persistence.Worker{UUID: workerUUID, Name: "Radnik", Address: "Slapić"}, + Dependencies: []*persistence.Task{}, + Activity: "used in unit test", + + Commands: []persistence.Command{ + {Name: "move-directory", + Parameters: map[string]interface{}{ + "dest": "/render/_flamenco/tests/renders/2022-04-29 Weekly/2022-04-29_140531", + "src": "/render/_flamenco/tests/renders/2022-04-29 Weekly/2022-04-29_140531__intermediate-2022-04-29_140531", + }}, + }, + } + + expectAPITask := api.Task{ + Activity: "used in unit test", + Created: dbTask.CreatedAt, + Id: taskUUID, + JobId: jobUUID, + Name: "симпатичная задача", + Priority: 47, + Status: api.TaskStatusQueued, + TaskType: "misc", + Updated: dbTask.UpdatedAt, + Worker: &api.TaskWorker{Id: workerUUID, Name: "Radnik", Address: "Slapić"}, + + Commands: []api.Command{ + {Name: "move-directory", + Parameters: map[string]interface{}{ + "dest": "/render/_flamenco/tests/renders/2022-04-29 Weekly/2022-04-29_140531", + "src": "/render/_flamenco/tests/renders/2022-04-29 Weekly/2022-04-29_140531__intermediate-2022-04-29_140531", + }}, + }, + } + + mf.persistence.EXPECT().FetchTask(gomock.Any(), taskUUID).Return(&dbTask, nil) + + echoCtx := mf.prepareMockedRequest(nil) + err := mf.flamenco.FetchTask(echoCtx, taskUUID) + assert.NoError(t, err) + + assertResponseJSON(t, echoCtx, http.StatusOK, expectAPITask) +}