Persist runner timeout in metadata
To be able to restore the runner timeouts even after a Poseidon restart, the timeout is stored in the Nomad metadata. The timeout will restart, but at least the runner will be returned at all.
This commit is contained in:
@ -9,7 +9,6 @@ import (
|
|||||||
"gitlab.hpi.de/codeocean/codemoon/poseidon/runner"
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/runner"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -48,7 +47,7 @@ func (r *RunnerController) provide(writer http.ResponseWriter, request *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
environmentId := runner.EnvironmentID(runnerRequest.ExecutionEnvironmentId)
|
environmentId := runner.EnvironmentID(runnerRequest.ExecutionEnvironmentId)
|
||||||
nextRunner, err := r.manager.Claim(environmentId)
|
nextRunner, err := r.manager.Claim(environmentId, runnerRequest.InactivityTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
switch err {
|
||||||
case runner.ErrUnknownExecutionEnvironment:
|
case runner.ErrUnknownExecutionEnvironment:
|
||||||
@ -61,9 +60,6 @@ func (r *RunnerController) provide(writer http.ResponseWriter, request *http.Req
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
timeout := time.Duration(runnerRequest.InactivityTimeout) * time.Second
|
|
||||||
nextRunner.SetupTimeout(timeout, nextRunner, r.manager)
|
|
||||||
|
|
||||||
sendJson(writer, &dto.RunnerResponse{Id: nextRunner.Id()}, http.StatusOK)
|
sendJson(writer, &dto.RunnerResponse{Id: nextRunner.Id()}, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ func (s *ProvideRunnerTestSuite) SetupTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ProvideRunnerTestSuite) TestValidRequestReturnsRunner() {
|
func (s *ProvideRunnerTestSuite) TestValidRequestReturnsRunner() {
|
||||||
s.runnerManager.On("Claim", mock.AnythingOfType("runner.EnvironmentID")).Return(s.runner, nil)
|
s.runnerManager.On("Claim", mock.AnythingOfType("runner.EnvironmentID"), mock.AnythingOfType("int")).Return(s.runner, nil)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
s.router.ServeHTTP(recorder, s.defaultRequest)
|
s.router.ServeHTTP(recorder, s.defaultRequest)
|
||||||
@ -149,7 +149,7 @@ func (s *ProvideRunnerTestSuite) TestInvalidRequestReturnsBadRequest() {
|
|||||||
|
|
||||||
func (s *ProvideRunnerTestSuite) TestWhenExecutionEnvironmentDoesNotExistReturnsNotFound() {
|
func (s *ProvideRunnerTestSuite) TestWhenExecutionEnvironmentDoesNotExistReturnsNotFound() {
|
||||||
s.runnerManager.
|
s.runnerManager.
|
||||||
On("Claim", mock.AnythingOfType("runner.EnvironmentID")).
|
On("Claim", mock.AnythingOfType("runner.EnvironmentID"), mock.AnythingOfType("int")).
|
||||||
Return(nil, runner.ErrUnknownExecutionEnvironment)
|
Return(nil, runner.ErrUnknownExecutionEnvironment)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
@ -158,7 +158,8 @@ func (s *ProvideRunnerTestSuite) TestWhenExecutionEnvironmentDoesNotExistReturns
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ProvideRunnerTestSuite) TestWhenNoRunnerAvailableReturnsNomadOverload() {
|
func (s *ProvideRunnerTestSuite) TestWhenNoRunnerAvailableReturnsNomadOverload() {
|
||||||
s.runnerManager.On("Claim", mock.AnythingOfType("runner.EnvironmentID")).Return(nil, runner.ErrNoRunnersAvailable)
|
s.runnerManager.On("Claim", mock.AnythingOfType("runner.EnvironmentID"), mock.AnythingOfType("int")).
|
||||||
|
Return(nil, runner.ErrNoRunnersAvailable)
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
s.router.ServeHTTP(recorder, s.defaultRequest)
|
s.router.ServeHTTP(recorder, s.defaultRequest)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Code generated by mockery v2.8.0. DO NOT EDIT.
|
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||||
|
|
||||||
package nomad
|
package nomad
|
||||||
|
|
||||||
@ -79,29 +79,8 @@ func (_m *ExecutorAPIMock) EvaluationStream(evalID string, ctx context.Context)
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute provides a mock function with given fields: allocationID, ctx, command, tty, stdin, stdout, stderr
|
// Execute provides a mock function with given fields: jobID, ctx, command, tty, stdin, stdout, stderr
|
||||||
func (_m *ExecutorAPIMock) Execute(allocationID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) {
|
func (_m *ExecutorAPIMock) Execute(jobID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) {
|
||||||
ret := _m.Called(allocationID, ctx, command, tty, stdin, stdout, stderr)
|
|
||||||
|
|
||||||
var r0 int
|
|
||||||
if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) int); ok {
|
|
||||||
r0 = rf(allocationID, ctx, command, tty, stdin, stdout, stderr)
|
|
||||||
} else {
|
|
||||||
r0 = ret.Get(0).(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
var r1 error
|
|
||||||
if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) error); ok {
|
|
||||||
r1 = rf(allocationID, ctx, command, tty, stdin, stdout, stderr)
|
|
||||||
} else {
|
|
||||||
r1 = ret.Error(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecuteCommand provides a mock function with given fields: jobID, ctx, command, tty, stdin, stdout, stderr
|
|
||||||
func (_m *ExecutorAPIMock) ExecuteCommand(jobID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) {
|
|
||||||
ret := _m.Called(jobID, ctx, command, tty, stdin, stdout, stderr)
|
ret := _m.Called(jobID, ctx, command, tty, stdin, stdout, stderr)
|
||||||
|
|
||||||
var r0 int
|
var r0 int
|
||||||
@ -121,6 +100,27 @@ func (_m *ExecutorAPIMock) ExecuteCommand(jobID string, ctx context.Context, com
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecuteCommand provides a mock function with given fields: allocationID, ctx, command, tty, stdin, stdout, stderr
|
||||||
|
func (_m *ExecutorAPIMock) ExecuteCommand(allocationID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) {
|
||||||
|
ret := _m.Called(allocationID, ctx, command, tty, stdin, stdout, stderr)
|
||||||
|
|
||||||
|
var r0 int
|
||||||
|
if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) int); ok {
|
||||||
|
r0 = rf(allocationID, ctx, command, tty, stdin, stdout, stderr)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Get(0).(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) error); ok {
|
||||||
|
r1 = rf(allocationID, ctx, command, tty, stdin, stdout, stderr)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
// JobScale provides a mock function with given fields: jobId
|
// JobScale provides a mock function with given fields: jobId
|
||||||
func (_m *ExecutorAPIMock) JobScale(jobId string) (uint, error) {
|
func (_m *ExecutorAPIMock) JobScale(jobId string) (uint, error) {
|
||||||
ret := _m.Called(jobId)
|
ret := _m.Called(jobId)
|
||||||
@ -142,6 +142,29 @@ func (_m *ExecutorAPIMock) JobScale(jobId string) (uint, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadEnvironmentJobs provides a mock function with given fields:
|
||||||
|
func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 []*api.Job
|
||||||
|
if rf, ok := ret.Get(0).(func() []*api.Job); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]*api.Job)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func() error); ok {
|
||||||
|
r1 = rf()
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
// LoadJobList provides a mock function with given fields:
|
// LoadJobList provides a mock function with given fields:
|
||||||
func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) {
|
func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
@ -165,6 +188,29 @@ func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadRunnerIDs provides a mock function with given fields: environmentID
|
||||||
|
func (_m *ExecutorAPIMock) LoadRunnerIDs(environmentID string) ([]string, error) {
|
||||||
|
ret := _m.Called(environmentID)
|
||||||
|
|
||||||
|
var r0 []string
|
||||||
|
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
||||||
|
r0 = rf(environmentID)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||||
|
r1 = rf(environmentID)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
// LoadRunnerJobs provides a mock function with given fields: environmentID
|
// LoadRunnerJobs provides a mock function with given fields: environmentID
|
||||||
func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID string) ([]*api.Job, error) {
|
func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID string) ([]*api.Job, error) {
|
||||||
ret := _m.Called(environmentID)
|
ret := _m.Called(environmentID)
|
||||||
@ -188,82 +234,13 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID string) ([]*api.Job, err
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadRunners provides a mock function with given fields: jobID
|
// MarkRunnerAsUsed provides a mock function with given fields: runnerID, duration
|
||||||
func (_m *ExecutorAPIMock) LoadRunnerIDs(jobID string) ([]string, error) {
|
func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string, duration int) error {
|
||||||
ret := _m.Called(jobID)
|
ret := _m.Called(runnerID, duration)
|
||||||
|
|
||||||
var r0 []string
|
|
||||||
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
|
||||||
r0 = rf(jobID)
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).([]string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var r1 error
|
|
||||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
|
||||||
r1 = rf(jobID)
|
|
||||||
} else {
|
|
||||||
r1 = ret.Error(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadTemplateJob provides a mock function with given fields: environmentID
|
|
||||||
func (_m *ExecutorAPIMock) LoadEnvironmentTemplate(environmentID string) (*api.Job, error) {
|
|
||||||
ret := _m.Called(environmentID)
|
|
||||||
|
|
||||||
var r0 *api.Job
|
|
||||||
if rf, ok := ret.Get(0).(func(string) *api.Job); ok {
|
|
||||||
r0 = rf(environmentID)
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(*api.Job)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var r1 error
|
|
||||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
|
||||||
r1 = rf(environmentID)
|
|
||||||
} else {
|
|
||||||
r1 = ret.Error(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadTemplateJobs provides a mock function with given fields:
|
|
||||||
func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 []*api.Job
|
|
||||||
if rf, ok := ret.Get(0).(func() []*api.Job); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).([]*api.Job)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var r1 error
|
|
||||||
if rf, ok := ret.Get(1).(func() error); ok {
|
|
||||||
r1 = rf()
|
|
||||||
} else {
|
|
||||||
r1 = ret.Error(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkRunnerAsUsed provides a mock function with given fields: runnerID
|
|
||||||
func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string) error {
|
|
||||||
ret := _m.Called(runnerID)
|
|
||||||
|
|
||||||
var r0 error
|
var r0 error
|
||||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
if rf, ok := ret.Get(0).(func(string, int) error); ok {
|
||||||
r0 = rf(runnerID)
|
r0 = rf(runnerID, duration)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Error(0)
|
r0 = ret.Error(0)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ const (
|
|||||||
ConfigMetaUsedKey = "used"
|
ConfigMetaUsedKey = "used"
|
||||||
ConfigMetaUsedValue = "true"
|
ConfigMetaUsedValue = "true"
|
||||||
ConfigMetaUnusedValue = "false"
|
ConfigMetaUnusedValue = "false"
|
||||||
|
ConfigMetaTimeoutKey = "timeout"
|
||||||
ConfigMetaPoolSizeKey = "prewarmingPoolSize"
|
ConfigMetaPoolSizeKey = "prewarmingPoolSize"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"gitlab.hpi.de/codeocean/codemoon/poseidon/util"
|
"gitlab.hpi.de/codeocean/codemoon/poseidon/util"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -255,7 +256,7 @@ func checkEvaluation(eval *nomadApi.Evaluation) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *APIClient) MarkRunnerAsUsed(runnerID string) error {
|
func (a *APIClient) MarkRunnerAsUsed(runnerID string, duration int) error {
|
||||||
job, err := a.job(runnerID)
|
job, err := a.job(runnerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't retrieve job info: %w", err)
|
return fmt.Errorf("couldn't retrieve job info: %w", err)
|
||||||
@ -264,6 +265,10 @@ func (a *APIClient) MarkRunnerAsUsed(runnerID string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't update runner in job as used: %w", err)
|
return fmt.Errorf("couldn't update runner in job as used: %w", err)
|
||||||
}
|
}
|
||||||
|
err = SetMetaConfigValue(job, ConfigMetaTimeoutKey, strconv.Itoa(duration))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't update runner in job with timeout: %w", err)
|
||||||
|
}
|
||||||
_, err = a.RegisterNomadJob(job)
|
_, err = a.RegisterNomadJob(job)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't update runner config: %w", err)
|
return fmt.Errorf("couldn't update runner config: %w", err)
|
||||||
|
@ -5,4 +5,5 @@ import "gitlab.hpi.de/codeocean/codemoon/poseidon/tests"
|
|||||||
const (
|
const (
|
||||||
defaultEnvironmentID = EnvironmentID(tests.DefaultEnvironmentIDAsInteger)
|
defaultEnvironmentID = EnvironmentID(tests.DefaultEnvironmentIDAsInteger)
|
||||||
anotherEnvironmentID = EnvironmentID(tests.AnotherEnvironmentIDAsInteger)
|
anotherEnvironmentID = EnvironmentID(tests.AnotherEnvironmentIDAsInteger)
|
||||||
|
defaultInactivityTimeout = 0
|
||||||
)
|
)
|
||||||
|
@ -44,9 +44,9 @@ type Manager interface {
|
|||||||
CreateOrUpdateEnvironment(id EnvironmentID, desiredIdleRunnersCount uint, templateJob *nomadApi.Job,
|
CreateOrUpdateEnvironment(id EnvironmentID, desiredIdleRunnersCount uint, templateJob *nomadApi.Job,
|
||||||
scale bool) (bool, error)
|
scale bool) (bool, error)
|
||||||
|
|
||||||
// Claim returns a new runner.
|
// Claim returns a new runner. The runner is deleted after duration seconds if duration is not 0.
|
||||||
// It makes sure that the runner is not in use yet and returns an error if no runner could be provided.
|
// It makes sure that the runner is not in use yet and returns an error if no runner could be provided.
|
||||||
Claim(id EnvironmentID) (Runner, error)
|
Claim(id EnvironmentID, duration int) (Runner, error)
|
||||||
|
|
||||||
// Get returns the used runner with the given runnerId.
|
// Get returns the used runner with the given runnerId.
|
||||||
// If no runner with the given runnerId is currently used, it returns an error.
|
// If no runner with the given runnerId is currently used, it returns an error.
|
||||||
@ -170,7 +170,7 @@ func (m *NomadRunnerManager) updateRunnerSpecs(environmentID EnvironmentID, temp
|
|||||||
return occurredError
|
return occurredError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *NomadRunnerManager) Claim(environmentID EnvironmentID) (Runner, error) {
|
func (m *NomadRunnerManager) Claim(environmentID EnvironmentID, duration int) (Runner, error) {
|
||||||
job, ok := m.environments.Get(environmentID)
|
job, ok := m.environments.Get(environmentID)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrUnknownExecutionEnvironment
|
return nil, ErrUnknownExecutionEnvironment
|
||||||
@ -180,7 +180,7 @@ func (m *NomadRunnerManager) Claim(environmentID EnvironmentID) (Runner, error)
|
|||||||
return nil, ErrNoRunnersAvailable
|
return nil, ErrNoRunnersAvailable
|
||||||
}
|
}
|
||||||
m.usedRunners.Add(runner)
|
m.usedRunners.Add(runner)
|
||||||
err := m.apiClient.MarkRunnerAsUsed(runner.Id())
|
err := m.apiClient.MarkRunnerAsUsed(runner.Id(), duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't mark runner as used: %w", err)
|
return nil, fmt.Errorf("can't mark runner as used: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Code generated by mockery v2.8.0. DO NOT EDIT.
|
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
@ -12,13 +12,13 @@ type ManagerMock struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
// Claim provides a mock function with given fields: id
|
// Claim provides a mock function with given fields: id, duration
|
||||||
func (_m *ManagerMock) Claim(id EnvironmentID) (Runner, error) {
|
func (_m *ManagerMock) Claim(id EnvironmentID, duration int) (Runner, error) {
|
||||||
ret := _m.Called(id)
|
ret := _m.Called(id, duration)
|
||||||
|
|
||||||
var r0 Runner
|
var r0 Runner
|
||||||
if rf, ok := ret.Get(0).(func(EnvironmentID) Runner); ok {
|
if rf, ok := ret.Get(0).(func(EnvironmentID, int) Runner); ok {
|
||||||
r0 = rf(id)
|
r0 = rf(id, duration)
|
||||||
} else {
|
} else {
|
||||||
if ret.Get(0) != nil {
|
if ret.Get(0) != nil {
|
||||||
r0 = ret.Get(0).(Runner)
|
r0 = ret.Get(0).(Runner)
|
||||||
@ -26,8 +26,8 @@ func (_m *ManagerMock) Claim(id EnvironmentID) (Runner, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(EnvironmentID) error); ok {
|
if rf, ok := ret.Get(1).(func(EnvironmentID, int) error); ok {
|
||||||
r1 = rf(id)
|
r1 = rf(id, duration)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
@ -35,20 +35,20 @@ func (_m *ManagerMock) Claim(id EnvironmentID) (Runner, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOrUpdateEnvironment provides a mock function with given fields: id, desiredIdleRunnersCount, teplateJob, scale
|
// CreateOrUpdateEnvironment provides a mock function with given fields: id, desiredIdleRunnersCount, templateJob, scale
|
||||||
func (_m *ManagerMock) CreateOrUpdateEnvironment(id EnvironmentID, desiredIdleRunnersCount uint, teplateJob *api.Job, scale bool) (bool, error) {
|
func (_m *ManagerMock) CreateOrUpdateEnvironment(id EnvironmentID, desiredIdleRunnersCount uint, templateJob *api.Job, scale bool) (bool, error) {
|
||||||
ret := _m.Called(id, desiredIdleRunnersCount, teplateJob, scale)
|
ret := _m.Called(id, desiredIdleRunnersCount, templateJob, scale)
|
||||||
|
|
||||||
var r0 bool
|
var r0 bool
|
||||||
if rf, ok := ret.Get(0).(func(EnvironmentID, uint, *api.Job, bool) bool); ok {
|
if rf, ok := ret.Get(0).(func(EnvironmentID, uint, *api.Job, bool) bool); ok {
|
||||||
r0 = rf(id, desiredIdleRunnersCount, teplateJob, scale)
|
r0 = rf(id, desiredIdleRunnersCount, templateJob, scale)
|
||||||
} else {
|
} else {
|
||||||
r0 = ret.Get(0).(bool)
|
r0 = ret.Get(0).(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
var r1 error
|
var r1 error
|
||||||
if rf, ok := ret.Get(1).(func(EnvironmentID, uint, *api.Job, bool) error); ok {
|
if rf, ok := ret.Get(1).(func(EnvironmentID, uint, *api.Job, bool) error); ok {
|
||||||
r1 = rf(id, desiredIdleRunnersCount, teplateJob, scale)
|
r1 = rf(id, desiredIdleRunnersCount, templateJob, scale)
|
||||||
} else {
|
} else {
|
||||||
r1 = ret.Error(1)
|
r1 = ret.Error(1)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func mockRunnerQueries(apiMock *nomad.ExecutorAPIMock, returnedRunnerIds []strin
|
|||||||
call.ReturnArguments = mock.Arguments{nil}
|
call.ReturnArguments = mock.Arguments{nil}
|
||||||
})
|
})
|
||||||
apiMock.On("LoadEnvironmentJobs").Return([]*nomadApi.Job{}, nil)
|
apiMock.On("LoadEnvironmentJobs").Return([]*nomadApi.Job{}, nil)
|
||||||
apiMock.On("MarkRunnerAsUsed", mock.AnythingOfType("string")).Return(nil)
|
apiMock.On("MarkRunnerAsUsed", mock.AnythingOfType("string"), mock.AnythingOfType("int")).Return(nil)
|
||||||
apiMock.On("LoadRunnerIDs", tests.DefaultJobID).Return(returnedRunnerIds, nil)
|
apiMock.On("LoadRunnerIDs", tests.DefaultJobID).Return(returnedRunnerIds, nil)
|
||||||
apiMock.On("JobScale", tests.DefaultJobID).Return(uint(len(returnedRunnerIds)), nil)
|
apiMock.On("JobScale", tests.DefaultJobID).Return(uint(len(returnedRunnerIds)), nil)
|
||||||
apiMock.On("SetJobScale", tests.DefaultJobID, mock.AnythingOfType("uint"), "Runner Requested").Return(nil)
|
apiMock.On("SetJobScale", tests.DefaultJobID, mock.AnythingOfType("uint"), "Runner Requested").Return(nil)
|
||||||
@ -82,28 +82,28 @@ func (s *ManagerTestSuite) TestRegisterEnvironmentAddsNewJob() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ManagerTestSuite) TestClaimReturnsNotFoundErrorIfEnvironmentNotFound() {
|
func (s *ManagerTestSuite) TestClaimReturnsNotFoundErrorIfEnvironmentNotFound() {
|
||||||
runner, err := s.nomadRunnerManager.Claim(EnvironmentID(42))
|
runner, err := s.nomadRunnerManager.Claim(EnvironmentID(42), defaultInactivityTimeout)
|
||||||
s.Nil(runner)
|
s.Nil(runner)
|
||||||
s.Equal(ErrUnknownExecutionEnvironment, err)
|
s.Equal(ErrUnknownExecutionEnvironment, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ManagerTestSuite) TestClaimReturnsRunnerIfAvailable() {
|
func (s *ManagerTestSuite) TestClaimReturnsRunnerIfAvailable() {
|
||||||
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
||||||
receivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID)
|
receivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID, defaultInactivityTimeout)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
s.Equal(s.exerciseRunner, receivedRunner)
|
s.Equal(s.exerciseRunner, receivedRunner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ManagerTestSuite) TestClaimReturnsErrorIfNoRunnerAvailable() {
|
func (s *ManagerTestSuite) TestClaimReturnsErrorIfNoRunnerAvailable() {
|
||||||
s.waitForRunnerRefresh()
|
s.waitForRunnerRefresh()
|
||||||
runner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID)
|
runner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID, defaultInactivityTimeout)
|
||||||
s.Nil(runner)
|
s.Nil(runner)
|
||||||
s.Equal(ErrNoRunnersAvailable, err)
|
s.Equal(ErrNoRunnersAvailable, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ManagerTestSuite) TestClaimReturnsNoRunnerOfDifferentEnvironment() {
|
func (s *ManagerTestSuite) TestClaimReturnsNoRunnerOfDifferentEnvironment() {
|
||||||
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
||||||
receivedRunner, err := s.nomadRunnerManager.Claim(anotherEnvironmentID)
|
receivedRunner, err := s.nomadRunnerManager.Claim(anotherEnvironmentID, defaultInactivityTimeout)
|
||||||
s.Nil(receivedRunner)
|
s.Nil(receivedRunner)
|
||||||
s.Error(err)
|
s.Error(err)
|
||||||
}
|
}
|
||||||
@ -112,22 +112,22 @@ func (s *ManagerTestSuite) TestClaimDoesNotReturnTheSameRunnerTwice() {
|
|||||||
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
||||||
s.AddIdleRunnerForDefaultEnvironment(NewRunner(tests.AnotherRunnerID, s.nomadRunnerManager))
|
s.AddIdleRunnerForDefaultEnvironment(NewRunner(tests.AnotherRunnerID, s.nomadRunnerManager))
|
||||||
|
|
||||||
firstReceivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID)
|
firstReceivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID, defaultInactivityTimeout)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
secondReceivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID)
|
secondReceivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID, defaultInactivityTimeout)
|
||||||
s.NoError(err)
|
s.NoError(err)
|
||||||
s.NotEqual(firstReceivedRunner, secondReceivedRunner)
|
s.NotEqual(firstReceivedRunner, secondReceivedRunner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ManagerTestSuite) TestClaimThrowsAnErrorIfNoRunnersAvailable() {
|
func (s *ManagerTestSuite) TestClaimThrowsAnErrorIfNoRunnersAvailable() {
|
||||||
receivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID)
|
receivedRunner, err := s.nomadRunnerManager.Claim(defaultEnvironmentID, defaultInactivityTimeout)
|
||||||
s.Nil(receivedRunner)
|
s.Nil(receivedRunner)
|
||||||
s.Error(err)
|
s.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ManagerTestSuite) TestClaimAddsRunnerToUsedRunners() {
|
func (s *ManagerTestSuite) TestClaimAddsRunnerToUsedRunners() {
|
||||||
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
s.AddIdleRunnerForDefaultEnvironment(s.exerciseRunner)
|
||||||
receivedRunner, _ := s.nomadRunnerManager.Claim(defaultEnvironmentID)
|
receivedRunner, _ := s.nomadRunnerManager.Claim(defaultEnvironmentID, defaultInactivityTimeout)
|
||||||
savedRunner, ok := s.nomadRunnerManager.usedRunners.Get(receivedRunner.Id())
|
savedRunner, ok := s.nomadRunnerManager.usedRunners.Get(receivedRunner.Id())
|
||||||
s.True(ok)
|
s.True(ok)
|
||||||
s.Equal(savedRunner, receivedRunner)
|
s.Equal(savedRunner, receivedRunner)
|
||||||
|
Reference in New Issue
Block a user