Skip to content

Commit

Permalink
Default test (#134)
Browse files Browse the repository at this point in the history
* add engine test to check defaults are used 

* Reserialize workflow input

* update plugin sdk to use fixed one-of schema

* update deployer

* add serialization detector with a default value test to workflow tests

---------

Co-authored-by: Jared O'Connell <[email protected]>
  • Loading branch information
mfleader and jaredoconnell authored Feb 29, 2024
1 parent e89260b commit 95baaa5
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 30 deletions.
40 changes: 40 additions & 0 deletions engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ input:
id: RootObject
properties:
name:
default: not
type:
type_id: string
steps:
Expand Down Expand Up @@ -217,6 +218,45 @@ outputs:
assert.Equals(t, outputData.(map[any]any), map[any]any{"message": "Hello, Arca Lot!"})
}

func TestE2EWorkflowDefaultInput(t *testing.T) {
content := map[string][]byte{
"workflow.yaml": []byte(`version: v0.2.0
input:
root: RootObject
objects:
RootObject:
id: RootObject
properties:
name:
type:
type_id: string
default: not
required: false
steps:
example:
plugin:
src: quay.io/arcalot/arcaflow-plugin-template-python:0.2.1
deployment_type: image
step: hello-world
input:
name: !expr $.input.name
outputs:
success:
message: !expr $.steps.example.outputs.success.message`),
}
fileCache := loadfile.NewFileCache("", content)
outputID, outputData, outputError, err := createTestEngine(t).RunWorkflow(
context.Background(),
[]byte(`{}`),
fileCache,
"",
)
assert.NoError(t, err)
assert.Equals(t, outputError, false)
assert.Equals(t, outputID, "success")
assert.Equals(t, outputData.(map[any]any), map[any]any{"message": "Hello, not!"})
}

// Test_CacheSubworkflows tests that every sub-workflow filename
// referenced in the main workflow is incorporated into the
// workflow's execution.
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ require (
go.arcalot.io/dgraph v1.2.0
go.arcalot.io/lang v1.1.0
go.arcalot.io/log/v2 v2.1.0
go.flow.arcalot.io/deployer v0.5.0
go.flow.arcalot.io/deployer v0.6.0-beta1
go.flow.arcalot.io/dockerdeployer v0.6.1
go.flow.arcalot.io/expressions v0.4.1
go.flow.arcalot.io/kubernetesdeployer v0.9.1
go.flow.arcalot.io/pluginsdk v0.8.0
go.flow.arcalot.io/pluginsdk v0.9.0-beta1
go.flow.arcalot.io/podmandeployer v0.8.1
go.flow.arcalot.io/pythondeployer v0.6.0
go.flow.arcalot.io/testdeployer v0.6.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,16 @@ go.arcalot.io/lang v1.1.0 h1:ugglRKpd3qIMkdghAjKJxsziIgHm8QpxrzZPSXoa08I=
go.arcalot.io/lang v1.1.0/go.mod h1:2BZJO4csY7NnN/Nf1+eTdIQH4A2vxtOMneaO+PJl+Co=
go.arcalot.io/log/v2 v2.1.0 h1:lNO931hJ82LgS6WcCFCxpLWXQXPFhOkz6PyAJ/augq4=
go.arcalot.io/log/v2 v2.1.0/go.mod h1:PNWOSkkPmgS2OMlWTIlB/WqOw0yaBvDYd8ENAP80H4k=
go.flow.arcalot.io/deployer v0.5.0 h1:yXYogvL3shNBEEoTx9U9CNbfxuf8777uAH5Vn3hv1Yo=
go.flow.arcalot.io/deployer v0.5.0/go.mod h1:whj8wOUursCnfZCt1a7eY5hU3EyOcUG48vM4NeAe5N8=
go.flow.arcalot.io/deployer v0.6.0-beta1 h1:6wVGi/D5rHcT1pnQETg9ZAq5PCxArPwg0MNjaG1Qy/8=
go.flow.arcalot.io/deployer v0.6.0-beta1/go.mod h1:MDaDc9xDRjQN5TyTvvKMXipc5Khe8NLOnUjh31Nm0wU=
go.flow.arcalot.io/dockerdeployer v0.6.1 h1:oRhxXEeOHmXDQVgtYa95tUpw9qc/M//pbeLjdDYMUxc=
go.flow.arcalot.io/dockerdeployer v0.6.1/go.mod h1:Y5Xfg/Fedw/y4LTV0eiJqnsex1mvTbhtP06LCtFkJyo=
go.flow.arcalot.io/expressions v0.4.1 h1:WOl3DtDcWAmPKupwYxJV3bVYKPoMgAmQbECfiUgv/0s=
go.flow.arcalot.io/expressions v0.4.1/go.mod h1:FA/50wX1+0iTgW/dFeeE1yOslZSmfBaMNR4IiMYRwxc=
go.flow.arcalot.io/kubernetesdeployer v0.9.1 h1:AGnJFazehAENXxGMCF0Uc7aG9F0LpvuhoyQFu8deJG0=
go.flow.arcalot.io/kubernetesdeployer v0.9.1/go.mod h1:yvxT3VwmyrlIi4422pxl02z4QeU2Gvbjg5aQB17Ye4s=
go.flow.arcalot.io/pluginsdk v0.8.0 h1:cShsshrR17ZFLcbgi3aZvqexLttcp3JISFNqPUPuDvA=
go.flow.arcalot.io/pluginsdk v0.8.0/go.mod h1:sk7ssInR/T+Gy+RSRr+QhKqZcECFFxMyn1hPQCTZSyU=
go.flow.arcalot.io/pluginsdk v0.9.0-beta1 h1:tJwEp92vRJldHMff29Q8vfQB5a7FHe/nn6vyFTC1sik=
go.flow.arcalot.io/pluginsdk v0.9.0-beta1/go.mod h1:7HafTRTFTYRbJ4sS/Vn0CFrHlaBpEoyOX4oNf612XJM=
go.flow.arcalot.io/podmandeployer v0.8.1 h1:40UDjR1XOn3zOhkwfxvG1AvY+di+MKpGGyd1O6jyzWk=
go.flow.arcalot.io/podmandeployer v0.8.1/go.mod h1:eC6FVbEQXwArSV+U5NePJ5tNbay1+2ZJDamwvcT4Ef8=
go.flow.arcalot.io/pythondeployer v0.6.0 h1:ptAurEJ2u2U127nK6Kk7zTelbkk6ipPqZcwnTmqB9vo=
Expand Down
2 changes: 1 addition & 1 deletion internal/step/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ type stepRegistry struct {
}

func (s stepRegistry) Schema() *schema.OneOfSchema[string] {
return schema.NewOneOfStringSchema[any](s.providerSchemas, "kind")
return schema.NewOneOfStringSchema[any](s.providerSchemas, "kind", false)
}

func (s stepRegistry) SchemaByKind(kind string) (schema.Object, error) {
Expand Down
8 changes: 6 additions & 2 deletions workflow/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ func (e *executableWorkflow) DAG() dgraph.DirectedGraph[*DAGItem] {
func (e *executableWorkflow) Execute(ctx context.Context, serializedInput any) (outputID string, outputData any, err error) { //nolint:gocognit
// First, we unserialize the input. This makes sure we didn't get garbage data.

_, err = e.input.Unserialize(serializedInput)
unserializedInput, err := e.input.Unserialize(serializedInput)
if err != nil {
return "", nil, fmt.Errorf("invalid workflow input (%w)", err)
}
reSerializedInput, err := e.input.Serialize(unserializedInput)
if err != nil {
return "", nil, fmt.Errorf("failed to reserialize workflow input (%w)", err)
}

// We use an internal cancel function to abort the workflow if something bad happens.
ctx, cancel := context.WithCancel(ctx)
Expand All @@ -73,7 +77,7 @@ func (e *executableWorkflow) Execute(ctx context.Context, serializedInput any) (
config: e.config,
lock: &sync.Mutex{},
data: map[string]any{
WorkflowInputKey: serializedInput,
WorkflowInputKey: reSerializedInput,
WorkflowStepsKey: map[string]any{},
},
callableFunctions: e.callableFunctions,
Expand Down
62 changes: 41 additions & 21 deletions workflow/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,33 +279,53 @@ func TestSimpleValidWaitWorkflow(t *testing.T) {
}

func TestWithDoubleSerializationDetection(t *testing.T) {
// Just a single wait
preparedWorkflow := assert.NoErrorR[workflow.ExecutableWorkflow](t)(
getTestImplPreparedWorkflow(t, simpleValidLiteralInputWaitWorkflowDefinition),
)
// First, get the root object
inputSchema := preparedWorkflow.Input()
rootObject := inputSchema.Objects()[inputSchema.Root()]
errorDetect := util.NewInvalidSerializationDetectorSchema()
// Inject the error detector into the object
rootObject.PropertiesValue["error_detector"] = schema.NewPropertySchema(
errorDetect,
nil,
true,
nil,
nil,
nil,
nil,
nil,
)
outputID, _, err := preparedWorkflow.Execute(context.Background(), map[string]any{
"error_detector": "original input",
})
assert.NoError(t, err)
assert.Equals(t, outputID, "a")
// Confirm that, while we did no double-unserializations or double-serializations,
// we did do at least one single one.
assert.Equals(t, errorDetect.SerializeCnt+errorDetect.UnserializeCnt > 0, true)
type testIterType struct {
defaultSpec *string
input map[string]any
}
testIter := []testIterType{
// No default specified; input provided
{
nil,
map[string]any{"error_detector": "original input"},
},
// Default specified; input provided (overrides default)
{
schema.PointerTo[string]("default"),
map[string]any{"error_detector": "original input"},
},
// Default specified; input omitted (default value used)
{
schema.PointerTo[string]("default"),
map[string]any{},
},
}
for _, i := range testIter {
errorDetect := util.NewInvalidSerializationDetectorSchema()
// Inject the error detector into the object
rootObject.PropertiesValue["error_detector"] = schema.NewPropertySchema(
errorDetect,
nil,
true,
nil,
nil,
nil,
i.defaultSpec,
nil,
)
outputID, _, err := preparedWorkflow.Execute(context.Background(), i.input)
assert.NoError(t, err)
assert.Equals(t, outputID, "a")
// Confirm that, while we did no double-unserializations or double-serializations,
// we did do at least one single one.
assert.Equals(t, errorDetect.SerializeCnt+errorDetect.UnserializeCnt > 0, true)
}
}

var waitForSerialWorkflowDefinition = `
Expand Down

0 comments on commit 95baaa5

Please sign in to comment.