Manager: implement fetchWorkers OpenAPI operation

This commit is contained in:
Sybren A. Stüvel 2022-05-30 18:48:52 +02:00
parent eab4fa2ca7
commit 08676f48f4
6 changed files with 168 additions and 0 deletions

View File

@ -54,6 +54,7 @@ type PersistenceService interface {
CreateWorker(ctx context.Context, w *persistence.Worker) error
FetchWorker(ctx context.Context, uuid string) (*persistence.Worker, error)
FetchWorkers(ctx context.Context) ([]*persistence.Worker, error)
SaveWorker(ctx context.Context, w *persistence.Worker) error
SaveWorkerStatus(ctx context.Context, w *persistence.Worker) error

View File

@ -114,6 +114,21 @@ func (mr *MockPersistenceServiceMockRecorder) FetchWorker(arg0, arg1 interface{}
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorker", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorker), arg0, arg1)
}
// FetchWorkers mocks base method.
func (m *MockPersistenceService) FetchWorkers(arg0 context.Context) ([]*persistence.Worker, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FetchWorkers", arg0)
ret0, _ := ret[0].([]*persistence.Worker)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FetchWorkers indicates an expected call of FetchWorkers.
func (mr *MockPersistenceServiceMockRecorder) FetchWorkers(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchWorkers", reflect.TypeOf((*MockPersistenceService)(nil).FetchWorkers), arg0)
}
// QueryJobTaskSummaries mocks base method.
func (m *MockPersistenceService) QueryJobTaskSummaries(arg0 context.Context, arg1 string) ([]*persistence.Task, error) {
m.ctrl.T.Helper()

View File

@ -0,0 +1,39 @@
package api_impl
// SPDX-License-Identifier: GPL-3.0-or-later
import (
"net/http"
"git.blender.org/flamenco/internal/manager/persistence"
"git.blender.org/flamenco/pkg/api"
"github.com/labstack/echo/v4"
)
func (f *Flamenco) FetchWorkers(e echo.Context) error {
dbWorkers, err := f.persist.FetchWorkers(e.Request().Context())
if err != nil {
return sendAPIError(e, http.StatusInternalServerError, "error fetching workers: %v", err)
}
apiWorkers := make([]api.WorkerSummary, len(dbWorkers))
for i := range dbWorkers {
apiWorkers[i] = workerSummary(*dbWorkers[i])
}
return e.JSON(http.StatusOK, api.WorkerList{
Workers: apiWorkers,
})
}
func workerSummary(w persistence.Worker) api.WorkerSummary {
summary := api.WorkerSummary{
Id: w.UUID,
Nickname: w.Name,
Status: w.Status,
}
if w.StatusRequested != "" {
summary.StatusRequested = &w.StatusRequested
}
return summary
}

View File

@ -0,0 +1,55 @@
package api_impl
// SPDX-License-Identifier: GPL-3.0-or-later
import (
"net/http"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"git.blender.org/flamenco/internal/manager/persistence"
"git.blender.org/flamenco/pkg/api"
)
func TestFetchWorkers(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mf := newMockedFlamenco(mockCtrl)
worker1 := testWorker()
worker2 := worker1
worker2.ID = 4
worker2.UUID = "f07b6d53-16ec-40a8-a7b4-a9cc8547f790"
worker2.Status = api.WorkerStatusAwake
worker2.StatusRequested = api.WorkerStatusAsleep
mf.persistence.EXPECT().FetchWorkers(gomock.Any()).
Return([]*persistence.Worker{&worker1, &worker2}, nil)
echo := mf.prepareMockedRequest(nil)
err := mf.flamenco.FetchWorkers(echo)
assert.NoError(t, err)
// Check the response
workers := api.WorkerList{
Workers: []api.WorkerSummary{
{
Id: worker1.UUID,
Nickname: worker1.Name,
Status: worker1.Status,
StatusRequested: nil,
},
{
Id: worker2.UUID,
Nickname: worker2.Name,
Status: worker2.Status,
StatusRequested: &worker2.StatusRequested,
},
},
}
assertResponseJSON(t, echo, http.StatusOK, workers)
resp := getRecordedResponse(echo)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}

View File

@ -50,6 +50,15 @@ func (db *DB) FetchWorker(ctx context.Context, uuid string) (*Worker, error) {
return &w, nil
}
func (db *DB) FetchWorkers(ctx context.Context) ([]*Worker, error) {
workers := make([]*Worker, 0)
tx := db.gormDB.WithContext(ctx).Model(&Worker{}).Scan(&workers)
if tx.Error != nil {
return nil, tx.Error
}
return workers, nil
}
func (db *DB) SaveWorkerStatus(ctx context.Context, w *Worker) error {
err := db.gormDB.WithContext(ctx).
Model(w).

View File

@ -103,3 +103,52 @@ func TestSaveWorker(t *testing.T) {
assert.Equal(t, updatedWorker.Name, fetchedWorker.Name, "non-status fields should also have been updated")
assert.Equal(t, updatedWorker.Software, fetchedWorker.Software, "non-status fields should also have been updated")
}
func TestFetchWorkers(t *testing.T) {
ctx, cancel, db := persistenceTestFixtures(t, 1*time.Second)
defer cancel()
// 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)
linuxWorker := Worker{
UUID: uuid.New(),
Name: "дрон",
Address: "fe80::5054:ff:fede:2ad7",
LastActivity: "",
Platform: "linux",
Software: "3.0",
Status: api.WorkerStatusAwake,
SupportedTaskTypes: "blender,ffmpeg,file-management",
}
// One worker:
err = db.CreateWorker(ctx, &linuxWorker)
assert.NoError(t, err)
workers, err = db.FetchWorkers(ctx)
assert.NoError(t, err)
assert.Equal(t, []*Worker{&linuxWorker}, workers)
// Two workers:
windowsWorker := Worker{
UUID: uuid.New(),
Name: "очиститель окон",
Address: "fe80::c000:d000:::3",
LastActivity: "nothing",
Platform: "windows",
Software: "3.0",
Status: api.WorkerStatusOffline,
SupportedTaskTypes: "blender,ffmpeg,file-management",
}
err = db.CreateWorker(ctx, &windowsWorker)
assert.NoError(t, err)
workers, err = db.FetchWorkers(ctx)
assert.NoError(t, err)
assert.Equal(t, []*Worker{&linuxWorker, &windowsWorker}, workers)
}