Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/jobmanager/bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,6 @@ func newStepBundles(ctx xcontext.Context, descriptors test.TestStepsDescriptors,
}
labels[bundle.TestStepLabel] = true
}
// TODO: verify that test variables refer to existing steps
return testStepBundles, nil
}
4 changes: 2 additions & 2 deletions pkg/jobmanager/job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestDisabledTestDescriptor(t *testing.T) {
"Steps": [
{
"name": "echo",
"label": "echo text",
"label": "echotext",
"parameters": {
"text": ["Some text1"]
}
Expand All @@ -38,7 +38,7 @@ func TestDisabledTestDescriptor(t *testing.T) {
"Steps": [
{
"name": "echo",
"label": "echo text",
"label": "echotext",
"parameters": {
"text": ["Some text1"]
}
Expand Down
7 changes: 5 additions & 2 deletions pkg/pluginregistry/bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package pluginregistry

import (
"fmt"

"github.com/linuxboot/contest/pkg/job"
"github.com/linuxboot/contest/pkg/target"
"github.com/linuxboot/contest/pkg/test"
Expand All @@ -28,9 +27,13 @@ func (r *PluginRegistry) NewTestStepBundle(ctx xcontext.Context, testStepDescrip
return nil, err
}
label := testStepDescriptor.Label
if label == "" {
if len(label) == 0 {
return nil, ErrStepLabelIsMandatory{TestStepDescriptor: testStepDescriptor}
}
if err := test.CheckIdentifier(label); err != nil {
return nil, ErrInvalidStepLabelFormat{InvalidName: label, Err: err}
}

testStepBundle := test.TestStepBundle{
TestStep: testStep,
TestStepLabel: label,
Expand Down
14 changes: 14 additions & 0 deletions pkg/pluginregistry/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,17 @@ type ErrStepLabelIsMandatory struct {
func (err ErrStepLabelIsMandatory) Error() string {
return fmt.Sprintf("step has no label, but it is mandatory (step: %+v)", err.TestStepDescriptor)
}

// ErrInvalidStepLabelFormat tells that a variable name doesn't fit the variable name format (alphanum + '_')
type ErrInvalidStepLabelFormat struct {
InvalidName string
Err error
}

func (err ErrInvalidStepLabelFormat) Error() string {
return fmt.Sprintf("'%s' doesn't match variable name format: %v", err.InvalidName, err.Err)
}

func (err ErrInvalidStepLabelFormat) Unwrap() error {
return err.Err
}
21 changes: 14 additions & 7 deletions pkg/pluginregistry/pluginregistry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ import (
"github.com/stretchr/testify/require"
)

var (
ctx, _ = logrusctx.NewContext(logger.LevelDebug)
)

// Definition of two dummy TestSteps to be used to test the PluginRegistry

// AStep implements a dummy TestStep
Expand All @@ -44,18 +40,29 @@ func (e AStep) Name() string {
}

// Run executes the AStep
func (e AStep) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func (e AStep) Run(
ctx xcontext.Context,
ch test.TestStepChannels,
ev testevent.Emitter,
stepsVars test.StepsVariables,
params test.TestStepParameters,
resumeState json.RawMessage,
) (json.RawMessage, error) {
return nil, nil
}

func TestRegisterTestStep(t *testing.T) {
ctx, cancel := logrusctx.NewContext(logger.LevelDebug)
defer cancel()
pr := NewPluginRegistry(ctx)
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{event.Name("AStepEventName")})
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{"AStepEventName"})
require.NoError(t, err)
}

func TestRegisterTestStepDoesNotValidate(t *testing.T) {
ctx, cancel := logrusctx.NewContext(logger.LevelDebug)
defer cancel()
pr := NewPluginRegistry(ctx)
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{event.Name("Event which does not validate")})
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{"Event which does not validate"})
require.Error(t, err)
}
12 changes: 8 additions & 4 deletions pkg/runner/base_test_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ func (s *BaseTestSuite) TearDownTest() {
}

func (s *BaseTestSuite) RegisterStateFullStep(
runFunction func(
ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters,
ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error),
runFunction func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters,
resumeState json.RawMessage) (json.RawMessage, error),
validateFunction func(ctx xcontext.Context, params test.TestStepParameters) error) error {

return s.PluginRegistry.RegisterTestStep(stateFullStepName, func() test.TestStep {
Expand All @@ -86,7 +86,11 @@ func (s *BaseTestSuite) RegisterStateFullStep(
}, nil)
}

func (s *BaseTestSuite) NewStep(ctx xcontext.Context, label, name string, params test.TestStepParameters) test.TestStepBundle {
func (s *BaseTestSuite) NewStep(
ctx xcontext.Context,
label, name string,
params test.TestStepParameters,
) test.TestStepBundle {
td := test.TestStepDescriptor{
Name: name,
Label: label,
Expand Down
21 changes: 14 additions & 7 deletions pkg/runner/job_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ func (s *JobRunnerSuite) TestSimpleJobStartFinish() {
var resultTargets []*target.Target

require.NoError(s.T(), s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
return teststeps.ForEachTarget(stateFullStepName, ctx, ch, func(ctx xcontext.Context, target *target.Target) error {
assert.NotNil(s.T(), target)
mu.Lock()
Expand Down Expand Up @@ -124,7 +125,8 @@ func (s *JobRunnerSuite) TestJobWithTestRetry() {
var callsCount int

require.NoError(s.T(), s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
return teststeps.ForEachTarget(stateFullStepName, ctx, ch, func(ctx xcontext.Context, target *target.Target) error {
assert.NotNil(s.T(), target)
mu.Lock()
Expand Down Expand Up @@ -454,22 +456,27 @@ func (s *JobRunnerSuite) TestResumeStateBadJobId() {
const stateFullStepName = "statefull"

type stateFullStep struct {
runFunction func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters,
ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error)
runFunction func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error)
validateFunction func(ctx xcontext.Context, params test.TestStepParameters) error
}

func (sfs *stateFullStep) Name() string {
return stateFullStepName
}

func (sfs *stateFullStep) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters,
ev testevent.Emitter, resumeState json.RawMessage,
func (sfs *stateFullStep) Run(
ctx xcontext.Context,
ch test.TestStepChannels,
ev testevent.Emitter,
stepsVars test.StepsVariables,
params test.TestStepParameters,
resumeState json.RawMessage,
) (json.RawMessage, error) {
if sfs.runFunction == nil {
return nil, fmt.Errorf("stateFullStep run is not initialised")
}
return sfs.runFunction(ctx, ch, params, ev, resumeState)
return sfs.runFunction(ctx, ch, ev, stepsVars, params, resumeState)
}

func (sfs *stateFullStep) ValidateParameters(ctx xcontext.Context, params test.TestStepParameters) error {
Expand Down
8 changes: 5 additions & 3 deletions pkg/runner/step_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func NewStepRunner() *StepRunner {
func (sr *StepRunner) Run(
ctx xcontext.Context,
bundle test.TestStepBundle,
stepsVariables test.StepsVariables,
ev testevent.Emitter,
resumeState json.RawMessage,
resumeStateTargets []target.Target,
Expand Down Expand Up @@ -132,7 +133,7 @@ func (sr *StepRunner) Run(
stepOut := make(chan test.TestStepResult)
go func() {
defer finish()
sr.runningLoop(ctx, sr.input, stepOut, bundle, ev, resumeState)
sr.runningLoop(ctx, sr.input, stepOut, bundle, stepsVariables, ev, resumeState)
ctx.Debugf("Running loop finished")
}()

Expand Down Expand Up @@ -381,6 +382,7 @@ func (sr *StepRunner) runningLoop(
stepIn <-chan *target.Target,
stepOut chan test.TestStepResult,
bundle test.TestStepBundle,
stepsVariables test.StepsVariables,
ev testevent.Emitter,
resumeState json.RawMessage,
) {
Expand Down Expand Up @@ -410,9 +412,9 @@ func (sr *StepRunner) runningLoop(
}()

inChannels := test.TestStepChannels{In: stepIn, Out: stepOut}
return bundle.TestStep.Run(ctx, inChannels, bundle.Parameters, ev, resumeState)
return bundle.TestStep.Run(ctx, inChannels, ev, stepsVariables, bundle.Parameters, resumeState)
}()
ctx.Debugf("TestStep finished '%v', rs %s", err, string(resultResumeState))
ctx.Debugf("TestStep finished '%v', rs: '%s'", err, string(resultResumeState))

sr.mu.Lock()
sr.setErrLocked(ctx, err)
Expand Down
47 changes: 42 additions & 5 deletions pkg/runner/step_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ func (s *StepRunnerSuite) TestRunningStep() {
var obtainedResumeState json.RawMessage

err := s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
obtainedResumeState = resumeState
_, err := teststeps.ForEachTarget(stateFullStepName, ctx, ch, func(ctx xcontext.Context, target *target.Target) error {
require.NotNil(s.T(), target)
Expand Down Expand Up @@ -85,6 +86,7 @@ func (s *StepRunnerSuite) TestRunningStep() {
inputResumeState := json.RawMessage("{\"some_input\": 42}")
addTarget, resumedTargetsResults, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
inputResumeState,
nil,
Expand Down Expand Up @@ -127,7 +129,8 @@ func (s *StepRunnerSuite) TestAddSameTargetSequentiallyTimes() {
const inputTargetID = "input_target_id"

err := s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
_, err := teststeps.ForEachTarget(stateFullStepName, ctx, ch, func(ctx xcontext.Context, target *target.Target) error {
require.NotNil(s.T(), target)
require.Equal(s.T(), inputTargetID, target.ID)
Expand All @@ -149,6 +152,7 @@ func (s *StepRunnerSuite) TestAddSameTargetSequentiallyTimes() {

addTarget, _, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand Down Expand Up @@ -180,7 +184,8 @@ func (s *StepRunnerSuite) TestAddTargetReturnsErrorIfFailsToInput() {
}
}()
err := s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
<-hangCh
for range ch.In {
require.Fail(s.T(), "unexpected input")
Expand All @@ -200,6 +205,7 @@ func (s *StepRunnerSuite) TestAddTargetReturnsErrorIfFailsToInput() {

addTarget, resumedTargetsResults, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand Down Expand Up @@ -238,7 +244,8 @@ func (s *StepRunnerSuite) TestStepPanics() {
defer cancel()

err := s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
panic("panic")
},
nil,
Expand All @@ -251,6 +258,7 @@ func (s *StepRunnerSuite) TestStepPanics() {

addTarget, resumedTargetsResults, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
NewTestStepEventsEmitterFactory(
s.MemoryStorage.StorageEngineVault,
1,
Expand Down Expand Up @@ -288,7 +296,8 @@ func (s *StepRunnerSuite) TestCornerCases() {
defer cancel()

err := s.RegisterStateFullStep(
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
_, err := teststeps.ForEachTarget(stateFullStepName, ctx, ch, func(ctx xcontext.Context, target *target.Target) error {
return fmt.Errorf("should not be called")
})
Expand All @@ -308,6 +317,7 @@ func (s *StepRunnerSuite) TestCornerCases() {

addTarget, _, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand All @@ -331,6 +341,7 @@ func (s *StepRunnerSuite) TestCornerCases() {

addTarget, _, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand All @@ -341,6 +352,7 @@ func (s *StepRunnerSuite) TestCornerCases() {

addTarget2, _, runResult2, err2 := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand All @@ -357,6 +369,7 @@ func (s *StepRunnerSuite) TestCornerCases() {

addTarget, _, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand All @@ -378,6 +391,7 @@ func (s *StepRunnerSuite) TestCornerCases() {
stepRunner.Stop()
addTarget, _, runResult, err := stepRunner.Run(ctx,
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
newStepsVariablesMock(nil, nil),
emitter,
nil,
nil,
Expand All @@ -388,3 +402,26 @@ func (s *StepRunnerSuite) TestCornerCases() {
checkSuccessfulResult(s.T(), runResult)
})
}

type stepsVariablesMock struct {
add func(tgtID string, name string, value interface{}) error
get func(tgtID string, stepLabel, name string, value interface{}) error
}

func (sm *stepsVariablesMock) Add(tgtID string, name string, value interface{}) error {
return sm.add(tgtID, name, value)
}

func (sm *stepsVariablesMock) Get(tgtID string, stepLabel, name string, value interface{}) error {
return sm.get(tgtID, stepLabel, name, value)
}

func newStepsVariablesMock(
add func(tgtID string, name string, value interface{}) error,
get func(tgtID string, stepLabel, name string, value interface{}) error,
) *stepsVariablesMock {
return &stepsVariablesMock{
add: add,
get: get,
}
}
Loading