Manager: implement fetchWorker API endpoint

This commit is contained in:
Sybren A. Stüvel 2022-05-31 11:21:55 +02:00
parent f2f6726ec0
commit 8e247b9dfc
2 changed files with 105 additions and 0 deletions

View File

@ -3,9 +3,11 @@ package api_impl
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
import ( import (
"errors"
"net/http" "net/http"
"git.blender.org/flamenco/internal/manager/persistence" "git.blender.org/flamenco/internal/manager/persistence"
"git.blender.org/flamenco/internal/uuid"
"git.blender.org/flamenco/pkg/api" "git.blender.org/flamenco/pkg/api"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -26,6 +28,29 @@ func (f *Flamenco) FetchWorkers(e echo.Context) error {
}) })
} }
func (f *Flamenco) FetchWorker(e echo.Context, workerUUID string) error {
logger := requestLogger(e)
logger = logger.With().Str("worker", workerUUID).Logger()
if !uuid.IsValid(workerUUID) {
return sendAPIError(e, http.StatusBadRequest, "not a valid UUID")
}
dbWorker, err := f.persist.FetchWorker(e.Request().Context(), workerUUID)
if errors.Is(err, persistence.ErrWorkerNotFound) {
logger.Debug().Msg("non-existent worker requested")
return sendAPIError(e, http.StatusNotFound, "worker %q not found", workerUUID)
}
if err != nil {
logger.Error().Err(err).Msg("error fetching worker")
return sendAPIError(e, http.StatusInternalServerError, "error fetching worker: %v", err)
}
logger.Debug().Msg("fetched worker")
apiWorker := workerDBtoAPI(dbWorker)
return e.JSON(http.StatusOK, apiWorker)
}
func workerSummary(w persistence.Worker) api.WorkerSummary { func workerSummary(w persistence.Worker) api.WorkerSummary {
summary := api.WorkerSummary{ summary := api.WorkerSummary{
Id: w.UUID, Id: w.UUID,
@ -37,3 +62,21 @@ func workerSummary(w persistence.Worker) api.WorkerSummary {
} }
return summary return summary
} }
func workerDBtoAPI(dbWorker *persistence.Worker) api.Worker {
apiWorker := api.Worker{
Id: dbWorker.UUID,
IpAddress: dbWorker.Address,
Nickname: dbWorker.Name,
Platform: dbWorker.Platform,
Status: dbWorker.Status,
SupportedTaskTypes: dbWorker.TaskTypes(),
Version: dbWorker.Software,
}
if dbWorker.StatusRequested != "" {
apiWorker.StatusRequested = &dbWorker.StatusRequested
}
return apiWorker
}

View File

@ -3,6 +3,8 @@ package api_impl
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
import ( import (
"errors"
"fmt"
"net/http" "net/http"
"testing" "testing"
@ -53,3 +55,63 @@ func TestFetchWorkers(t *testing.T) {
resp := getRecordedResponse(echo) resp := getRecordedResponse(echo)
assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, http.StatusOK, resp.StatusCode)
} }
func TestFetchWorker(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mf := newMockedFlamenco(mockCtrl)
worker := testWorker()
workerUUID := worker.UUID
// Test without worker in the database.
mf.persistence.EXPECT().FetchWorker(gomock.Any(), workerUUID).
Return(nil, fmt.Errorf("wrapped: %w", persistence.ErrWorkerNotFound))
echo := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchWorker(echo, workerUUID)
assert.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusNotFound, fmt.Sprintf("worker %q not found", workerUUID))
// Test database error fetching worker.
mf.persistence.EXPECT().FetchWorker(gomock.Any(), workerUUID).
Return(nil, errors.New("some unknown error"))
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchWorker(echo, workerUUID)
assert.NoError(t, err)
assertResponseAPIError(t, echo, http.StatusInternalServerError, "error fetching worker: some unknown error")
// Test with worker that doesn't have a status change requested.
mf.persistence.EXPECT().FetchWorker(gomock.Any(), workerUUID).Return(&worker, nil)
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchWorker(echo, workerUUID)
assert.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.Worker{
Id: workerUUID,
Nickname: "дрон",
IpAddress: "fe80::5054:ff:fede:2ad7",
Platform: "linux",
Version: "3.0",
Status: api.WorkerStatusAwake,
SupportedTaskTypes: []string{"blender", "ffmpeg", "file-management", "misc"},
})
// Test with worker that does have a status change requested.
requestedStatus := api.WorkerStatusAsleep
worker.StatusRequested = requestedStatus
mf.persistence.EXPECT().FetchWorker(gomock.Any(), workerUUID).Return(&worker, nil)
echo = mf.prepareMockedRequest(nil)
err = mf.flamenco.FetchWorker(echo, worker.UUID)
assert.NoError(t, err)
assertResponseJSON(t, echo, http.StatusOK, api.Worker{
Id: workerUUID,
Nickname: "дрон",
IpAddress: "fe80::5054:ff:fede:2ad7",
Platform: "linux",
Version: "3.0",
Status: api.WorkerStatusAwake,
StatusRequested: &requestedStatus,
SupportedTaskTypes: []string{"blender", "ffmpeg", "file-management", "misc"},
})
}