Skip to content

Commit 768d780

Browse files
authored
Merge pull request #83 from linuxboot/poc/steps_variables
TestStep variables proof of concept
2 parents 0807544 + 8196bfa commit 768d780

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+786
-228
lines changed

pkg/jobmanager/bundles.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@ func newStepBundles(ctx xcontext.Context, descriptors test.TestStepsDescriptors,
9999
}
100100
labels[bundle.TestStepLabel] = true
101101
}
102+
// TODO: verify that test variables refer to existing steps
102103
return testStepBundles, nil
103104
}

pkg/jobmanager/job_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestDisabledTestDescriptor(t *testing.T) {
2626
"Steps": [
2727
{
2828
"name": "echo",
29-
"label": "echo text",
29+
"label": "echotext",
3030
"parameters": {
3131
"text": ["Some text1"]
3232
}
@@ -38,7 +38,7 @@ func TestDisabledTestDescriptor(t *testing.T) {
3838
"Steps": [
3939
{
4040
"name": "echo",
41-
"label": "echo text",
41+
"label": "echotext",
4242
"parameters": {
4343
"text": ["Some text1"]
4444
}

pkg/pluginregistry/bundles.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package pluginregistry
77

88
import (
99
"fmt"
10-
1110
"github.com/linuxboot/contest/pkg/job"
1211
"github.com/linuxboot/contest/pkg/target"
1312
"github.com/linuxboot/contest/pkg/test"
@@ -28,9 +27,13 @@ func (r *PluginRegistry) NewTestStepBundle(ctx xcontext.Context, testStepDescrip
2827
return nil, err
2928
}
3029
label := testStepDescriptor.Label
31-
if label == "" {
30+
if len(label) == 0 {
3231
return nil, ErrStepLabelIsMandatory{TestStepDescriptor: testStepDescriptor}
3332
}
33+
if err := test.CheckIdentifier(label); err != nil {
34+
return nil, ErrInvalidStepLabelFormat{InvalidName: label, Err: err}
35+
}
36+
3437
testStepBundle := test.TestStepBundle{
3538
TestStep: testStep,
3639
TestStepLabel: label,

pkg/pluginregistry/errors.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,17 @@ type ErrStepLabelIsMandatory struct {
1818
func (err ErrStepLabelIsMandatory) Error() string {
1919
return fmt.Sprintf("step has no label, but it is mandatory (step: %+v)", err.TestStepDescriptor)
2020
}
21+
22+
// ErrInvalidStepLabelFormat tells that a variable name doesn't fit the variable name format (alphanum + '_')
23+
type ErrInvalidStepLabelFormat struct {
24+
InvalidName string
25+
Err error
26+
}
27+
28+
func (err ErrInvalidStepLabelFormat) Error() string {
29+
return fmt.Sprintf("'%s' doesn't match variable name format: %v", err.InvalidName, err.Err)
30+
}
31+
32+
func (err ErrInvalidStepLabelFormat) Unwrap() error {
33+
return err.Err
34+
}

pkg/pluginregistry/pluginregistry_test.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ import (
1919
"github.com/stretchr/testify/require"
2020
)
2121

22-
var (
23-
ctx, _ = logrusctx.NewContext(logger.LevelDebug)
24-
)
25-
2622
// Definition of two dummy TestSteps to be used to test the PluginRegistry
2723

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

4642
// Run executes the AStep
47-
func (e AStep) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
43+
func (e AStep) Run(
44+
ctx xcontext.Context,
45+
ch test.TestStepChannels,
46+
ev testevent.Emitter,
47+
stepsVars test.StepsVariables,
48+
params test.TestStepParameters,
49+
resumeState json.RawMessage,
50+
) (json.RawMessage, error) {
4851
return nil, nil
4952
}
5053

5154
func TestRegisterTestStep(t *testing.T) {
55+
ctx, cancel := logrusctx.NewContext(logger.LevelDebug)
56+
defer cancel()
5257
pr := NewPluginRegistry(ctx)
53-
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{event.Name("AStepEventName")})
58+
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{"AStepEventName"})
5459
require.NoError(t, err)
5560
}
5661

5762
func TestRegisterTestStepDoesNotValidate(t *testing.T) {
63+
ctx, cancel := logrusctx.NewContext(logger.LevelDebug)
64+
defer cancel()
5865
pr := NewPluginRegistry(ctx)
59-
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{event.Name("Event which does not validate")})
66+
err := pr.RegisterTestStep("AStep", NewAStep, []event.Name{"Event which does not validate"})
6067
require.Error(t, err)
6168
}

pkg/runner/base_test_suite_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ func (s *BaseTestSuite) TearDownTest() {
7373
}
7474

7575
func (s *BaseTestSuite) RegisterStateFullStep(
76-
runFunction func(
77-
ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters,
78-
ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error),
76+
runFunction func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
77+
stepsVars test.StepsVariables, params test.TestStepParameters,
78+
resumeState json.RawMessage) (json.RawMessage, error),
7979
validateFunction func(ctx xcontext.Context, params test.TestStepParameters) error) error {
8080

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

89-
func (s *BaseTestSuite) NewStep(ctx xcontext.Context, label, name string, params test.TestStepParameters) test.TestStepBundle {
89+
func (s *BaseTestSuite) NewStep(
90+
ctx xcontext.Context,
91+
label, name string,
92+
params test.TestStepParameters,
93+
) test.TestStepBundle {
9094
td := test.TestStepDescriptor{
9195
Name: name,
9296
Label: label,

pkg/runner/job_runner_test.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ func (s *JobRunnerSuite) TestSimpleJobStartFinish() {
5858
var resultTargets []*target.Target
5959

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

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

456458
type stateFullStep struct {
457-
runFunction func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters,
458-
ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error)
459+
runFunction func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
460+
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error)
459461
validateFunction func(ctx xcontext.Context, params test.TestStepParameters) error
460462
}
461463

462464
func (sfs *stateFullStep) Name() string {
463465
return stateFullStepName
464466
}
465467

466-
func (sfs *stateFullStep) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters,
467-
ev testevent.Emitter, resumeState json.RawMessage,
468+
func (sfs *stateFullStep) Run(
469+
ctx xcontext.Context,
470+
ch test.TestStepChannels,
471+
ev testevent.Emitter,
472+
stepsVars test.StepsVariables,
473+
params test.TestStepParameters,
474+
resumeState json.RawMessage,
468475
) (json.RawMessage, error) {
469476
if sfs.runFunction == nil {
470477
return nil, fmt.Errorf("stateFullStep run is not initialised")
471478
}
472-
return sfs.runFunction(ctx, ch, params, ev, resumeState)
479+
return sfs.runFunction(ctx, ch, ev, stepsVars, params, resumeState)
473480
}
474481

475482
func (sfs *stateFullStep) ValidateParameters(ctx xcontext.Context, params test.TestStepParameters) error {

pkg/runner/step_runner.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ func NewStepRunner() *StepRunner {
9090
func (sr *StepRunner) Run(
9191
ctx xcontext.Context,
9292
bundle test.TestStepBundle,
93+
stepsVariables test.StepsVariables,
9394
ev testevent.Emitter,
9495
resumeState json.RawMessage,
9596
resumeStateTargets []target.Target,
@@ -132,7 +133,7 @@ func (sr *StepRunner) Run(
132133
stepOut := make(chan test.TestStepResult)
133134
go func() {
134135
defer finish()
135-
sr.runningLoop(ctx, sr.input, stepOut, bundle, ev, resumeState)
136+
sr.runningLoop(ctx, sr.input, stepOut, bundle, stepsVariables, ev, resumeState)
136137
ctx.Debugf("Running loop finished")
137138
}()
138139

@@ -381,6 +382,7 @@ func (sr *StepRunner) runningLoop(
381382
stepIn <-chan *target.Target,
382383
stepOut chan test.TestStepResult,
383384
bundle test.TestStepBundle,
385+
stepsVariables test.StepsVariables,
384386
ev testevent.Emitter,
385387
resumeState json.RawMessage,
386388
) {
@@ -410,9 +412,9 @@ func (sr *StepRunner) runningLoop(
410412
}()
411413

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

417419
sr.mu.Lock()
418420
sr.setErrLocked(ctx, err)

pkg/runner/step_runner_test.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ func (s *StepRunnerSuite) TestRunningStep() {
5757
var obtainedResumeState json.RawMessage
5858

5959
err := s.RegisterStateFullStep(
60-
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
60+
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
61+
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
6162
obtainedResumeState = resumeState
6263
_, err := teststeps.ForEachTarget(stateFullStepName, ctx, ch, func(ctx xcontext.Context, target *target.Target) error {
6364
require.NotNil(s.T(), target)
@@ -85,6 +86,7 @@ func (s *StepRunnerSuite) TestRunningStep() {
8586
inputResumeState := json.RawMessage("{\"some_input\": 42}")
8687
addTarget, resumedTargetsResults, runResult, err := stepRunner.Run(ctx,
8788
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
89+
newStepsVariablesMock(nil, nil),
8890
emitter,
8991
inputResumeState,
9092
nil,
@@ -127,7 +129,8 @@ func (s *StepRunnerSuite) TestAddSameTargetSequentiallyTimes() {
127129
const inputTargetID = "input_target_id"
128130

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

150153
addTarget, _, runResult, err := stepRunner.Run(ctx,
151154
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
155+
newStepsVariablesMock(nil, nil),
152156
emitter,
153157
nil,
154158
nil,
@@ -180,7 +184,8 @@ func (s *StepRunnerSuite) TestAddTargetReturnsErrorIfFailsToInput() {
180184
}
181185
}()
182186
err := s.RegisterStateFullStep(
183-
func(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
187+
func(ctx xcontext.Context, ch test.TestStepChannels, ev testevent.Emitter,
188+
stepsVars test.StepsVariables, params test.TestStepParameters, resumeState json.RawMessage) (json.RawMessage, error) {
184189
<-hangCh
185190
for range ch.In {
186191
require.Fail(s.T(), "unexpected input")
@@ -200,6 +205,7 @@ func (s *StepRunnerSuite) TestAddTargetReturnsErrorIfFailsToInput() {
200205

201206
addTarget, resumedTargetsResults, runResult, err := stepRunner.Run(ctx,
202207
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
208+
newStepsVariablesMock(nil, nil),
203209
emitter,
204210
nil,
205211
nil,
@@ -238,7 +244,8 @@ func (s *StepRunnerSuite) TestStepPanics() {
238244
defer cancel()
239245

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

252259
addTarget, resumedTargetsResults, runResult, err := stepRunner.Run(ctx,
253260
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
261+
newStepsVariablesMock(nil, nil),
254262
NewTestStepEventsEmitterFactory(
255263
s.MemoryStorage.StorageEngineVault,
256264
1,
@@ -288,7 +296,8 @@ func (s *StepRunnerSuite) TestCornerCases() {
288296
defer cancel()
289297

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

309318
addTarget, _, runResult, err := stepRunner.Run(ctx,
310319
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
320+
newStepsVariablesMock(nil, nil),
311321
emitter,
312322
nil,
313323
nil,
@@ -331,6 +341,7 @@ func (s *StepRunnerSuite) TestCornerCases() {
331341

332342
addTarget, _, runResult, err := stepRunner.Run(ctx,
333343
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
344+
newStepsVariablesMock(nil, nil),
334345
emitter,
335346
nil,
336347
nil,
@@ -341,6 +352,7 @@ func (s *StepRunnerSuite) TestCornerCases() {
341352

342353
addTarget2, _, runResult2, err2 := stepRunner.Run(ctx,
343354
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
355+
newStepsVariablesMock(nil, nil),
344356
emitter,
345357
nil,
346358
nil,
@@ -357,6 +369,7 @@ func (s *StepRunnerSuite) TestCornerCases() {
357369

358370
addTarget, _, runResult, err := stepRunner.Run(ctx,
359371
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
372+
newStepsVariablesMock(nil, nil),
360373
emitter,
361374
nil,
362375
nil,
@@ -378,6 +391,7 @@ func (s *StepRunnerSuite) TestCornerCases() {
378391
stepRunner.Stop()
379392
addTarget, _, runResult, err := stepRunner.Run(ctx,
380393
s.NewStep(ctx, "test_step_label", stateFullStepName, nil),
394+
newStepsVariablesMock(nil, nil),
381395
emitter,
382396
nil,
383397
nil,
@@ -388,3 +402,26 @@ func (s *StepRunnerSuite) TestCornerCases() {
388402
checkSuccessfulResult(s.T(), runResult)
389403
})
390404
}
405+
406+
type stepsVariablesMock struct {
407+
add func(tgtID string, name string, value interface{}) error
408+
get func(tgtID string, stepLabel, name string, value interface{}) error
409+
}
410+
411+
func (sm *stepsVariablesMock) Add(tgtID string, name string, value interface{}) error {
412+
return sm.add(tgtID, name, value)
413+
}
414+
415+
func (sm *stepsVariablesMock) Get(tgtID string, stepLabel, name string, value interface{}) error {
416+
return sm.get(tgtID, stepLabel, name, value)
417+
}
418+
419+
func newStepsVariablesMock(
420+
add func(tgtID string, name string, value interface{}) error,
421+
get func(tgtID string, stepLabel, name string, value interface{}) error,
422+
) *stepsVariablesMock {
423+
return &stepsVariablesMock{
424+
add: add,
425+
get: get,
426+
}
427+
}

0 commit comments

Comments
 (0)