Refactor Nomad Command Generation.

- Abstracting from the exec form while generating.
- Removal of single quotes (usage of only double-quotes).
- Bash-nesting using escaping of special characters.
This commit is contained in:
Maximilian Paß
2023-03-06 00:20:09 +00:00
committed by Sebastian Serth
parent f309d0f70e
commit 7dadc5dfe9
13 changed files with 1148 additions and 150 deletions

View File

@ -290,7 +290,7 @@ func TestWebSocketProxyStopsReadingTheWebSocketAfterClosingIt(t *testing.T) {
r.StoreExecution(executionID, &executionRequestHead) r.StoreExecution(executionID, &executionRequestHead)
mockAPIExecute(apiMock, &executionRequestHead, mockAPIExecute(apiMock, &executionRequestHead,
func(_ string, ctx context.Context, _ []string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { func(_ string, ctx context.Context, _ string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) {
return 0, nil return 0, nil
}) })
connection, _, err := websocket.DefaultDialer.Dial(wsURL.String(), nil) connection, _, err := websocket.DefaultDialer.Dial(wsURL.String(), nil)
@ -376,7 +376,7 @@ var executionRequestLs = dto.ExecutionRequest{Command: "ls"}
// 'ls existing-file non-existing-file' was executed. // 'ls existing-file non-existing-file' was executed.
func mockAPIExecuteLs(api *nomad.ExecutorAPIMock) { func mockAPIExecuteLs(api *nomad.ExecutorAPIMock) {
mockAPIExecute(api, &executionRequestLs, mockAPIExecute(api, &executionRequestLs,
func(_ string, _ context.Context, _ []string, _ bool, _ io.Reader, stdout, stderr io.Writer) (int, error) { func(_ string, _ context.Context, _ string, _ bool, _ io.Reader, stdout, stderr io.Writer) (int, error) {
_, _ = stdout.Write([]byte("existing-file\n")) _, _ = stdout.Write([]byte("existing-file\n"))
_, _ = stderr.Write([]byte("ls: cannot access 'non-existing-file': No such file or directory\n")) _, _ = stderr.Write([]byte("ls: cannot access 'non-existing-file': No such file or directory\n"))
return 0, nil return 0, nil
@ -388,7 +388,7 @@ var executionRequestHead = dto.ExecutionRequest{Command: "head -n 1"}
// mockAPIExecuteHead mocks the ExecuteCommand of an ExecutorApi to act as if 'head -n 1' was executed. // mockAPIExecuteHead mocks the ExecuteCommand of an ExecutorApi to act as if 'head -n 1' was executed.
func mockAPIExecuteHead(api *nomad.ExecutorAPIMock) { func mockAPIExecuteHead(api *nomad.ExecutorAPIMock) {
mockAPIExecute(api, &executionRequestHead, mockAPIExecute(api, &executionRequestHead,
func(_ string, _ context.Context, _ []string, _ bool, func(_ string, _ context.Context, _ string, _ bool,
stdin io.Reader, stdout io.Writer, stderr io.Writer, stdin io.Reader, stdout io.Writer, stderr io.Writer,
) (int, error) { ) (int, error) {
scanner := bufio.NewScanner(stdin) scanner := bufio.NewScanner(stdin)
@ -408,7 +408,7 @@ func mockAPIExecuteSleep(api *nomad.ExecutorAPIMock) <-chan bool {
canceled := make(chan bool, 1) canceled := make(chan bool, 1)
mockAPIExecute(api, &executionRequestSleep, mockAPIExecute(api, &executionRequestSleep,
func(_ string, ctx context.Context, _ []string, _ bool, func(_ string, ctx context.Context, _ string, _ bool,
stdin io.Reader, stdout io.Writer, stderr io.Writer, stdin io.Reader, stdout io.Writer, stderr io.Writer,
) (int, error) { ) (int, error) {
var err error var err error
@ -429,7 +429,7 @@ var executionRequestError = dto.ExecutionRequest{Command: "error"}
// mockAPIExecuteError mocks the ExecuteCommand method of an ExecutorApi to return an error. // mockAPIExecuteError mocks the ExecuteCommand method of an ExecutorApi to return an error.
func mockAPIExecuteError(api *nomad.ExecutorAPIMock) { func mockAPIExecuteError(api *nomad.ExecutorAPIMock) {
mockAPIExecute(api, &executionRequestError, mockAPIExecute(api, &executionRequestError,
func(_ string, _ context.Context, _ []string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { func(_ string, _ context.Context, _ string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) {
return 0, tests.ErrDefault return 0, tests.ErrDefault
}) })
} }
@ -439,7 +439,7 @@ var executionRequestExitNonZero = dto.ExecutionRequest{Command: "exit 42"}
// mockAPIExecuteExitNonZero mocks the ExecuteCommand method of an ExecutorApi to exit with exit status 42. // mockAPIExecuteExitNonZero mocks the ExecuteCommand method of an ExecutorApi to exit with exit status 42.
func mockAPIExecuteExitNonZero(api *nomad.ExecutorAPIMock) { func mockAPIExecuteExitNonZero(api *nomad.ExecutorAPIMock) {
mockAPIExecute(api, &executionRequestExitNonZero, mockAPIExecute(api, &executionRequestExitNonZero,
func(_ string, _ context.Context, _ []string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) { func(_ string, _ context.Context, _ string, _ bool, _ io.Reader, _, _ io.Writer) (int, error) {
return 42, nil return 42, nil
}) })
} }
@ -447,7 +447,7 @@ func mockAPIExecuteExitNonZero(api *nomad.ExecutorAPIMock) {
// mockAPIExecute mocks the ExecuteCommand method of an ExecutorApi to call the given method run when the command // mockAPIExecute mocks the ExecuteCommand method of an ExecutorApi to call the given method run when the command
// corresponding to the given ExecutionRequest is called. // corresponding to the given ExecutionRequest is called.
func mockAPIExecute(api *nomad.ExecutorAPIMock, request *dto.ExecutionRequest, func mockAPIExecute(api *nomad.ExecutorAPIMock, request *dto.ExecutionRequest,
run func(runnerId string, ctx context.Context, command []string, tty bool, run func(runnerId string, ctx context.Context, command string, tty bool,
stdin io.Reader, stdout, stderr io.Writer) (int, error)) { stdin io.Reader, stdout, stderr io.Writer) (int, error)) {
call := api.On("ExecuteCommand", call := api.On("ExecuteCommand",
mock.AnythingOfType("string"), mock.AnythingOfType("string"),
@ -461,7 +461,7 @@ func mockAPIExecute(api *nomad.ExecutorAPIMock, request *dto.ExecutionRequest,
call.Run(func(args mock.Arguments) { call.Run(func(args mock.Arguments) {
exit, err := run(args.Get(0).(string), exit, err := run(args.Get(0).(string),
args.Get(1).(context.Context), args.Get(1).(context.Context),
args.Get(2).([]string), args.Get(2).(string),
args.Get(3).(bool), args.Get(3).(bool),
args.Get(5).(io.Reader), args.Get(5).(io.Reader),
args.Get(6).(io.Writer), args.Get(6).(io.Writer),

View File

@ -34,7 +34,7 @@ type apiQuerier interface {
DeleteJob(jobID string) (err error) DeleteJob(jobID string) (err error)
// Execute runs a command in the passed job. // Execute runs a command in the passed job.
Execute(jobID string, ctx context.Context, command []string, tty bool, Execute(jobID string, ctx context.Context, command string, tty bool,
stdin io.Reader, stdout, stderr io.Writer) (int, error) stdin io.Reader, stdout, stderr io.Writer) (int, error)
// listJobs loads all jobs with the specified prefix. // listJobs loads all jobs with the specified prefix.
@ -87,11 +87,10 @@ func (nc *nomadAPIClient) DeleteJob(jobID string) (err error) {
} }
func (nc *nomadAPIClient) Execute(runnerID string, func (nc *nomadAPIClient) Execute(runnerID string,
ctx context.Context, command []string, tty bool, ctx context.Context, cmd string, tty bool,
stdin io.Reader, stdout, stderr io.Writer, stdin io.Reader, stdout, stderr io.Writer,
) (int, error) { ) (int, error) {
log.WithField("command", strings.ReplaceAll(strings.Join(command, ", "), "\n", "")). log.WithField("command", strings.ReplaceAll(cmd, "\n", "")).Trace("Requesting Nomad Exec")
Trace("Requesting Nomad Exec")
var allocations []*nomadApi.AllocationListStub var allocations []*nomadApi.AllocationListStub
var err error var err error
logging.StartSpan("nomad.execute.list", "List Allocations for id", ctx, func(_ context.Context) { logging.StartSpan("nomad.execute.list", "List Allocations for id", ctx, func(_ context.Context) {
@ -115,8 +114,9 @@ func (nc *nomadAPIClient) Execute(runnerID string,
var exitCode int var exitCode int
logging.StartSpan("nomad.execute.exec", "Execute Command in Allocation", ctx, func(ctx context.Context) { logging.StartSpan("nomad.execute.exec", "Execute Command in Allocation", ctx, func(ctx context.Context) {
debugWriter := NewSentryDebugWriter(stdout, ctx) debugWriter := NewSentryDebugWriter(stdout, ctx)
commands := []string{"/bin/bash", "-c", cmd}
exitCode, err = nc.client.Allocations(). exitCode, err = nc.client.Allocations().
Exec(ctx, allocation, TaskName, tty, command, stdin, debugWriter, stderr, nil, nil) Exec(ctx, allocation, TaskName, tty, commands, stdin, debugWriter, stderr, nil, nil)
debugWriter.Close(exitCode) debugWriter.Close(exitCode)
}) })
switch { switch {

View File

@ -1,4 +1,4 @@
// Code generated by mockery v2.9.4. DO NOT EDIT. // Code generated by mockery v2.21.0. DO NOT EDIT.
package nomad package nomad
@ -18,6 +18,14 @@ type apiQuerierMock struct {
mock.Mock mock.Mock
} }
type apiQuerierMock_Expecter struct {
mock *mock.Mock
}
func (_m *apiQuerierMock) EXPECT() *apiQuerierMock_Expecter {
return &apiQuerierMock_Expecter{mock: &_m.Mock}
}
// DeleteJob provides a mock function with given fields: jobID // DeleteJob provides a mock function with given fields: jobID
func (_m *apiQuerierMock) DeleteJob(jobID string) error { func (_m *apiQuerierMock) DeleteJob(jobID string) error {
ret := _m.Called(jobID) ret := _m.Called(jobID)
@ -32,11 +40,43 @@ func (_m *apiQuerierMock) DeleteJob(jobID string) error {
return r0 return r0
} }
// apiQuerierMock_DeleteJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteJob'
type apiQuerierMock_DeleteJob_Call struct {
*mock.Call
}
// DeleteJob is a helper method to define mock.On call
// - jobID string
func (_e *apiQuerierMock_Expecter) DeleteJob(jobID interface{}) *apiQuerierMock_DeleteJob_Call {
return &apiQuerierMock_DeleteJob_Call{Call: _e.mock.On("DeleteJob", jobID)}
}
func (_c *apiQuerierMock_DeleteJob_Call) Run(run func(jobID string)) *apiQuerierMock_DeleteJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *apiQuerierMock_DeleteJob_Call) Return(err error) *apiQuerierMock_DeleteJob_Call {
_c.Call.Return(err)
return _c
}
func (_c *apiQuerierMock_DeleteJob_Call) RunAndReturn(run func(string) error) *apiQuerierMock_DeleteJob_Call {
_c.Call.Return(run)
return _c
}
// EventStream provides a mock function with given fields: ctx // EventStream provides a mock function with given fields: ctx
func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events, error) { func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events, error) {
ret := _m.Called(ctx) ret := _m.Called(ctx)
var r0 <-chan *api.Events var r0 <-chan *api.Events
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (<-chan *api.Events, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) <-chan *api.Events); ok { if rf, ok := ret.Get(0).(func(context.Context) <-chan *api.Events); ok {
r0 = rf(ctx) r0 = rf(ctx)
} else { } else {
@ -45,7 +85,6 @@ func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events,
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok { if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx) r1 = rf(ctx)
} else { } else {
@ -55,19 +94,50 @@ func (_m *apiQuerierMock) EventStream(ctx context.Context) (<-chan *api.Events,
return r0, r1 return r0, r1
} }
// apiQuerierMock_EventStream_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventStream'
type apiQuerierMock_EventStream_Call struct {
*mock.Call
}
// EventStream is a helper method to define mock.On call
// - ctx context.Context
func (_e *apiQuerierMock_Expecter) EventStream(ctx interface{}) *apiQuerierMock_EventStream_Call {
return &apiQuerierMock_EventStream_Call{Call: _e.mock.On("EventStream", ctx)}
}
func (_c *apiQuerierMock_EventStream_Call) Run(run func(ctx context.Context)) *apiQuerierMock_EventStream_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *apiQuerierMock_EventStream_Call) Return(_a0 <-chan *api.Events, _a1 error) *apiQuerierMock_EventStream_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *apiQuerierMock_EventStream_Call) RunAndReturn(run func(context.Context) (<-chan *api.Events, error)) *apiQuerierMock_EventStream_Call {
_c.Call.Return(run)
return _c
}
// Execute provides a mock function with given fields: jobID, ctx, command, tty, stdin, stdout, stderr // Execute provides a mock function with given fields: jobID, ctx, command, tty, stdin, stdout, stderr
func (_m *apiQuerierMock) Execute(jobID string, ctx context.Context, command []string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { func (_m *apiQuerierMock) Execute(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
if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) int); ok { var r1 error
if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)); ok {
return rf(jobID, ctx, command, tty, stdin, stdout, stderr)
}
if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) int); ok {
r0 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) r0 = rf(jobID, ctx, command, tty, stdin, stdout, stderr)
} else { } else {
r0 = ret.Get(0).(int) 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 {
if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) error); ok {
r1 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) r1 = rf(jobID, ctx, command, tty, stdin, stdout, stderr)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
@ -76,18 +146,55 @@ func (_m *apiQuerierMock) Execute(jobID string, ctx context.Context, command []s
return r0, r1 return r0, r1
} }
// apiQuerierMock_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute'
type apiQuerierMock_Execute_Call struct {
*mock.Call
}
// Execute is a helper method to define mock.On call
// - jobID string
// - ctx context.Context
// - command string
// - tty bool
// - stdin io.Reader
// - stdout io.Writer
// - stderr io.Writer
func (_e *apiQuerierMock_Expecter) Execute(jobID interface{}, ctx interface{}, command interface{}, tty interface{}, stdin interface{}, stdout interface{}, stderr interface{}) *apiQuerierMock_Execute_Call {
return &apiQuerierMock_Execute_Call{Call: _e.mock.On("Execute", jobID, ctx, command, tty, stdin, stdout, stderr)}
}
func (_c *apiQuerierMock_Execute_Call) Run(run func(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer)) *apiQuerierMock_Execute_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(context.Context), args[2].(string), args[3].(bool), args[4].(io.Reader), args[5].(io.Writer), args[6].(io.Writer))
})
return _c
}
func (_c *apiQuerierMock_Execute_Call) Return(_a0 int, _a1 error) *apiQuerierMock_Execute_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *apiQuerierMock_Execute_Call) RunAndReturn(run func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)) *apiQuerierMock_Execute_Call {
_c.Call.Return(run)
return _c
}
// JobScale provides a mock function with given fields: jobID // JobScale provides a mock function with given fields: jobID
func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) { func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) {
ret := _m.Called(jobID) ret := _m.Called(jobID)
var r0 uint var r0 uint
var r1 error
if rf, ok := ret.Get(0).(func(string) (uint, error)); ok {
return rf(jobID)
}
if rf, ok := ret.Get(0).(func(string) uint); ok { if rf, ok := ret.Get(0).(func(string) uint); ok {
r0 = rf(jobID) r0 = rf(jobID)
} else { } else {
r0 = ret.Get(0).(uint) r0 = ret.Get(0).(uint)
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobID) r1 = rf(jobID)
} else { } else {
@ -97,11 +204,43 @@ func (_m *apiQuerierMock) JobScale(jobID string) (uint, error) {
return r0, r1 return r0, r1
} }
// apiQuerierMock_JobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobScale'
type apiQuerierMock_JobScale_Call struct {
*mock.Call
}
// JobScale is a helper method to define mock.On call
// - jobID string
func (_e *apiQuerierMock_Expecter) JobScale(jobID interface{}) *apiQuerierMock_JobScale_Call {
return &apiQuerierMock_JobScale_Call{Call: _e.mock.On("JobScale", jobID)}
}
func (_c *apiQuerierMock_JobScale_Call) Run(run func(jobID string)) *apiQuerierMock_JobScale_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *apiQuerierMock_JobScale_Call) Return(jobScale uint, err error) *apiQuerierMock_JobScale_Call {
_c.Call.Return(jobScale, err)
return _c
}
func (_c *apiQuerierMock_JobScale_Call) RunAndReturn(run func(string) (uint, error)) *apiQuerierMock_JobScale_Call {
_c.Call.Return(run)
return _c
}
// LoadJobList provides a mock function with given fields: // LoadJobList provides a mock function with given fields:
func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) { func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) {
ret := _m.Called() ret := _m.Called()
var r0 []*api.JobListStub var r0 []*api.JobListStub
var r1 error
if rf, ok := ret.Get(0).(func() ([]*api.JobListStub, error)); ok {
return rf()
}
if rf, ok := ret.Get(0).(func() []*api.JobListStub); ok { if rf, ok := ret.Get(0).(func() []*api.JobListStub); ok {
r0 = rf() r0 = rf()
} else { } else {
@ -110,7 +249,6 @@ func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func() error); ok { if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf() r1 = rf()
} else { } else {
@ -120,18 +258,48 @@ func (_m *apiQuerierMock) LoadJobList() ([]*api.JobListStub, error) {
return r0, r1 return r0, r1
} }
// apiQuerierMock_LoadJobList_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadJobList'
type apiQuerierMock_LoadJobList_Call struct {
*mock.Call
}
// LoadJobList is a helper method to define mock.On call
func (_e *apiQuerierMock_Expecter) LoadJobList() *apiQuerierMock_LoadJobList_Call {
return &apiQuerierMock_LoadJobList_Call{Call: _e.mock.On("LoadJobList")}
}
func (_c *apiQuerierMock_LoadJobList_Call) Run(run func()) *apiQuerierMock_LoadJobList_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *apiQuerierMock_LoadJobList_Call) Return(list []*api.JobListStub, err error) *apiQuerierMock_LoadJobList_Call {
_c.Call.Return(list, err)
return _c
}
func (_c *apiQuerierMock_LoadJobList_Call) RunAndReturn(run func() ([]*api.JobListStub, error)) *apiQuerierMock_LoadJobList_Call {
_c.Call.Return(run)
return _c
}
// RegisterNomadJob provides a mock function with given fields: job // RegisterNomadJob provides a mock function with given fields: job
func (_m *apiQuerierMock) RegisterNomadJob(job *api.Job) (string, error) { func (_m *apiQuerierMock) RegisterNomadJob(job *api.Job) (string, error) {
ret := _m.Called(job) ret := _m.Called(job)
var r0 string var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(*api.Job) (string, error)); ok {
return rf(job)
}
if rf, ok := ret.Get(0).(func(*api.Job) string); ok { if rf, ok := ret.Get(0).(func(*api.Job) string); ok {
r0 = rf(job) r0 = rf(job)
} else { } else {
r0 = ret.Get(0).(string) r0 = ret.Get(0).(string)
} }
var r1 error
if rf, ok := ret.Get(1).(func(*api.Job) error); ok { if rf, ok := ret.Get(1).(func(*api.Job) error); ok {
r1 = rf(job) r1 = rf(job)
} else { } else {
@ -141,6 +309,34 @@ func (_m *apiQuerierMock) RegisterNomadJob(job *api.Job) (string, error) {
return r0, r1 return r0, r1
} }
// apiQuerierMock_RegisterNomadJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterNomadJob'
type apiQuerierMock_RegisterNomadJob_Call struct {
*mock.Call
}
// RegisterNomadJob is a helper method to define mock.On call
// - job *api.Job
func (_e *apiQuerierMock_Expecter) RegisterNomadJob(job interface{}) *apiQuerierMock_RegisterNomadJob_Call {
return &apiQuerierMock_RegisterNomadJob_Call{Call: _e.mock.On("RegisterNomadJob", job)}
}
func (_c *apiQuerierMock_RegisterNomadJob_Call) Run(run func(job *api.Job)) *apiQuerierMock_RegisterNomadJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*api.Job))
})
return _c
}
func (_c *apiQuerierMock_RegisterNomadJob_Call) Return(_a0 string, _a1 error) *apiQuerierMock_RegisterNomadJob_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *apiQuerierMock_RegisterNomadJob_Call) RunAndReturn(run func(*api.Job) (string, error)) *apiQuerierMock_RegisterNomadJob_Call {
_c.Call.Return(run)
return _c
}
// SetJobScale provides a mock function with given fields: jobID, count, reason // SetJobScale provides a mock function with given fields: jobID, count, reason
func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) error { func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) error {
ret := _m.Called(jobID, count, reason) ret := _m.Called(jobID, count, reason)
@ -155,11 +351,45 @@ func (_m *apiQuerierMock) SetJobScale(jobID string, count uint, reason string) e
return r0 return r0
} }
// apiQuerierMock_SetJobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetJobScale'
type apiQuerierMock_SetJobScale_Call struct {
*mock.Call
}
// SetJobScale is a helper method to define mock.On call
// - jobID string
// - count uint
// - reason string
func (_e *apiQuerierMock_Expecter) SetJobScale(jobID interface{}, count interface{}, reason interface{}) *apiQuerierMock_SetJobScale_Call {
return &apiQuerierMock_SetJobScale_Call{Call: _e.mock.On("SetJobScale", jobID, count, reason)}
}
func (_c *apiQuerierMock_SetJobScale_Call) Run(run func(jobID string, count uint, reason string)) *apiQuerierMock_SetJobScale_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(uint), args[2].(string))
})
return _c
}
func (_c *apiQuerierMock_SetJobScale_Call) Return(err error) *apiQuerierMock_SetJobScale_Call {
_c.Call.Return(err)
return _c
}
func (_c *apiQuerierMock_SetJobScale_Call) RunAndReturn(run func(string, uint, string) error) *apiQuerierMock_SetJobScale_Call {
_c.Call.Return(run)
return _c
}
// allocation provides a mock function with given fields: jobID // allocation provides a mock function with given fields: jobID
func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) { func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) {
ret := _m.Called(jobID) ret := _m.Called(jobID)
var r0 *api.Allocation var r0 *api.Allocation
var r1 error
if rf, ok := ret.Get(0).(func(string) (*api.Allocation, error)); ok {
return rf(jobID)
}
if rf, ok := ret.Get(0).(func(string) *api.Allocation); ok { if rf, ok := ret.Get(0).(func(string) *api.Allocation); ok {
r0 = rf(jobID) r0 = rf(jobID)
} else { } else {
@ -168,7 +398,6 @@ func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobID) r1 = rf(jobID)
} else { } else {
@ -178,6 +407,34 @@ func (_m *apiQuerierMock) allocation(jobID string) (*api.Allocation, error) {
return r0, r1 return r0, r1
} }
// apiQuerierMock_allocation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'allocation'
type apiQuerierMock_allocation_Call struct {
*mock.Call
}
// allocation is a helper method to define mock.On call
// - jobID string
func (_e *apiQuerierMock_Expecter) allocation(jobID interface{}) *apiQuerierMock_allocation_Call {
return &apiQuerierMock_allocation_Call{Call: _e.mock.On("allocation", jobID)}
}
func (_c *apiQuerierMock_allocation_Call) Run(run func(jobID string)) *apiQuerierMock_allocation_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *apiQuerierMock_allocation_Call) Return(_a0 *api.Allocation, _a1 error) *apiQuerierMock_allocation_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *apiQuerierMock_allocation_Call) RunAndReturn(run func(string) (*api.Allocation, error)) *apiQuerierMock_allocation_Call {
_c.Call.Return(run)
return _c
}
// init provides a mock function with given fields: nomadConfig // init provides a mock function with given fields: nomadConfig
func (_m *apiQuerierMock) init(nomadConfig *config.Nomad) error { func (_m *apiQuerierMock) init(nomadConfig *config.Nomad) error {
ret := _m.Called(nomadConfig) ret := _m.Called(nomadConfig)
@ -192,11 +449,43 @@ func (_m *apiQuerierMock) init(nomadConfig *config.Nomad) error {
return r0 return r0
} }
// apiQuerierMock_init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'init'
type apiQuerierMock_init_Call struct {
*mock.Call
}
// init is a helper method to define mock.On call
// - nomadConfig *config.Nomad
func (_e *apiQuerierMock_Expecter) init(nomadConfig interface{}) *apiQuerierMock_init_Call {
return &apiQuerierMock_init_Call{Call: _e.mock.On("init", nomadConfig)}
}
func (_c *apiQuerierMock_init_Call) Run(run func(nomadConfig *config.Nomad)) *apiQuerierMock_init_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*config.Nomad))
})
return _c
}
func (_c *apiQuerierMock_init_Call) Return(err error) *apiQuerierMock_init_Call {
_c.Call.Return(err)
return _c
}
func (_c *apiQuerierMock_init_Call) RunAndReturn(run func(*config.Nomad) error) *apiQuerierMock_init_Call {
_c.Call.Return(run)
return _c
}
// job provides a mock function with given fields: jobID // job provides a mock function with given fields: jobID
func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) { func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) {
ret := _m.Called(jobID) ret := _m.Called(jobID)
var r0 *api.Job var r0 *api.Job
var r1 error
if rf, ok := ret.Get(0).(func(string) (*api.Job, error)); ok {
return rf(jobID)
}
if rf, ok := ret.Get(0).(func(string) *api.Job); ok { if rf, ok := ret.Get(0).(func(string) *api.Job); ok {
r0 = rf(jobID) r0 = rf(jobID)
} else { } else {
@ -205,7 +494,6 @@ func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobID) r1 = rf(jobID)
} else { } else {
@ -215,11 +503,43 @@ func (_m *apiQuerierMock) job(jobID string) (*api.Job, error) {
return r0, r1 return r0, r1
} }
// apiQuerierMock_job_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'job'
type apiQuerierMock_job_Call struct {
*mock.Call
}
// job is a helper method to define mock.On call
// - jobID string
func (_e *apiQuerierMock_Expecter) job(jobID interface{}) *apiQuerierMock_job_Call {
return &apiQuerierMock_job_Call{Call: _e.mock.On("job", jobID)}
}
func (_c *apiQuerierMock_job_Call) Run(run func(jobID string)) *apiQuerierMock_job_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *apiQuerierMock_job_Call) Return(job *api.Job, err error) *apiQuerierMock_job_Call {
_c.Call.Return(job, err)
return _c
}
func (_c *apiQuerierMock_job_Call) RunAndReturn(run func(string) (*api.Job, error)) *apiQuerierMock_job_Call {
_c.Call.Return(run)
return _c
}
// listJobs provides a mock function with given fields: prefix // listJobs provides a mock function with given fields: prefix
func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) { func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) {
ret := _m.Called(prefix) ret := _m.Called(prefix)
var r0 []*api.JobListStub var r0 []*api.JobListStub
var r1 error
if rf, ok := ret.Get(0).(func(string) ([]*api.JobListStub, error)); ok {
return rf(prefix)
}
if rf, ok := ret.Get(0).(func(string) []*api.JobListStub); ok { if rf, ok := ret.Get(0).(func(string) []*api.JobListStub); ok {
r0 = rf(prefix) r0 = rf(prefix)
} else { } else {
@ -228,7 +548,6 @@ func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prefix) r1 = rf(prefix)
} else { } else {
@ -237,3 +556,46 @@ func (_m *apiQuerierMock) listJobs(prefix string) ([]*api.JobListStub, error) {
return r0, r1 return r0, r1
} }
// apiQuerierMock_listJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'listJobs'
type apiQuerierMock_listJobs_Call struct {
*mock.Call
}
// listJobs is a helper method to define mock.On call
// - prefix string
func (_e *apiQuerierMock_Expecter) listJobs(prefix interface{}) *apiQuerierMock_listJobs_Call {
return &apiQuerierMock_listJobs_Call{Call: _e.mock.On("listJobs", prefix)}
}
func (_c *apiQuerierMock_listJobs_Call) Run(run func(prefix string)) *apiQuerierMock_listJobs_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *apiQuerierMock_listJobs_Call) Return(allocationListStub []*api.JobListStub, err error) *apiQuerierMock_listJobs_Call {
_c.Call.Return(allocationListStub, err)
return _c
}
func (_c *apiQuerierMock_listJobs_Call) RunAndReturn(run func(string) ([]*api.JobListStub, error)) *apiQuerierMock_listJobs_Call {
_c.Call.Return(run)
return _c
}
type mockConstructorTestingTnewApiQuerierMock interface {
mock.TestingT
Cleanup(func())
}
// newApiQuerierMock creates a new instance of apiQuerierMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func newApiQuerierMock(t mockConstructorTestingTnewApiQuerierMock) *apiQuerierMock {
mock := &apiQuerierMock{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@ -1,4 +1,4 @@
// Code generated by mockery v2.14.0. DO NOT EDIT. // Code generated by mockery v2.21.0. DO NOT EDIT.
package nomad package nomad
@ -20,6 +20,14 @@ type ExecutorAPIMock struct {
mock.Mock mock.Mock
} }
type ExecutorAPIMock_Expecter struct {
mock *mock.Mock
}
func (_m *ExecutorAPIMock) EXPECT() *ExecutorAPIMock_Expecter {
return &ExecutorAPIMock_Expecter{mock: &_m.Mock}
}
// DeleteJob provides a mock function with given fields: jobID // DeleteJob provides a mock function with given fields: jobID
func (_m *ExecutorAPIMock) DeleteJob(jobID string) error { func (_m *ExecutorAPIMock) DeleteJob(jobID string) error {
ret := _m.Called(jobID) ret := _m.Called(jobID)
@ -34,11 +42,43 @@ func (_m *ExecutorAPIMock) DeleteJob(jobID string) error {
return r0 return r0
} }
// ExecutorAPIMock_DeleteJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteJob'
type ExecutorAPIMock_DeleteJob_Call struct {
*mock.Call
}
// DeleteJob is a helper method to define mock.On call
// - jobID string
func (_e *ExecutorAPIMock_Expecter) DeleteJob(jobID interface{}) *ExecutorAPIMock_DeleteJob_Call {
return &ExecutorAPIMock_DeleteJob_Call{Call: _e.mock.On("DeleteJob", jobID)}
}
func (_c *ExecutorAPIMock_DeleteJob_Call) Run(run func(jobID string)) *ExecutorAPIMock_DeleteJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_DeleteJob_Call) Return(err error) *ExecutorAPIMock_DeleteJob_Call {
_c.Call.Return(err)
return _c
}
func (_c *ExecutorAPIMock_DeleteJob_Call) RunAndReturn(run func(string) error) *ExecutorAPIMock_DeleteJob_Call {
_c.Call.Return(run)
return _c
}
// EventStream provides a mock function with given fields: ctx // EventStream provides a mock function with given fields: ctx
func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events, error) { func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events, error) {
ret := _m.Called(ctx) ret := _m.Called(ctx)
var r0 <-chan *api.Events var r0 <-chan *api.Events
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (<-chan *api.Events, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) <-chan *api.Events); ok { if rf, ok := ret.Get(0).(func(context.Context) <-chan *api.Events); ok {
r0 = rf(ctx) r0 = rf(ctx)
} else { } else {
@ -47,7 +87,6 @@ func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events,
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok { if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx) r1 = rf(ctx)
} else { } else {
@ -57,19 +96,50 @@ func (_m *ExecutorAPIMock) EventStream(ctx context.Context) (<-chan *api.Events,
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_EventStream_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EventStream'
type ExecutorAPIMock_EventStream_Call struct {
*mock.Call
}
// EventStream is a helper method to define mock.On call
// - ctx context.Context
func (_e *ExecutorAPIMock_Expecter) EventStream(ctx interface{}) *ExecutorAPIMock_EventStream_Call {
return &ExecutorAPIMock_EventStream_Call{Call: _e.mock.On("EventStream", ctx)}
}
func (_c *ExecutorAPIMock_EventStream_Call) Run(run func(ctx context.Context)) *ExecutorAPIMock_EventStream_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *ExecutorAPIMock_EventStream_Call) Return(_a0 <-chan *api.Events, _a1 error) *ExecutorAPIMock_EventStream_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_EventStream_Call) RunAndReturn(run func(context.Context) (<-chan *api.Events, error)) *ExecutorAPIMock_EventStream_Call {
_c.Call.Return(run)
return _c
}
// Execute provides a mock function with given fields: jobID, 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(jobID 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(jobID, ctx, command, tty, stdin, stdout, stderr) ret := _m.Called(jobID, ctx, command, tty, stdin, stdout, stderr)
var r0 int var r0 int
if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) int); ok { var r1 error
if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)); ok {
return rf(jobID, ctx, command, tty, stdin, stdout, stderr)
}
if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) int); ok {
r0 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) r0 = rf(jobID, ctx, command, tty, stdin, stdout, stderr)
} else { } else {
r0 = ret.Get(0).(int) 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 {
if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, io.Reader, io.Writer, io.Writer) error); ok {
r1 = rf(jobID, ctx, command, tty, stdin, stdout, stderr) r1 = rf(jobID, ctx, command, tty, stdin, stdout, stderr)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
@ -78,20 +148,57 @@ func (_m *ExecutorAPIMock) Execute(jobID string, ctx context.Context, command []
return r0, r1 return r0, r1
} }
// ExecuteCommand provides a mock function with given fields: allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr // ExecutorAPIMock_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute'
func (_m *ExecutorAPIMock) ExecuteCommand(allocationID string, ctx context.Context, command []string, tty bool, privilegedExecution bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) { type ExecutorAPIMock_Execute_Call struct {
ret := _m.Called(allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) *mock.Call
}
// Execute is a helper method to define mock.On call
// - jobID string
// - ctx context.Context
// - command string
// - tty bool
// - stdin io.Reader
// - stdout io.Writer
// - stderr io.Writer
func (_e *ExecutorAPIMock_Expecter) Execute(jobID interface{}, ctx interface{}, command interface{}, tty interface{}, stdin interface{}, stdout interface{}, stderr interface{}) *ExecutorAPIMock_Execute_Call {
return &ExecutorAPIMock_Execute_Call{Call: _e.mock.On("Execute", jobID, ctx, command, tty, stdin, stdout, stderr)}
}
func (_c *ExecutorAPIMock_Execute_Call) Run(run func(jobID string, ctx context.Context, command string, tty bool, stdin io.Reader, stdout io.Writer, stderr io.Writer)) *ExecutorAPIMock_Execute_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(context.Context), args[2].(string), args[3].(bool), args[4].(io.Reader), args[5].(io.Writer), args[6].(io.Writer))
})
return _c
}
func (_c *ExecutorAPIMock_Execute_Call) Return(_a0 int, _a1 error) *ExecutorAPIMock_Execute_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_Execute_Call) RunAndReturn(run func(string, context.Context, string, bool, io.Reader, io.Writer, io.Writer) (int, error)) *ExecutorAPIMock_Execute_Call {
_c.Call.Return(run)
return _c
}
// ExecuteCommand provides a mock function with given fields: jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr
func (_m *ExecutorAPIMock) ExecuteCommand(jobID string, ctx context.Context, command string, tty bool, privilegedExecution bool, stdin io.Reader, stdout io.Writer, stderr io.Writer) (int, error) {
ret := _m.Called(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)
var r0 int var r0 int
if rf, ok := ret.Get(0).(func(string, context.Context, []string, bool, bool, io.Reader, io.Writer, io.Writer) int); ok { var r1 error
r0 = rf(allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr) if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) (int, error)); ok {
return rf(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)
}
if rf, ok := ret.Get(0).(func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) int); ok {
r0 = rf(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)
} else { } else {
r0 = ret.Get(0).(int) r0 = ret.Get(0).(int)
} }
var r1 error if rf, ok := ret.Get(1).(func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) error); ok {
if rf, ok := ret.Get(1).(func(string, context.Context, []string, bool, bool, io.Reader, io.Writer, io.Writer) error); ok { r1 = rf(jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)
r1 = rf(allocationID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)
} }
@ -99,18 +206,56 @@ func (_m *ExecutorAPIMock) ExecuteCommand(allocationID string, ctx context.Conte
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_ExecuteCommand_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExecuteCommand'
type ExecutorAPIMock_ExecuteCommand_Call struct {
*mock.Call
}
// ExecuteCommand is a helper method to define mock.On call
// - jobID string
// - ctx context.Context
// - command string
// - tty bool
// - privilegedExecution bool
// - stdin io.Reader
// - stdout io.Writer
// - stderr io.Writer
func (_e *ExecutorAPIMock_Expecter) ExecuteCommand(jobID interface{}, ctx interface{}, command interface{}, tty interface{}, privilegedExecution interface{}, stdin interface{}, stdout interface{}, stderr interface{}) *ExecutorAPIMock_ExecuteCommand_Call {
return &ExecutorAPIMock_ExecuteCommand_Call{Call: _e.mock.On("ExecuteCommand", jobID, ctx, command, tty, privilegedExecution, stdin, stdout, stderr)}
}
func (_c *ExecutorAPIMock_ExecuteCommand_Call) Run(run func(jobID string, ctx context.Context, command string, tty bool, privilegedExecution bool, stdin io.Reader, stdout io.Writer, stderr io.Writer)) *ExecutorAPIMock_ExecuteCommand_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(context.Context), args[2].(string), args[3].(bool), args[4].(bool), args[5].(io.Reader), args[6].(io.Writer), args[7].(io.Writer))
})
return _c
}
func (_c *ExecutorAPIMock_ExecuteCommand_Call) Return(_a0 int, _a1 error) *ExecutorAPIMock_ExecuteCommand_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_ExecuteCommand_Call) RunAndReturn(run func(string, context.Context, string, bool, bool, io.Reader, io.Writer, io.Writer) (int, error)) *ExecutorAPIMock_ExecuteCommand_Call {
_c.Call.Return(run)
return _c
}
// 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)
var r0 uint var r0 uint
var r1 error
if rf, ok := ret.Get(0).(func(string) (uint, error)); ok {
return rf(jobID)
}
if rf, ok := ret.Get(0).(func(string) uint); ok { if rf, ok := ret.Get(0).(func(string) uint); ok {
r0 = rf(jobID) r0 = rf(jobID)
} else { } else {
r0 = ret.Get(0).(uint) r0 = ret.Get(0).(uint)
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobID) r1 = rf(jobID)
} else { } else {
@ -120,11 +265,43 @@ func (_m *ExecutorAPIMock) JobScale(jobID string) (uint, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_JobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'JobScale'
type ExecutorAPIMock_JobScale_Call struct {
*mock.Call
}
// JobScale is a helper method to define mock.On call
// - jobID string
func (_e *ExecutorAPIMock_Expecter) JobScale(jobID interface{}) *ExecutorAPIMock_JobScale_Call {
return &ExecutorAPIMock_JobScale_Call{Call: _e.mock.On("JobScale", jobID)}
}
func (_c *ExecutorAPIMock_JobScale_Call) Run(run func(jobID string)) *ExecutorAPIMock_JobScale_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_JobScale_Call) Return(jobScale uint, err error) *ExecutorAPIMock_JobScale_Call {
_c.Call.Return(jobScale, err)
return _c
}
func (_c *ExecutorAPIMock_JobScale_Call) RunAndReturn(run func(string) (uint, error)) *ExecutorAPIMock_JobScale_Call {
_c.Call.Return(run)
return _c
}
// LoadEnvironmentJobs provides a mock function with given fields: // LoadEnvironmentJobs provides a mock function with given fields:
func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) { func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) {
ret := _m.Called() ret := _m.Called()
var r0 []*api.Job var r0 []*api.Job
var r1 error
if rf, ok := ret.Get(0).(func() ([]*api.Job, error)); ok {
return rf()
}
if rf, ok := ret.Get(0).(func() []*api.Job); ok { if rf, ok := ret.Get(0).(func() []*api.Job); ok {
r0 = rf() r0 = rf()
} else { } else {
@ -133,7 +310,6 @@ func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func() error); ok { if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf() r1 = rf()
} else { } else {
@ -143,11 +319,42 @@ func (_m *ExecutorAPIMock) LoadEnvironmentJobs() ([]*api.Job, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_LoadEnvironmentJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadEnvironmentJobs'
type ExecutorAPIMock_LoadEnvironmentJobs_Call struct {
*mock.Call
}
// LoadEnvironmentJobs is a helper method to define mock.On call
func (_e *ExecutorAPIMock_Expecter) LoadEnvironmentJobs() *ExecutorAPIMock_LoadEnvironmentJobs_Call {
return &ExecutorAPIMock_LoadEnvironmentJobs_Call{Call: _e.mock.On("LoadEnvironmentJobs")}
}
func (_c *ExecutorAPIMock_LoadEnvironmentJobs_Call) Run(run func()) *ExecutorAPIMock_LoadEnvironmentJobs_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *ExecutorAPIMock_LoadEnvironmentJobs_Call) Return(_a0 []*api.Job, _a1 error) *ExecutorAPIMock_LoadEnvironmentJobs_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_LoadEnvironmentJobs_Call) RunAndReturn(run func() ([]*api.Job, error)) *ExecutorAPIMock_LoadEnvironmentJobs_Call {
_c.Call.Return(run)
return _c
}
// 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()
var r0 []*api.JobListStub var r0 []*api.JobListStub
var r1 error
if rf, ok := ret.Get(0).(func() ([]*api.JobListStub, error)); ok {
return rf()
}
if rf, ok := ret.Get(0).(func() []*api.JobListStub); ok { if rf, ok := ret.Get(0).(func() []*api.JobListStub); ok {
r0 = rf() r0 = rf()
} else { } else {
@ -156,7 +363,6 @@ func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func() error); ok { if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf() r1 = rf()
} else { } else {
@ -166,11 +372,42 @@ func (_m *ExecutorAPIMock) LoadJobList() ([]*api.JobListStub, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_LoadJobList_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadJobList'
type ExecutorAPIMock_LoadJobList_Call struct {
*mock.Call
}
// LoadJobList is a helper method to define mock.On call
func (_e *ExecutorAPIMock_Expecter) LoadJobList() *ExecutorAPIMock_LoadJobList_Call {
return &ExecutorAPIMock_LoadJobList_Call{Call: _e.mock.On("LoadJobList")}
}
func (_c *ExecutorAPIMock_LoadJobList_Call) Run(run func()) *ExecutorAPIMock_LoadJobList_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *ExecutorAPIMock_LoadJobList_Call) Return(list []*api.JobListStub, err error) *ExecutorAPIMock_LoadJobList_Call {
_c.Call.Return(list, err)
return _c
}
func (_c *ExecutorAPIMock_LoadJobList_Call) RunAndReturn(run func() ([]*api.JobListStub, error)) *ExecutorAPIMock_LoadJobList_Call {
_c.Call.Return(run)
return _c
}
// LoadRunnerIDs provides a mock function with given fields: prefix // LoadRunnerIDs provides a mock function with given fields: prefix
func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) { func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) {
ret := _m.Called(prefix) ret := _m.Called(prefix)
var r0 []string var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok {
return rf(prefix)
}
if rf, ok := ret.Get(0).(func(string) []string); ok { if rf, ok := ret.Get(0).(func(string) []string); ok {
r0 = rf(prefix) r0 = rf(prefix)
} else { } else {
@ -179,7 +416,6 @@ func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prefix) r1 = rf(prefix)
} else { } else {
@ -189,11 +425,43 @@ func (_m *ExecutorAPIMock) LoadRunnerIDs(prefix string) ([]string, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_LoadRunnerIDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadRunnerIDs'
type ExecutorAPIMock_LoadRunnerIDs_Call struct {
*mock.Call
}
// LoadRunnerIDs is a helper method to define mock.On call
// - prefix string
func (_e *ExecutorAPIMock_Expecter) LoadRunnerIDs(prefix interface{}) *ExecutorAPIMock_LoadRunnerIDs_Call {
return &ExecutorAPIMock_LoadRunnerIDs_Call{Call: _e.mock.On("LoadRunnerIDs", prefix)}
}
func (_c *ExecutorAPIMock_LoadRunnerIDs_Call) Run(run func(prefix string)) *ExecutorAPIMock_LoadRunnerIDs_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_LoadRunnerIDs_Call) Return(runnerIds []string, err error) *ExecutorAPIMock_LoadRunnerIDs_Call {
_c.Call.Return(runnerIds, err)
return _c
}
func (_c *ExecutorAPIMock_LoadRunnerIDs_Call) RunAndReturn(run func(string) ([]string, error)) *ExecutorAPIMock_LoadRunnerIDs_Call {
_c.Call.Return(run)
return _c
}
// LoadRunnerJobs provides a mock function with given fields: environmentID // LoadRunnerJobs provides a mock function with given fields: environmentID
func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*api.Job, error) { func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*api.Job, error) {
ret := _m.Called(environmentID) ret := _m.Called(environmentID)
var r0 []*api.Job var r0 []*api.Job
var r1 error
if rf, ok := ret.Get(0).(func(dto.EnvironmentID) ([]*api.Job, error)); ok {
return rf(environmentID)
}
if rf, ok := ret.Get(0).(func(dto.EnvironmentID) []*api.Job); ok { if rf, ok := ret.Get(0).(func(dto.EnvironmentID) []*api.Job); ok {
r0 = rf(environmentID) r0 = rf(environmentID)
} else { } else {
@ -202,7 +470,6 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*a
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(dto.EnvironmentID) error); ok { if rf, ok := ret.Get(1).(func(dto.EnvironmentID) error); ok {
r1 = rf(environmentID) r1 = rf(environmentID)
} else { } else {
@ -212,11 +479,43 @@ func (_m *ExecutorAPIMock) LoadRunnerJobs(environmentID dto.EnvironmentID) ([]*a
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_LoadRunnerJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadRunnerJobs'
type ExecutorAPIMock_LoadRunnerJobs_Call struct {
*mock.Call
}
// LoadRunnerJobs is a helper method to define mock.On call
// - environmentID dto.EnvironmentID
func (_e *ExecutorAPIMock_Expecter) LoadRunnerJobs(environmentID interface{}) *ExecutorAPIMock_LoadRunnerJobs_Call {
return &ExecutorAPIMock_LoadRunnerJobs_Call{Call: _e.mock.On("LoadRunnerJobs", environmentID)}
}
func (_c *ExecutorAPIMock_LoadRunnerJobs_Call) Run(run func(environmentID dto.EnvironmentID)) *ExecutorAPIMock_LoadRunnerJobs_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(dto.EnvironmentID))
})
return _c
}
func (_c *ExecutorAPIMock_LoadRunnerJobs_Call) Return(_a0 []*api.Job, _a1 error) *ExecutorAPIMock_LoadRunnerJobs_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_LoadRunnerJobs_Call) RunAndReturn(run func(dto.EnvironmentID) ([]*api.Job, error)) *ExecutorAPIMock_LoadRunnerJobs_Call {
_c.Call.Return(run)
return _c
}
// LoadRunnerPortMappings provides a mock function with given fields: runnerID // LoadRunnerPortMappings provides a mock function with given fields: runnerID
func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMapping, error) { func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMapping, error) {
ret := _m.Called(runnerID) ret := _m.Called(runnerID)
var r0 []api.PortMapping var r0 []api.PortMapping
var r1 error
if rf, ok := ret.Get(0).(func(string) ([]api.PortMapping, error)); ok {
return rf(runnerID)
}
if rf, ok := ret.Get(0).(func(string) []api.PortMapping); ok { if rf, ok := ret.Get(0).(func(string) []api.PortMapping); ok {
r0 = rf(runnerID) r0 = rf(runnerID)
} else { } else {
@ -225,7 +524,6 @@ func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMa
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(runnerID) r1 = rf(runnerID)
} else { } else {
@ -235,6 +533,34 @@ func (_m *ExecutorAPIMock) LoadRunnerPortMappings(runnerID string) ([]api.PortMa
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_LoadRunnerPortMappings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadRunnerPortMappings'
type ExecutorAPIMock_LoadRunnerPortMappings_Call struct {
*mock.Call
}
// LoadRunnerPortMappings is a helper method to define mock.On call
// - runnerID string
func (_e *ExecutorAPIMock_Expecter) LoadRunnerPortMappings(runnerID interface{}) *ExecutorAPIMock_LoadRunnerPortMappings_Call {
return &ExecutorAPIMock_LoadRunnerPortMappings_Call{Call: _e.mock.On("LoadRunnerPortMappings", runnerID)}
}
func (_c *ExecutorAPIMock_LoadRunnerPortMappings_Call) Run(run func(runnerID string)) *ExecutorAPIMock_LoadRunnerPortMappings_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_LoadRunnerPortMappings_Call) Return(_a0 []api.PortMapping, _a1 error) *ExecutorAPIMock_LoadRunnerPortMappings_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_LoadRunnerPortMappings_Call) RunAndReturn(run func(string) ([]api.PortMapping, error)) *ExecutorAPIMock_LoadRunnerPortMappings_Call {
_c.Call.Return(run)
return _c
}
// MarkRunnerAsUsed provides a mock function with given fields: runnerID, duration // MarkRunnerAsUsed provides a mock function with given fields: runnerID, duration
func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string, duration int) error { func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string, duration int) error {
ret := _m.Called(runnerID, duration) ret := _m.Called(runnerID, duration)
@ -249,6 +575,35 @@ func (_m *ExecutorAPIMock) MarkRunnerAsUsed(runnerID string, duration int) error
return r0 return r0
} }
// ExecutorAPIMock_MarkRunnerAsUsed_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MarkRunnerAsUsed'
type ExecutorAPIMock_MarkRunnerAsUsed_Call struct {
*mock.Call
}
// MarkRunnerAsUsed is a helper method to define mock.On call
// - runnerID string
// - duration int
func (_e *ExecutorAPIMock_Expecter) MarkRunnerAsUsed(runnerID interface{}, duration interface{}) *ExecutorAPIMock_MarkRunnerAsUsed_Call {
return &ExecutorAPIMock_MarkRunnerAsUsed_Call{Call: _e.mock.On("MarkRunnerAsUsed", runnerID, duration)}
}
func (_c *ExecutorAPIMock_MarkRunnerAsUsed_Call) Run(run func(runnerID string, duration int)) *ExecutorAPIMock_MarkRunnerAsUsed_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(int))
})
return _c
}
func (_c *ExecutorAPIMock_MarkRunnerAsUsed_Call) Return(_a0 error) *ExecutorAPIMock_MarkRunnerAsUsed_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *ExecutorAPIMock_MarkRunnerAsUsed_Call) RunAndReturn(run func(string, int) error) *ExecutorAPIMock_MarkRunnerAsUsed_Call {
_c.Call.Return(run)
return _c
}
// MonitorEvaluation provides a mock function with given fields: evaluationID, ctx // MonitorEvaluation provides a mock function with given fields: evaluationID, ctx
func (_m *ExecutorAPIMock) MonitorEvaluation(evaluationID string, ctx context.Context) error { func (_m *ExecutorAPIMock) MonitorEvaluation(evaluationID string, ctx context.Context) error {
ret := _m.Called(evaluationID, ctx) ret := _m.Called(evaluationID, ctx)
@ -263,18 +618,50 @@ func (_m *ExecutorAPIMock) MonitorEvaluation(evaluationID string, ctx context.Co
return r0 return r0
} }
// ExecutorAPIMock_MonitorEvaluation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MonitorEvaluation'
type ExecutorAPIMock_MonitorEvaluation_Call struct {
*mock.Call
}
// MonitorEvaluation is a helper method to define mock.On call
// - evaluationID string
// - ctx context.Context
func (_e *ExecutorAPIMock_Expecter) MonitorEvaluation(evaluationID interface{}, ctx interface{}) *ExecutorAPIMock_MonitorEvaluation_Call {
return &ExecutorAPIMock_MonitorEvaluation_Call{Call: _e.mock.On("MonitorEvaluation", evaluationID, ctx)}
}
func (_c *ExecutorAPIMock_MonitorEvaluation_Call) Run(run func(evaluationID string, ctx context.Context)) *ExecutorAPIMock_MonitorEvaluation_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(context.Context))
})
return _c
}
func (_c *ExecutorAPIMock_MonitorEvaluation_Call) Return(_a0 error) *ExecutorAPIMock_MonitorEvaluation_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *ExecutorAPIMock_MonitorEvaluation_Call) RunAndReturn(run func(string, context.Context) error) *ExecutorAPIMock_MonitorEvaluation_Call {
_c.Call.Return(run)
return _c
}
// RegisterNomadJob provides a mock function with given fields: job // RegisterNomadJob provides a mock function with given fields: job
func (_m *ExecutorAPIMock) RegisterNomadJob(job *api.Job) (string, error) { func (_m *ExecutorAPIMock) RegisterNomadJob(job *api.Job) (string, error) {
ret := _m.Called(job) ret := _m.Called(job)
var r0 string var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(*api.Job) (string, error)); ok {
return rf(job)
}
if rf, ok := ret.Get(0).(func(*api.Job) string); ok { if rf, ok := ret.Get(0).(func(*api.Job) string); ok {
r0 = rf(job) r0 = rf(job)
} else { } else {
r0 = ret.Get(0).(string) r0 = ret.Get(0).(string)
} }
var r1 error
if rf, ok := ret.Get(1).(func(*api.Job) error); ok { if rf, ok := ret.Get(1).(func(*api.Job) error); ok {
r1 = rf(job) r1 = rf(job)
} else { } else {
@ -284,6 +671,34 @@ func (_m *ExecutorAPIMock) RegisterNomadJob(job *api.Job) (string, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_RegisterNomadJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterNomadJob'
type ExecutorAPIMock_RegisterNomadJob_Call struct {
*mock.Call
}
// RegisterNomadJob is a helper method to define mock.On call
// - job *api.Job
func (_e *ExecutorAPIMock_Expecter) RegisterNomadJob(job interface{}) *ExecutorAPIMock_RegisterNomadJob_Call {
return &ExecutorAPIMock_RegisterNomadJob_Call{Call: _e.mock.On("RegisterNomadJob", job)}
}
func (_c *ExecutorAPIMock_RegisterNomadJob_Call) Run(run func(job *api.Job)) *ExecutorAPIMock_RegisterNomadJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*api.Job))
})
return _c
}
func (_c *ExecutorAPIMock_RegisterNomadJob_Call) Return(_a0 string, _a1 error) *ExecutorAPIMock_RegisterNomadJob_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_RegisterNomadJob_Call) RunAndReturn(run func(*api.Job) (string, error)) *ExecutorAPIMock_RegisterNomadJob_Call {
_c.Call.Return(run)
return _c
}
// RegisterRunnerJob provides a mock function with given fields: template // RegisterRunnerJob provides a mock function with given fields: template
func (_m *ExecutorAPIMock) RegisterRunnerJob(template *api.Job) error { func (_m *ExecutorAPIMock) RegisterRunnerJob(template *api.Job) error {
ret := _m.Called(template) ret := _m.Called(template)
@ -298,6 +713,34 @@ func (_m *ExecutorAPIMock) RegisterRunnerJob(template *api.Job) error {
return r0 return r0
} }
// ExecutorAPIMock_RegisterRunnerJob_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterRunnerJob'
type ExecutorAPIMock_RegisterRunnerJob_Call struct {
*mock.Call
}
// RegisterRunnerJob is a helper method to define mock.On call
// - template *api.Job
func (_e *ExecutorAPIMock_Expecter) RegisterRunnerJob(template interface{}) *ExecutorAPIMock_RegisterRunnerJob_Call {
return &ExecutorAPIMock_RegisterRunnerJob_Call{Call: _e.mock.On("RegisterRunnerJob", template)}
}
func (_c *ExecutorAPIMock_RegisterRunnerJob_Call) Run(run func(template *api.Job)) *ExecutorAPIMock_RegisterRunnerJob_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*api.Job))
})
return _c
}
func (_c *ExecutorAPIMock_RegisterRunnerJob_Call) Return(_a0 error) *ExecutorAPIMock_RegisterRunnerJob_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *ExecutorAPIMock_RegisterRunnerJob_Call) RunAndReturn(run func(*api.Job) error) *ExecutorAPIMock_RegisterRunnerJob_Call {
_c.Call.Return(run)
return _c
}
// SetJobScale provides a mock function with given fields: jobID, count, reason // SetJobScale provides a mock function with given fields: jobID, count, reason
func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string) error { func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string) error {
ret := _m.Called(jobID, count, reason) ret := _m.Called(jobID, count, reason)
@ -312,6 +755,36 @@ func (_m *ExecutorAPIMock) SetJobScale(jobID string, count uint, reason string)
return r0 return r0
} }
// ExecutorAPIMock_SetJobScale_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetJobScale'
type ExecutorAPIMock_SetJobScale_Call struct {
*mock.Call
}
// SetJobScale is a helper method to define mock.On call
// - jobID string
// - count uint
// - reason string
func (_e *ExecutorAPIMock_Expecter) SetJobScale(jobID interface{}, count interface{}, reason interface{}) *ExecutorAPIMock_SetJobScale_Call {
return &ExecutorAPIMock_SetJobScale_Call{Call: _e.mock.On("SetJobScale", jobID, count, reason)}
}
func (_c *ExecutorAPIMock_SetJobScale_Call) Run(run func(jobID string, count uint, reason string)) *ExecutorAPIMock_SetJobScale_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(uint), args[2].(string))
})
return _c
}
func (_c *ExecutorAPIMock_SetJobScale_Call) Return(err error) *ExecutorAPIMock_SetJobScale_Call {
_c.Call.Return(err)
return _c
}
func (_c *ExecutorAPIMock_SetJobScale_Call) RunAndReturn(run func(string, uint, string) error) *ExecutorAPIMock_SetJobScale_Call {
_c.Call.Return(run)
return _c
}
// WatchEventStream provides a mock function with given fields: ctx, callbacks // WatchEventStream provides a mock function with given fields: ctx, callbacks
func (_m *ExecutorAPIMock) WatchEventStream(ctx context.Context, callbacks *AllocationProcessoring) error { func (_m *ExecutorAPIMock) WatchEventStream(ctx context.Context, callbacks *AllocationProcessoring) error {
ret := _m.Called(ctx, callbacks) ret := _m.Called(ctx, callbacks)
@ -326,11 +799,44 @@ func (_m *ExecutorAPIMock) WatchEventStream(ctx context.Context, callbacks *Allo
return r0 return r0
} }
// ExecutorAPIMock_WatchEventStream_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WatchEventStream'
type ExecutorAPIMock_WatchEventStream_Call struct {
*mock.Call
}
// WatchEventStream is a helper method to define mock.On call
// - ctx context.Context
// - callbacks *AllocationProcessoring
func (_e *ExecutorAPIMock_Expecter) WatchEventStream(ctx interface{}, callbacks interface{}) *ExecutorAPIMock_WatchEventStream_Call {
return &ExecutorAPIMock_WatchEventStream_Call{Call: _e.mock.On("WatchEventStream", ctx, callbacks)}
}
func (_c *ExecutorAPIMock_WatchEventStream_Call) Run(run func(ctx context.Context, callbacks *AllocationProcessoring)) *ExecutorAPIMock_WatchEventStream_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*AllocationProcessoring))
})
return _c
}
func (_c *ExecutorAPIMock_WatchEventStream_Call) Return(_a0 error) *ExecutorAPIMock_WatchEventStream_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *ExecutorAPIMock_WatchEventStream_Call) RunAndReturn(run func(context.Context, *AllocationProcessoring) error) *ExecutorAPIMock_WatchEventStream_Call {
_c.Call.Return(run)
return _c
}
// allocation provides a mock function with given fields: jobID // allocation provides a mock function with given fields: jobID
func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) { func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) {
ret := _m.Called(jobID) ret := _m.Called(jobID)
var r0 *api.Allocation var r0 *api.Allocation
var r1 error
if rf, ok := ret.Get(0).(func(string) (*api.Allocation, error)); ok {
return rf(jobID)
}
if rf, ok := ret.Get(0).(func(string) *api.Allocation); ok { if rf, ok := ret.Get(0).(func(string) *api.Allocation); ok {
r0 = rf(jobID) r0 = rf(jobID)
} else { } else {
@ -339,7 +845,6 @@ func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobID) r1 = rf(jobID)
} else { } else {
@ -349,6 +854,34 @@ func (_m *ExecutorAPIMock) allocation(jobID string) (*api.Allocation, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_allocation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'allocation'
type ExecutorAPIMock_allocation_Call struct {
*mock.Call
}
// allocation is a helper method to define mock.On call
// - jobID string
func (_e *ExecutorAPIMock_Expecter) allocation(jobID interface{}) *ExecutorAPIMock_allocation_Call {
return &ExecutorAPIMock_allocation_Call{Call: _e.mock.On("allocation", jobID)}
}
func (_c *ExecutorAPIMock_allocation_Call) Run(run func(jobID string)) *ExecutorAPIMock_allocation_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_allocation_Call) Return(_a0 *api.Allocation, _a1 error) *ExecutorAPIMock_allocation_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *ExecutorAPIMock_allocation_Call) RunAndReturn(run func(string) (*api.Allocation, error)) *ExecutorAPIMock_allocation_Call {
_c.Call.Return(run)
return _c
}
// init provides a mock function with given fields: nomadConfig // init provides a mock function with given fields: nomadConfig
func (_m *ExecutorAPIMock) init(nomadConfig *config.Nomad) error { func (_m *ExecutorAPIMock) init(nomadConfig *config.Nomad) error {
ret := _m.Called(nomadConfig) ret := _m.Called(nomadConfig)
@ -363,11 +896,43 @@ func (_m *ExecutorAPIMock) init(nomadConfig *config.Nomad) error {
return r0 return r0
} }
// ExecutorAPIMock_init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'init'
type ExecutorAPIMock_init_Call struct {
*mock.Call
}
// init is a helper method to define mock.On call
// - nomadConfig *config.Nomad
func (_e *ExecutorAPIMock_Expecter) init(nomadConfig interface{}) *ExecutorAPIMock_init_Call {
return &ExecutorAPIMock_init_Call{Call: _e.mock.On("init", nomadConfig)}
}
func (_c *ExecutorAPIMock_init_Call) Run(run func(nomadConfig *config.Nomad)) *ExecutorAPIMock_init_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*config.Nomad))
})
return _c
}
func (_c *ExecutorAPIMock_init_Call) Return(err error) *ExecutorAPIMock_init_Call {
_c.Call.Return(err)
return _c
}
func (_c *ExecutorAPIMock_init_Call) RunAndReturn(run func(*config.Nomad) error) *ExecutorAPIMock_init_Call {
_c.Call.Return(run)
return _c
}
// job provides a mock function with given fields: jobID // job provides a mock function with given fields: jobID
func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) { func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) {
ret := _m.Called(jobID) ret := _m.Called(jobID)
var r0 *api.Job var r0 *api.Job
var r1 error
if rf, ok := ret.Get(0).(func(string) (*api.Job, error)); ok {
return rf(jobID)
}
if rf, ok := ret.Get(0).(func(string) *api.Job); ok { if rf, ok := ret.Get(0).(func(string) *api.Job); ok {
r0 = rf(jobID) r0 = rf(jobID)
} else { } else {
@ -376,7 +941,6 @@ func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(jobID) r1 = rf(jobID)
} else { } else {
@ -386,11 +950,43 @@ func (_m *ExecutorAPIMock) job(jobID string) (*api.Job, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_job_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'job'
type ExecutorAPIMock_job_Call struct {
*mock.Call
}
// job is a helper method to define mock.On call
// - jobID string
func (_e *ExecutorAPIMock_Expecter) job(jobID interface{}) *ExecutorAPIMock_job_Call {
return &ExecutorAPIMock_job_Call{Call: _e.mock.On("job", jobID)}
}
func (_c *ExecutorAPIMock_job_Call) Run(run func(jobID string)) *ExecutorAPIMock_job_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_job_Call) Return(job *api.Job, err error) *ExecutorAPIMock_job_Call {
_c.Call.Return(job, err)
return _c
}
func (_c *ExecutorAPIMock_job_Call) RunAndReturn(run func(string) (*api.Job, error)) *ExecutorAPIMock_job_Call {
_c.Call.Return(run)
return _c
}
// listJobs provides a mock function with given fields: prefix // listJobs provides a mock function with given fields: prefix
func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) { func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) {
ret := _m.Called(prefix) ret := _m.Called(prefix)
var r0 []*api.JobListStub var r0 []*api.JobListStub
var r1 error
if rf, ok := ret.Get(0).(func(string) ([]*api.JobListStub, error)); ok {
return rf(prefix)
}
if rf, ok := ret.Get(0).(func(string) []*api.JobListStub); ok { if rf, ok := ret.Get(0).(func(string) []*api.JobListStub); ok {
r0 = rf(prefix) r0 = rf(prefix)
} else { } else {
@ -399,7 +995,6 @@ func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) {
} }
} }
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok { if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prefix) r1 = rf(prefix)
} else { } else {
@ -409,6 +1004,34 @@ func (_m *ExecutorAPIMock) listJobs(prefix string) ([]*api.JobListStub, error) {
return r0, r1 return r0, r1
} }
// ExecutorAPIMock_listJobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'listJobs'
type ExecutorAPIMock_listJobs_Call struct {
*mock.Call
}
// listJobs is a helper method to define mock.On call
// - prefix string
func (_e *ExecutorAPIMock_Expecter) listJobs(prefix interface{}) *ExecutorAPIMock_listJobs_Call {
return &ExecutorAPIMock_listJobs_Call{Call: _e.mock.On("listJobs", prefix)}
}
func (_c *ExecutorAPIMock_listJobs_Call) Run(run func(prefix string)) *ExecutorAPIMock_listJobs_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *ExecutorAPIMock_listJobs_Call) Return(allocationListStub []*api.JobListStub, err error) *ExecutorAPIMock_listJobs_Call {
_c.Call.Return(allocationListStub, err)
return _c
}
func (_c *ExecutorAPIMock_listJobs_Call) RunAndReturn(run func(string) ([]*api.JobListStub, error)) *ExecutorAPIMock_listJobs_Call {
_c.Call.Return(run)
return _c
}
type mockConstructorTestingTNewExecutorAPIMock interface { type mockConstructorTestingTNewExecutorAPIMock interface {
mock.TestingT mock.TestingT
Cleanup(func()) Cleanup(func())

View File

@ -72,7 +72,8 @@ type ExecutorAPI interface {
// It writes the output of the command to stdout/stderr and reads input from stdin. // It writes the output of the command to stdout/stderr and reads input from stdin.
// If tty is true, the command will run with a tty. // If tty is true, the command will run with a tty.
// Iff privilegedExecution is true, the command will be executed privileged. // Iff privilegedExecution is true, the command will be executed privileged.
ExecuteCommand(jobID string, ctx context.Context, command []string, tty bool, privilegedExecution bool, // The command is passed in the shell form (not the exec array form) and will be executed in a shell.
ExecuteCommand(jobID string, ctx context.Context, command string, tty bool, privilegedExecution bool,
stdin io.Reader, stdout, stderr io.Writer) (int, error) stdin io.Reader, stdout, stderr io.Writer) (int, error)
// MarkRunnerAsUsed marks the runner with the given ID as used. It also stores the timeout duration in the metadata. // MarkRunnerAsUsed marks the runner with the given ID as used. It also stores the timeout duration in the metadata.
@ -389,10 +390,8 @@ func (a *APIClient) LoadEnvironmentJobs() ([]*nomadApi.Job, error) {
// If tty is true, Nomad would normally write stdout and stderr of the command // If tty is true, Nomad would normally write stdout and stderr of the command
// both on the stdout stream. However, if the InteractiveStderr server config option is true, // both on the stdout stream. However, if the InteractiveStderr server config option is true,
// we make sure that stdout and stderr are split correctly. // we make sure that stdout and stderr are split correctly.
// In order for the stderr splitting to work, the command must have the structure
// []string{..., "bash", "-c", "my-command"}.
func (a *APIClient) ExecuteCommand(jobID string, func (a *APIClient) ExecuteCommand(jobID string,
ctx context.Context, command []string, tty bool, privilegedExecution bool, ctx context.Context, command string, tty bool, privilegedExecution bool,
stdin io.Reader, stdout, stderr io.Writer) (int, error) { stdin io.Reader, stdout, stderr io.Writer) (int, error) {
if tty && config.Config.Server.InteractiveStderr { if tty && config.Config.Server.InteractiveStderr {
return a.executeCommandInteractivelyWithStderr(jobID, ctx, command, privilegedExecution, stdin, stdout, stderr) return a.executeCommandInteractivelyWithStderr(jobID, ctx, command, privilegedExecution, stdin, stdout, stderr)
@ -411,7 +410,7 @@ func (a *APIClient) ExecuteCommand(jobID string,
// to be served both over stdout. This function circumvents this by creating a fifo for the stderr // to be served both over stdout. This function circumvents this by creating a fifo for the stderr
// of the command and starting a second execution that reads the stderr from that fifo. // of the command and starting a second execution that reads the stderr from that fifo.
func (a *APIClient) executeCommandInteractivelyWithStderr(allocationID string, ctx context.Context, func (a *APIClient) executeCommandInteractivelyWithStderr(allocationID string, ctx context.Context,
command []string, privilegedExecution bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) { command string, privilegedExecution bool, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
// Use current nano time to make the stderr fifo kind of unique. // Use current nano time to make the stderr fifo kind of unique.
currentNanoTime := time.Now().UnixNano() currentNanoTime := time.Now().UnixNano()
@ -461,8 +460,8 @@ const (
// stderrWrapperCommandFormat, if executed, is supposed to wait until a fifo exists (it sleeps 10ms to reduce load // stderrWrapperCommandFormat, if executed, is supposed to wait until a fifo exists (it sleeps 10ms to reduce load
// cause by busy waiting on the system). Once the fifo exists, the given command is executed and its stderr // cause by busy waiting on the system). Once the fifo exists, the given command is executed and its stderr
// redirected to the fifo. // redirected to the fifo.
// Example: "'until [ -e my.fifo ]; do sleep 0.01; done; (echo \"my.fifo exists\") 2> my.fifo'". // Example: "until [ -e my.fifo ]; do sleep 0.01; done; (echo \"my.fifo exists\") 2> my.fifo".
stderrWrapperCommandFormat = "'until [ -e %s ]; do sleep 0.01; done; (%s) 2> %s'" stderrWrapperCommandFormat = "until [ -e %s ]; do sleep 0.01; done; (%s) 2> %s"
// setUserBinaryPath is due to Poseidon requires the setuser script for Nomad environments. // setUserBinaryPath is due to Poseidon requires the setuser script for Nomad environments.
setUserBinaryPath = "/sbin/setuser" setUserBinaryPath = "/sbin/setuser"
@ -474,58 +473,61 @@ const (
UnprivilegedExecution = false UnprivilegedExecution = false
) )
func prepareCommandWithoutTTY(srcCommands []string, privilegedExecution bool) []string { func prepareCommandWithoutTTY(command string, privilegedExecution bool) string {
commands := make([]string, len(srcCommands)) // nozero The size is required for the copy. command = setInnerDebugMessages(command, false)
copy(commands, srcCommands)
commands[len(commands)-1] = setInnerDebugMessages(commands[len(commands)-1], false) command = setUserCommand(command, privilegedExecution)
commands = setUserCommand(commands, privilegedExecution) command = unsetEnvironmentVariables(command)
commands[len(commands)-1] = fmt.Sprintf("'%s'", commands[len(commands)-1]) return command
cmd := strings.Join(commands, " ")
cmd = fmt.Sprintf(unsetEnvironmentVariablesFormat, unsetEnvironmentVariablesShell, cmd)
// Debug Message
cmd = fmt.Sprintf(timeDebugMessageFormatStart, "SetUserAndUnsetEnv", cmd)
return []string{"bash", "-c", cmd}
} }
func prepareCommandTTY(srcCommands []string, currentNanoTime int64, privilegedExecution bool) []string { func prepareCommandTTY(command string, currentNanoTime int64, privilegedExecution bool) string {
commands := make([]string, len(srcCommands)) // nozero The size is required for the copy. command = setInnerDebugMessages(command, false)
copy(commands, srcCommands)
commands[len(commands)-1] = setInnerDebugMessages(commands[len(commands)-1], true) // Take the command to be executed and wrap it to redirect stderr.
commands = setUserCommand(commands, privilegedExecution)
// Take the last command which is the one to be executed and wrap it to redirect stderr.
stderrFifoPath := stderrFifo(currentNanoTime) stderrFifoPath := stderrFifo(currentNanoTime)
commands[len(commands)-1] = command = fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoPath, command, stderrFifoPath)
fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoPath, commands[len(commands)-1], stderrFifoPath)
cmd := strings.Join(commands, " ") command = setUserCommand(command, privilegedExecution)
cmd = fmt.Sprintf(unsetEnvironmentVariablesFormat, unsetEnvironmentVariablesShell, cmd) command = unsetEnvironmentVariables(command)
// Debug Message return command
cmd = fmt.Sprintf(timeDebugMessageFormatStart, "SetUserAndUnsetEnv", cmd)
return []string{"bash", "-c", cmd}
} }
func prepareCommandTTYStdErr(currentNanoTime int64, privilegedExecution bool) []string { func prepareCommandTTYStdErr(currentNanoTime int64, privilegedExecution bool) string {
stderrFifoPath := stderrFifo(currentNanoTime) stderrFifoPath := stderrFifo(currentNanoTime)
cmd := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoPath, stderrFifoPath, stderrFifoPath) command := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoPath, stderrFifoPath, stderrFifoPath)
cmd = setInnerDebugMessages(cmd, false) command = setInnerDebugMessages(command, false)
return setUserCommand([]string{"bash", "-c", cmd}, privilegedExecution) command = setUserCommand(command, privilegedExecution)
} return command
// setUserCommand prefixes the passed command with the setUser command.
// The passed command needs to be wrapped in single quotes to avoid escaping the setUser binary.
func setUserCommand(command []string, privilegedExecution bool) []string {
if privilegedExecution {
return command
} else {
return append([]string{setUserBinaryPath, setUserBinaryUser}, command...)
}
} }
func stderrFifo(id int64) string { func stderrFifo(id int64) string {
return fmt.Sprintf(stderrFifoFormat, id) return fmt.Sprintf(stderrFifoFormat, id)
} }
func unsetEnvironmentVariables(command string) string {
command = dto.WrapBashCommand(command)
command = fmt.Sprintf(unsetEnvironmentVariablesFormat, unsetEnvironmentVariablesShell, command)
// Debug Message
command = fmt.Sprintf(timeDebugMessageFormatStart, "UnsetEnv", command)
return command
}
// setUserCommand prefixes the passed command with the setUser command.
func setUserCommand(command string, privilegedExecution bool) string {
// Wrap the inner command first so that the setUserBinary applies to the whole inner command.
command = dto.WrapBashCommand(command)
if !privilegedExecution {
command = fmt.Sprintf("%s %s %s", setUserBinaryPath, setUserBinaryUser, command)
}
// Debug Message
command = fmt.Sprintf(timeDebugMessageFormatStart, "SetUser", command)
return command
}
// setInnerDebugMessages injects debug commands into the bash command. // setInnerDebugMessages injects debug commands into the bash command.
// The debug messages are parsed by the SentryDebugWriter. // The debug messages are parsed by the SentryDebugWriter.
func setInnerDebugMessages(command string, includeCommandInDescription bool) (result string) { func setInnerDebugMessages(command string, includeCommandInDescription bool) (result string) {

View File

@ -644,21 +644,19 @@ func TestExecuteCommandTestSuite(t *testing.T) {
type ExecuteCommandTestSuite struct { type ExecuteCommandTestSuite struct {
suite.Suite suite.Suite
allocationID string allocationID string
ctx context.Context ctx context.Context
testCommand string testCommand string
testCommandArray []string expectedStdout string
expectedStdout string expectedStderr string
expectedStderr string apiMock *apiQuerierMock
apiMock *apiQuerierMock nomadAPIClient APIClient
nomadAPIClient APIClient
} }
func (s *ExecuteCommandTestSuite) SetupTest() { func (s *ExecuteCommandTestSuite) SetupTest() {
s.allocationID = "test-allocation-id" s.allocationID = "test-allocation-id"
s.ctx = context.Background() s.ctx = context.Background()
s.testCommand = "echo \"do nothing\"" s.testCommand = "echo \"do nothing\""
s.testCommandArray = []string{"bash", "-c", s.testCommand}
s.expectedStdout = "stdout" s.expectedStdout = "stdout"
s.expectedStderr = "stderr" s.expectedStderr = "stderr"
s.apiMock = &apiQuerierMock{} s.apiMock = &apiQuerierMock{}
@ -673,18 +671,18 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() {
stderrExitCode := 1 stderrExitCode := 1
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
var calledStdoutCommand, calledStderrCommand []string var calledStdoutCommand, calledStderrCommand string
// mock regular call // mock regular call
call := s.mockExecute(mock.AnythingOfType("[]string"), 0, nil, func(_ mock.Arguments) {}) call := s.mockExecute(mock.AnythingOfType("string"), 0, nil, func(_ mock.Arguments) {})
call.Run(func(args mock.Arguments) { call.Run(func(args mock.Arguments) {
var ok bool var ok bool
calledCommand, ok := args.Get(2).([]string) calledCommand, ok := args.Get(2).(string)
s.Require().True(ok) s.Require().True(ok)
writer, ok := args.Get(5).(io.Writer) writer, ok := args.Get(5).(io.Writer)
s.Require().True(ok) s.Require().True(ok)
if isStderrCommand := len(calledCommand) == 5; isStderrCommand { if isStderrCommand := strings.Contains(calledCommand, "mkfifo"); isStderrCommand {
calledStderrCommand = calledCommand calledStderrCommand = calledCommand
_, err := writer.Write([]byte(s.expectedStderr)) _, err := writer.Write([]byte(s.expectedStderr))
s.Require().NoError(err) s.Require().NoError(err)
@ -697,7 +695,7 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() {
} }
}) })
exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY,
UnprivilegedExecution, nullio.Reader{}, &stdout, &stderr) UnprivilegedExecution, nullio.Reader{}, &stdout, &stderr)
s.Require().NoError(err) s.Require().NoError(err)
@ -705,18 +703,18 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() {
s.Equal(commandExitCode, exitCode) s.Equal(commandExitCode, exitCode)
s.Run("should wrap command in stderr wrapper", func() { s.Run("should wrap command in stderr wrapper", func() {
s.Require().NotNil(calledStdoutCommand) s.Require().NotEmpty(calledStdoutCommand)
stderrWrapperCommand := fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoFormat, s.testCommand, stderrFifoFormat) stderrWrapperCommand := fmt.Sprintf(stderrWrapperCommandFormat, stderrFifoFormat, s.testCommand, stderrFifoFormat)
stdoutFifoRegexp := strings.ReplaceAll(regexp.QuoteMeta(stderrWrapperCommand), "%d", "\\d*") stdoutFifoRegexp := strings.ReplaceAll(regexp.QuoteMeta(stderrWrapperCommand), "%d", "\\d*")
stdoutFifoRegexp = strings.Replace(stdoutFifoRegexp, s.testCommand, ".*", 1) stdoutFifoRegexp = strings.Replace(stdoutFifoRegexp, s.testCommand, ".*", 1)
s.Regexp(stdoutFifoRegexp, calledStdoutCommand[len(calledStdoutCommand)-1]) s.Regexp(stdoutFifoRegexp, calledStdoutCommand)
}) })
s.Run("should call correct stderr command", func() { s.Run("should call correct stderr command", func() {
s.Require().NotNil(calledStderrCommand) s.Require().NotEmpty(calledStderrCommand)
stderrFifoCommand := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoFormat, stderrFifoFormat, stderrFifoFormat) stderrFifoCommand := fmt.Sprintf(stderrFifoCommandFormat, stderrFifoFormat, stderrFifoFormat, stderrFifoFormat)
stderrFifoRegexp := strings.ReplaceAll(regexp.QuoteMeta(stderrFifoCommand), "%d", "\\d*") stderrFifoRegexp := strings.ReplaceAll(regexp.QuoteMeta(stderrFifoCommand), "%d", "\\d*")
s.Regexp(stderrFifoRegexp, calledStderrCommand[len(calledStderrCommand)-1]) s.Regexp(stderrFifoRegexp, calledStderrCommand)
}) })
s.Run("should return correct output", func() { s.Run("should return correct output", func() {
@ -728,20 +726,20 @@ func (s *ExecuteCommandTestSuite) TestWithSeparateStderr() {
func (s *ExecuteCommandTestSuite) TestWithSeparateStderrReturnsCommandError() { func (s *ExecuteCommandTestSuite) TestWithSeparateStderrReturnsCommandError() {
config.Config.Server.InteractiveStderr = true config.Config.Server.InteractiveStderr = true
call := s.mockExecute(mock.AnythingOfType("[]string"), 0, nil, func(_ mock.Arguments) {}) call := s.mockExecute(mock.AnythingOfType("string"), 0, nil, func(_ mock.Arguments) {})
call.Run(func(args mock.Arguments) { call.Run(func(args mock.Arguments) {
var ok bool var ok bool
calledCommand, ok := args.Get(2).([]string) calledCommand, ok := args.Get(2).(string)
s.Require().True(ok) s.Require().True(ok)
if isStderrCommand := len(calledCommand) == 5; isStderrCommand { if isStderrCommand := strings.Contains(calledCommand, "mkfifo"); isStderrCommand {
call.ReturnArguments = mock.Arguments{1, nil} call.ReturnArguments = mock.Arguments{1, nil}
} else { } else {
call.ReturnArguments = mock.Arguments{1, tests.ErrDefault} call.ReturnArguments = mock.Arguments{1, tests.ErrDefault}
} }
}) })
_, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, UnprivilegedExecution, _, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY, UnprivilegedExecution,
nullio.Reader{}, io.Discard, io.Discard) nullio.Reader{}, io.Discard, io.Discard)
s.Equal(tests.ErrDefault, err) s.Equal(tests.ErrDefault, err)
} }
@ -752,7 +750,7 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() {
commandExitCode := 42 commandExitCode := 42
// mock regular call // mock regular call
expectedCommand := prepareCommandWithoutTTY(s.testCommandArray, UnprivilegedExecution) expectedCommand := prepareCommandWithoutTTY(s.testCommand, UnprivilegedExecution)
s.mockExecute(expectedCommand, commandExitCode, nil, func(args mock.Arguments) { s.mockExecute(expectedCommand, commandExitCode, nil, func(args mock.Arguments) {
stdout, ok := args.Get(5).(io.Writer) stdout, ok := args.Get(5).(io.Writer)
s.Require().True(ok) s.Require().True(ok)
@ -764,7 +762,7 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() {
s.Require().NoError(err) s.Require().NoError(err)
}) })
exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, exitCode, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY,
UnprivilegedExecution, nullio.Reader{}, &stdout, &stderr) UnprivilegedExecution, nullio.Reader{}, &stdout, &stderr)
s.Require().NoError(err) s.Require().NoError(err)
@ -776,9 +774,9 @@ func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderr() {
func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderrReturnsCommandError() { func (s *ExecuteCommandTestSuite) TestWithoutSeparateStderrReturnsCommandError() {
config.Config.Server.InteractiveStderr = false config.Config.Server.InteractiveStderr = false
expectedCommand := prepareCommandWithoutTTY(s.testCommandArray, UnprivilegedExecution) expectedCommand := prepareCommandWithoutTTY(s.testCommand, UnprivilegedExecution)
s.mockExecute(expectedCommand, 1, tests.ErrDefault, func(args mock.Arguments) {}) s.mockExecute(expectedCommand, 1, tests.ErrDefault, func(args mock.Arguments) {})
_, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommandArray, withTTY, UnprivilegedExecution, _, err := s.nomadAPIClient.ExecuteCommand(s.allocationID, s.ctx, s.testCommand, withTTY, UnprivilegedExecution,
nullio.Reader{}, io.Discard, io.Discard) nullio.Reader{}, io.Discard, io.Discard)
s.ErrorIs(err, tests.ErrDefault) s.ErrorIs(err, tests.ErrDefault)
} }

View File

@ -4,23 +4,23 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/getsentry/sentry-go" "github.com/getsentry/sentry-go"
"github.com/openHPI/poseidon/pkg/dto"
"io" "io"
"regexp" "regexp"
"strconv" "strconv"
"time" "time"
) )
const (
// timeDebugMessageFormat is the format of messages that will be converted to debug messages.
// Format Parameters: 1. Debug Comment, 2. command.
timeDebugMessageFormatStart = `echo -ne "\x1EPoseidon %s $(date +%%s%%3N)\x1E"; %s`
// Format Parameters: 1. command, 2. Debug Comment.
timeDebugMessageFormatEnd = `%s; bash -c "ec=$?; echo -ne \"\\x1EPoseidon %s \$(date +%%s%%3N)\\x1E\" && exit \$ec"`
)
var ( var (
timeDebugMessagePattern = regexp. // timeDebugMessageFormat is the format of messages that will be converted to debug messages.
MustCompile(`(?P<before>.*)\x1EPoseidon (?P<text>.+) (?P<time>\d{13})\x1E(?P<after>.*)`) timeDebugMessageFormat = `echo -ne "\x1EPoseidon %s $(date +%%s%%3N)\x1E"`
// Format Parameters: 1. Debug Comment, 2. command.
timeDebugMessageFormatStart = timeDebugMessageFormat + `; %s`
// Format Parameters: 1. command, 2. Debug Comment.
timeDebugMessageFormatEnd = `%s; ` + dto.WrapBashCommand(`ec=$?; `+timeDebugMessageFormat+` && exit $ec`)
timeDebugMessagePattern = regexp.MustCompile(
`(?P<before>.*)\x1EPoseidon (?P<text>.+) (?P<time>\d{13})\x1E(?P<after>.*)`)
timeDebugMessagePatternStart = regexp.MustCompile(`\x1EPoseidon`) timeDebugMessagePatternStart = regexp.MustCompile(`\x1EPoseidon`)
) )

View File

@ -98,10 +98,11 @@ func (w *AWSFunctionWorkload) ExecuteInteractively(
hideEnvironmentVariables(request, "AWS") hideEnvironmentVariables(request, "AWS")
request.PrivilegedExecution = true // AWS does not support multiple users at this moment. request.PrivilegedExecution = true // AWS does not support multiple users at this moment.
command, ctx, cancel := prepareExecution(request, w.ctx) command, ctx, cancel := prepareExecution(request, w.ctx)
commands := []string{"/bin/bash", "-c", command}
exitInternal := make(chan ExitInfo) exitInternal := make(chan ExitInfo)
exit := make(chan ExitInfo, 1) exit := make(chan ExitInfo, 1)
go w.executeCommand(ctx, command, stdout, stderr, exitInternal) go w.executeCommand(ctx, commands, stdout, stderr, exitInternal)
go w.handleRunnerTimeout(ctx, exitInternal, exit, id) go w.handleRunnerTimeout(ctx, exitInternal, exit, id)
return exit, cancel, nil return exit, cancel, nil

View File

@ -96,9 +96,9 @@ func TestAWSFunctionWorkload_ExecuteInteractively(t *testing.T) {
<-time.After(tests.ShortTimeout) <-time.After(tests.ShortTimeout)
cancel() cancel()
expectedRequestData := "{\"action\":\"" + environment.Image() + expectedRequestData := `{"action":"` + environment.Image() +
"\",\"cmd\":[\"env\",\"CODEOCEAN=true\",\"bash\",\"-c\",\"unset \\\"${!AWS@}\\\" \\u0026\\u0026 " + command + `","cmd":["/bin/bash","-c","env CODEOCEAN=true /bin/bash -c \"unset \\\"\\${!AWS@}\\\" \u0026\u0026 ` + command +
"\"],\"files\":{}}" `\""],"files":{}}`
assert.Equal(t, expectedRequestData, awsMock.receivedData) assert.Equal(t, expectedRequestData, awsMock.receivedData)
}) })
} }
@ -131,9 +131,9 @@ func TestAWSFunctionWorkload_UpdateFileSystem(t *testing.T) {
<-time.After(tests.ShortTimeout) <-time.After(tests.ShortTimeout)
execCancel() execCancel()
expectedRequestData := "{\"action\":\"" + environment.Image() + expectedRequestData := `{"action":"` + environment.Image() +
"\",\"cmd\":[\"env\",\"CODEOCEAN=true\",\"bash\",\"-c\",\"unset \\\"${!AWS@}\\\" \\u0026\\u0026 " + command + `","cmd":["/bin/bash","-c","env CODEOCEAN=true /bin/bash -c \"unset \\\"\\${!AWS@}\\\" \u0026\u0026 ` + command +
"\"]," + "\"files\":{\"" + string(myFile.Path) + "\":\"" + base64.StdEncoding.EncodeToString(myFile.Content) + "\"}}" `\""],"files":{"` + string(myFile.Path) + `":"` + base64.StdEncoding.EncodeToString(myFile.Content) + `"}}`
assert.Equal(t, expectedRequestData, awsMock.receivedData) assert.Equal(t, expectedRequestData, awsMock.receivedData)
} }

View File

@ -232,7 +232,7 @@ func (r *NomadJob) Destroy() error {
} }
func prepareExecution(request *dto.ExecutionRequest, environmentCtx context.Context) ( func prepareExecution(request *dto.ExecutionRequest, environmentCtx context.Context) (
command []string, ctx context.Context, cancel context.CancelFunc, command string, ctx context.Context, cancel context.CancelFunc,
) { ) {
command = request.FullCommand() command = request.FullCommand()
if request.TimeLimit == 0 { if request.TimeLimit == 0 {
@ -243,7 +243,7 @@ func prepareExecution(request *dto.ExecutionRequest, environmentCtx context.Cont
return command, ctx, cancel return command, ctx, cancel
} }
func (r *NomadJob) executeCommand(ctx context.Context, command []string, privilegedExecution bool, func (r *NomadJob) executeCommand(ctx context.Context, command string, privilegedExecution bool,
stdin io.ReadWriter, stdout, stderr io.Writer, exit chan<- ExitInfo, stdin io.ReadWriter, stdout, stderr io.Writer, exit chan<- ExitInfo,
) { ) {
exitCode, err := r.api.ExecuteCommand(r.id, ctx, command, true, privilegedExecution, stdin, stdout, stderr) exitCode, err := r.api.ExecuteCommand(r.id, ctx, command, true, privilegedExecution, stdin, stdout, stderr)

View File

@ -247,7 +247,7 @@ type UpdateFileSystemTestSuite struct {
timer *InactivityTimerMock timer *InactivityTimerMock
apiMock *nomad.ExecutorAPIMock apiMock *nomad.ExecutorAPIMock
mockedExecuteCommandCall *mock.Call mockedExecuteCommandCall *mock.Call
command []string command string
stdin *bytes.Buffer stdin *bytes.Buffer
} }
@ -266,7 +266,7 @@ func (s *UpdateFileSystemTestSuite) SetupTest() {
mock.Anything, false, mock.AnythingOfType("bool"), mock.Anything, mock.Anything, mock.Anything). mock.Anything, false, mock.AnythingOfType("bool"), mock.Anything, mock.Anything, mock.Anything).
Run(func(args mock.Arguments) { Run(func(args mock.Arguments) {
var ok bool var ok bool
s.command, ok = args.Get(2).([]string) s.command, ok = args.Get(2).(string)
s.Require().True(ok) s.Require().True(ok)
s.stdin, ok = args.Get(5).(*bytes.Buffer) s.stdin, ok = args.Get(5).(*bytes.Buffer)
s.Require().True(ok) s.Require().True(ok)
@ -365,7 +365,7 @@ func (s *UpdateFileSystemTestSuite) TestFilesToRemoveGetEscaped() {
s.NoError(err) s.NoError(err)
s.apiMock.AssertCalled(s.T(), "ExecuteCommand", mock.Anything, mock.Anything, mock.Anything, false, true, s.apiMock.AssertCalled(s.T(), "ExecuteCommand", mock.Anything, mock.Anything, mock.Anything, false, true,
mock.Anything, mock.Anything, mock.Anything) mock.Anything, mock.Anything, mock.Anything)
s.Contains(strings.Join(s.command, " "), "'/some/potentially/harmful'\\''filename'") s.Contains(s.command, "'/some/potentially/harmful'\\\\''filename'")
} }
func (s *UpdateFileSystemTestSuite) TestResetTimerGetsCalled() { func (s *UpdateFileSystemTestSuite) TestResetTimerGetsCalled() {

View File

@ -23,11 +23,11 @@ type ExecutionRequest struct {
Environment map[string]string Environment map[string]string
} }
// FullCommand joins the environment variables and the passed command into an "sh -c" wrapped command. // FullCommand joins the environment variables.
// It does not handle the TimeLimit or the PrivilegedExecution flag. // It does not handle the TimeLimit or the PrivilegedExecution flag.
func (er *ExecutionRequest) FullCommand() []string { func (er *ExecutionRequest) FullCommand() string {
command := make([]string, 0) var command string
command = append(command, "env") command += "env"
if er.Environment == nil { if er.Environment == nil {
er.Environment = make(map[string]string) er.Environment = make(map[string]string)
@ -35,9 +35,20 @@ func (er *ExecutionRequest) FullCommand() []string {
er.Environment["CODEOCEAN"] = "true" er.Environment["CODEOCEAN"] = "true"
for variable, value := range er.Environment { for variable, value := range er.Environment {
command = append(command, fmt.Sprintf("%s=%s", variable, value)) command += fmt.Sprintf(" %s=%s", variable, value)
} }
command = append(command, "bash", "-c", er.Command) command += fmt.Sprintf(" %s", WrapBashCommand(er.Command))
return command
}
// WrapBashCommand escapes the passed command and wraps it into a new bash command.
// The escaping includes the characters ", \, $, ` (comma-separated) as they are the exceptional characters
// that still have a special meaning with double quotes. See the Bash Manual - Chapter Quoting.
// We only handle the dollar-character and the backquote because the %q format already escapes the other two.
func WrapBashCommand(command string) string {
command = fmt.Sprintf("/bin/bash -c %q", command)
command = strings.ReplaceAll(command, "$", "\\$")
command = strings.ReplaceAll(command, "`", "\\`")
return command return command
} }

View File

@ -128,7 +128,7 @@ func (s *E2ETestSuite) TestListFileSystem_Nomad() {
listFilesResponse := new(dto.ListFileSystemResponse) listFilesResponse := new(dto.ListFileSystemResponse)
err = json.NewDecoder(response.Body).Decode(listFilesResponse) err = json.NewDecoder(response.Body).Decode(listFilesResponse)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Equal(len(listFilesResponse.Files), 1) s.Require().Equal(1, len(listFilesResponse.Files))
fileHeader := listFilesResponse.Files[0] fileHeader := listFilesResponse.Files[0]
s.Equal(dto.FilePath("./"+tests.DefaultFileName), fileHeader.Name) s.Equal(dto.FilePath("./"+tests.DefaultFileName), fileHeader.Name)
s.Equal(dto.EntryTypeRegularFile, fileHeader.EntryType) s.Equal(dto.EntryTypeRegularFile, fileHeader.EntryType)
@ -322,8 +322,9 @@ func (s *E2ETestSuite) TestCopyFilesRoute_ProtectedFolders() {
// User manipulates protected folder // User manipulates protected folder
s.Run("User can create files", func() { s.Run("User can create files", func() {
log.WithField("id", runnerID).Debug("Runner ID")
webSocketURL, err := ProvideWebSocketURL(runnerID, &dto.ExecutionRequest{ webSocketURL, err := ProvideWebSocketURL(runnerID, &dto.ExecutionRequest{
Command: fmt.Sprintf("touch %s/userfile", protectedFolderPath), Command: fmt.Sprintf("touch %s%s", protectedFolderPath, "userfile"),
TimeLimit: int(tests.DefaultTestTimeout.Seconds()), TimeLimit: int(tests.DefaultTestTimeout.Seconds()),
PrivilegedExecution: false, PrivilegedExecution: false,
}) })