Implement routes to list, get and delete execution environments

* #9 Implement routes to list, get and delete execution environments.
A refactoring was required to introduce the ExecutionEnvironment interface.

* Fix MR comments, linting issues and bug that lead to e2e test failure

* Add e2e tests

* Add unit tests
This commit is contained in:
Maximilian Paß
2021-10-21 10:33:52 +02:00
committed by GitHub
parent 71cf21abce
commit 34d4bb7ea0
31 changed files with 2239 additions and 1065 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"github.com/gorilla/mux"
"github.com/openHPI/poseidon/internal/environment"
"github.com/openHPI/poseidon/internal/nomad"
"github.com/openHPI/poseidon/internal/runner"
"github.com/openHPI/poseidon/pkg/dto"
"github.com/openHPI/poseidon/tests"
@ -33,10 +34,178 @@ func (s *EnvironmentControllerTestSuite) SetupTest() {
s.router = NewRouter(nil, s.manager)
}
func (s *EnvironmentControllerTestSuite) TestList() {
call := s.manager.On("List", mock.AnythingOfType("bool"))
call.Run(func(args mock.Arguments) {
call.ReturnArguments = mock.Arguments{[]runner.ExecutionEnvironment{}, nil}
})
path, err := s.router.Get(listRouteName).URL()
s.Require().NoError(err)
request, err := http.NewRequest(http.MethodGet, path.String(), nil)
s.Require().NoError(err)
s.Run("with no Environments", func() {
recorder := httptest.NewRecorder()
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusOK, recorder.Code)
var environmentsResponse ExecutionEnvironmentsResponse
err = json.NewDecoder(recorder.Result().Body).Decode(&environmentsResponse)
s.Require().NoError(err)
_ = recorder.Result().Body.Close()
s.Empty(environmentsResponse.ExecutionEnvironments)
})
s.manager.Calls = []mock.Call{}
s.Run("with fetch", func() {
recorder := httptest.NewRecorder()
query := path.Query()
query.Set("fetch", "true")
path.RawQuery = query.Encode()
request, err := http.NewRequest(http.MethodGet, path.String(), nil)
s.Require().NoError(err)
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusOK, recorder.Code)
s.manager.AssertCalled(s.T(), "List", true)
})
s.manager.Calls = []mock.Call{}
s.Run("with bad fetch", func() {
recorder := httptest.NewRecorder()
query := path.Query()
query.Set("fetch", "YouDecide")
path.RawQuery = query.Encode()
request, err := http.NewRequest(http.MethodGet, path.String(), nil)
s.Require().NoError(err)
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusBadRequest, recorder.Code)
s.manager.AssertNotCalled(s.T(), "List")
})
s.Run("returns multiple environments", func() {
call.Run(func(args mock.Arguments) {
firstEnvironment, err := environment.NewNomadEnvironment(
"job \"" + nomad.TemplateJobID(tests.DefaultEnvironmentIDAsInteger) + "\" {}")
s.Require().NoError(err)
secondEnvironment, err := environment.NewNomadEnvironment(
"job \"" + nomad.TemplateJobID(tests.AnotherEnvironmentIDAsInteger) + "\" {}")
s.Require().NoError(err)
call.ReturnArguments = mock.Arguments{[]runner.ExecutionEnvironment{firstEnvironment, secondEnvironment}, nil}
})
recorder := httptest.NewRecorder()
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusOK, recorder.Code)
paramMap := make(map[string]interface{})
err := json.NewDecoder(recorder.Result().Body).Decode(&paramMap)
s.Require().NoError(err)
environmentsInterface, ok := paramMap["executionEnvironments"]
s.Require().True(ok)
environments, ok := environmentsInterface.([]interface{})
s.Require().True(ok)
s.Equal(2, len(environments))
})
}
func (s *EnvironmentControllerTestSuite) TestGet() {
call := s.manager.On("Get", mock.AnythingOfType("dto.EnvironmentID"), mock.AnythingOfType("bool"))
path, err := s.router.Get(getRouteName).URL(executionEnvironmentIDKey, tests.DefaultEnvironmentIDAsString)
s.Require().NoError(err)
request, err := http.NewRequest(http.MethodGet, path.String(), nil)
s.Require().NoError(err)
s.Run("with unknown environment", func() {
call.Run(func(args mock.Arguments) {
call.ReturnArguments = mock.Arguments{nil, runner.ErrUnknownExecutionEnvironment}
})
recorder := httptest.NewRecorder()
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusNotFound, recorder.Code)
s.manager.AssertCalled(s.T(), "Get", dto.EnvironmentID(0), false)
})
s.manager.Calls = []mock.Call{}
s.Run("not found with fetch", func() {
recorder := httptest.NewRecorder()
query := path.Query()
query.Set("fetch", "true")
path.RawQuery = query.Encode()
request, err := http.NewRequest(http.MethodGet, path.String(), nil)
s.Require().NoError(err)
call.Run(func(args mock.Arguments) {
call.ReturnArguments = mock.Arguments{nil, runner.ErrUnknownExecutionEnvironment}
})
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusNotFound, recorder.Code)
s.manager.AssertCalled(s.T(), "Get", dto.EnvironmentID(0), true)
})
s.manager.Calls = []mock.Call{}
s.Run("returns environment", func() {
call.Run(func(args mock.Arguments) {
testEnvironment, err := environment.NewNomadEnvironment(
"job \"" + nomad.TemplateJobID(tests.DefaultEnvironmentIDAsInteger) + "\" {}")
s.Require().NoError(err)
call.ReturnArguments = mock.Arguments{testEnvironment, nil}
})
recorder := httptest.NewRecorder()
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusOK, recorder.Code)
var environmentParams map[string]interface{}
err := json.NewDecoder(recorder.Result().Body).Decode(&environmentParams)
s.Require().NoError(err)
idInterface, ok := environmentParams["id"]
s.Require().True(ok)
idFloat, ok := idInterface.(float64)
s.Require().True(ok)
s.Equal(tests.DefaultEnvironmentIDAsInteger, int(idFloat))
})
}
func (s *EnvironmentControllerTestSuite) TestDelete() {
call := s.manager.On("Delete", mock.AnythingOfType("dto.EnvironmentID"))
path, err := s.router.Get(deleteRouteName).URL(executionEnvironmentIDKey, tests.DefaultEnvironmentIDAsString)
s.Require().NoError(err)
request, err := http.NewRequest(http.MethodDelete, path.String(), nil)
s.Require().NoError(err)
s.Run("environment not found", func() {
call.Run(func(args mock.Arguments) {
call.ReturnArguments = mock.Arguments{false, nil}
})
recorder := httptest.NewRecorder()
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusNotFound, recorder.Code)
})
s.Run("environment deleted", func() {
call.Run(func(args mock.Arguments) {
call.ReturnArguments = mock.Arguments{true, nil}
})
recorder := httptest.NewRecorder()
s.router.ServeHTTP(recorder, request)
s.Equal(http.StatusNoContent, recorder.Code)
})
s.manager.Calls = []mock.Call{}
s.Run("with bad environment id", func() {
_, err := s.router.Get(deleteRouteName).URL(executionEnvironmentIDKey, "MagicNonNumberID")
s.Error(err)
})
}
type CreateOrUpdateEnvironmentTestSuite struct {
EnvironmentControllerTestSuite
path string
id runner.EnvironmentID
id dto.EnvironmentID
body []byte
}