Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/vars expanding into parameters #85

Closed
wants to merge 7 commits into from
Closed
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
13 changes: 12 additions & 1 deletion pkg/jobmanager/bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func newBundlesFromSteps(ctx xcontext.Context, descriptors []*test.TestStepDescr

// look up test step plugins in the plugin registry
var stepBundles []test.TestStepBundle

for idx, descriptor := range descriptors {
if descriptor == nil {
return nil, fmt.Errorf("test step description is null")
Expand Down Expand Up @@ -99,5 +98,17 @@ func newStepBundles(ctx xcontext.Context, descriptors test.TestStepsDescriptors,
}
labels[bundle.TestStepLabel] = true
}
// verify that all variables mappings refer to existing labels
for _, bundle := range testStepBundles {
if bundle.VariablesMapping == nil {
continue
}
for _, sv := range bundle.VariablesMapping {
if _, ok := labels[sv.StepLabel]; !ok {
return nil, fmt.Errorf("variable '%s.%s' of step '%s' refers to unexisting step",
sv.StepLabel, sv.VariableName, bundle.TestStepLabel)
}
}
}
return testStepBundles, nil
}
120 changes: 118 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 Expand Up @@ -112,6 +112,122 @@ func TestNewJobNoTests(t *testing.T) {
require.Error(t, err)
}

func TestVariablesReferToExistingStepLabels(t *testing.T) {
pr := pluginregistry.NewPluginRegistry(xcontext.Background())
require.NoError(t, pr.RegisterTestStep(echo.Load()))
require.NoError(t, pr.RegisterTargetManager(targetlist.Load()))
require.NoError(t, pr.RegisterTestFetcher(literal.Load()))
require.NoError(t, pr.RegisterReporter(noop.Load()))

targetManagerAcquireParameters := `{
"Targets": [
{
"ID": "id1",
"FQDN": "some-host.fna1.dummy-facebook.com"
}
]
}`

t.Run("correct_label", func(t *testing.T) {
testParams := `{
"TestName": "TestVariables",
"Steps": [
{
"name": "echo",
"label": "echo1",
"parameters": {
"text": ["Some text1"]
}
},
{
"name": "echo",
"label": "echo2",
"parameters": {
"text": ["Some text1"]
},
"variablesmapping": {
"output_var": "echo1.message"
}
}
]
}`

testDescriptors := []*test.TestDescriptor{
{
TargetManagerName: "targetList",
TargetManagerAcquireParameters: []byte(targetManagerAcquireParameters),
TargetManagerReleaseParameters: []byte("{}"),
TestFetcherName: "literal",
TestFetcherFetchParameters: []byte(testParams),
},
}

jd := job.Descriptor{
TestDescriptors: testDescriptors,
JobName: "Test",
Reporting: job.Reporting{
RunReporters: []job.ReporterConfig{
{Name: "noop"},
},
},
}

result, err := NewJobFromDescriptor(xcontext.Background(), pr, &jd)
require.NoError(t, err)
require.NotNil(t, result)
require.Len(t, result.Tests, 1)
require.Equal(t, "TestVariables", result.Tests[0].Name)
})

t.Run("unexisting_label", func(t *testing.T) {
testParams := `{
"TestName": "TestVariables",
"Steps": [
{
"name": "echo",
"label": "echo1",
"parameters": {
"text": ["Some text1"]
}
},
{
"name": "echo",
"label": "echo2",
"parameters": {
"text": ["Some text1"]
},
"variablesmapping": {
"output_var": "noecho.message"
}
}
]
}`

testDescriptors := []*test.TestDescriptor{
{
TargetManagerName: "targetList",
TargetManagerAcquireParameters: []byte(targetManagerAcquireParameters),
TargetManagerReleaseParameters: []byte("{}"),
TestFetcherName: "literal",
TestFetcherFetchParameters: []byte(testParams),
},
}

jd := job.Descriptor{
TestDescriptors: testDescriptors,
JobName: "Test",
Reporting: job.Reporting{
RunReporters: []job.ReporterConfig{
{Name: "noop"},
},
},
}

_, err := NewJobFromDescriptor(xcontext.Background(), pr, &jd)
require.Error(t, err)
})
}

func TestNewJobNoTestSteps(t *testing.T) {
pr := pluginregistry.NewPluginRegistry(xcontext.Background())
// require.NoError(t, pr.RegisterTestStep(echo.Load()))
Expand Down
44 changes: 39 additions & 5 deletions pkg/pluginregistry/bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package pluginregistry

import (
"fmt"
"strings"

"github.com/linuxboot/contest/pkg/job"
"github.com/linuxboot/contest/pkg/target"
Expand All @@ -28,14 +29,47 @@ 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.CheckVariableName(label); err != nil {
return nil, InvalidVariableFormat{InvalidName: label, Err: err}
}

var variablesMapping test.StepVariablesMapping
if testStepDescriptor.VariablesMapping != nil {
variablesMapping = make(test.StepVariablesMapping)
for internalName, mappedName := range testStepDescriptor.VariablesMapping {
if err := test.CheckVariableName(internalName); err != nil {
return nil, InvalidVariableFormat{InvalidName: internalName, Err: err}
}
if _, found := variablesMapping[internalName]; found {
return nil, fmt.Errorf("duplication of '%s' variable", internalName)
}
// NewStepVariable creates a StepVariable object from mapping: "stepName.VariableName"
parts := strings.Split(mappedName, ".")
if len(parts) != 2 {
return nil, fmt.Errorf("variable mapping '%s' should contain a single '.' separator", mappedName)
}
if err := test.CheckVariableName(parts[0]); err != nil {
return nil, InvalidVariableFormat{InvalidName: parts[0], Err: err}
}
if err := test.CheckVariableName(parts[1]); err != nil {
return nil, InvalidVariableFormat{InvalidName: parts[1], Err: err}
}

variablesMapping[internalName] = test.StepVariable{
StepLabel: parts[0],
VariableName: parts[1],
}
}
}
testStepBundle := test.TestStepBundle{
TestStep: testStep,
TestStepLabel: label,
Parameters: testStepDescriptor.Parameters,
AllowedEvents: allowedEvents,
TestStep: testStep,
TestStepLabel: label,
Parameters: testStepDescriptor.Parameters,
AllowedEvents: allowedEvents,
VariablesMapping: variablesMapping,
}
return &testStepBundle, nil
}
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)
}

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

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

func (err InvalidVariableFormat) Unwrap() error {
return err.Err
}
53 changes: 46 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,61 @@ 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 := logrusctx.NewContext(logger.LevelDebug)
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 := logrusctx.NewContext(logger.LevelDebug)
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)
}

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

_, err = pr.NewTestStepBundle(ctx, test.TestStepDescriptor{
Name: "AStep",
Label: "Dummy",
VariablesMapping: map[string]string{
"variable": "step_label.var",
},
})
require.NoError(t, err)
})

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

_, err = pr.NewTestStepBundle(ctx, test.TestStepDescriptor{
Name: "AStep",
Label: "Dummy",
VariablesMapping: map[string]string{
"variable ": "step_label.var",
},
})
require.Error(t, err)
})
}
20 changes: 13 additions & 7 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,11 +86,17 @@ 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,
variablesMapping map[string]string,
) test.TestStepBundle {
td := test.TestStepDescriptor{
Name: name,
Label: label,
Parameters: params,
Name: name,
Label: label,
Parameters: params,
VariablesMapping: variablesMapping,
}
sb, err := s.PluginRegistry.NewTestStepBundle(ctx, td)
require.NoError(s.T(), err)
Expand Down
Loading