2018-01-18 01:49:03 -05:00
|
|
|
package multistep
|
|
|
|
|
|
|
|
import (
|
2019-03-22 10:09:20 -04:00
|
|
|
"context"
|
2018-01-18 01:49:03 -05:00
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestBasicRunner_ImplRunner(t *testing.T) {
|
|
|
|
var raw interface{}
|
|
|
|
raw = &BasicRunner{}
|
|
|
|
if _, ok := raw.(Runner); !ok {
|
|
|
|
t.Fatalf("BasicRunner must be a Runner")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBasicRunner_Run(t *testing.T) {
|
|
|
|
data := new(BasicStateBag)
|
|
|
|
stepA := &TestStepAcc{Data: "a"}
|
|
|
|
stepB := &TestStepAcc{Data: "b"}
|
|
|
|
|
|
|
|
r := &BasicRunner{Steps: []Step{stepA, stepB}}
|
2019-03-22 10:09:20 -04:00
|
|
|
r.Run(context.Background(), data)
|
2018-01-18 01:49:03 -05:00
|
|
|
|
|
|
|
// Test run data
|
|
|
|
expected := []string{"a", "b"}
|
|
|
|
results := data.Get("data").([]string)
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
|
|
t.Errorf("unexpected result: %#v", results)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test cleanup data
|
|
|
|
expected = []string{"b", "a"}
|
|
|
|
results = data.Get("cleanup").([]string)
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
|
|
t.Errorf("unexpected result: %#v", results)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test no halted or cancelled
|
|
|
|
if _, ok := data.GetOk(StateCancelled); ok {
|
|
|
|
t.Errorf("cancelled should not be in state bag")
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := data.GetOk(StateHalted); ok {
|
|
|
|
t.Errorf("halted should not be in state bag")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBasicRunner_Run_Halt(t *testing.T) {
|
|
|
|
data := new(BasicStateBag)
|
|
|
|
stepA := &TestStepAcc{Data: "a"}
|
|
|
|
stepB := &TestStepAcc{Data: "b", Halt: true}
|
|
|
|
stepC := &TestStepAcc{Data: "c"}
|
|
|
|
|
|
|
|
r := &BasicRunner{Steps: []Step{stepA, stepB, stepC}}
|
2019-03-22 10:09:20 -04:00
|
|
|
r.Run(context.Background(), data)
|
2018-01-18 01:49:03 -05:00
|
|
|
|
|
|
|
// Test run data
|
|
|
|
expected := []string{"a", "b"}
|
|
|
|
results := data.Get("data").([]string)
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
|
|
t.Errorf("unexpected result: %#v", results)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test cleanup data
|
|
|
|
expected = []string{"b", "a"}
|
|
|
|
results = data.Get("cleanup").([]string)
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
|
|
t.Errorf("unexpected result: %#v", results)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that it says it is halted
|
|
|
|
halted := data.Get(StateHalted).(bool)
|
|
|
|
if !halted {
|
|
|
|
t.Errorf("not halted")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// confirm that can't run twice
|
|
|
|
func TestBasicRunner_Run_Run(t *testing.T) {
|
|
|
|
defer func() {
|
|
|
|
recover()
|
|
|
|
}()
|
|
|
|
ch := make(chan chan bool)
|
|
|
|
stepInt := &TestStepSync{ch}
|
|
|
|
stepWait := &TestStepWaitForever{}
|
|
|
|
r := &BasicRunner{Steps: []Step{stepInt, stepWait}}
|
|
|
|
|
2019-03-22 10:09:20 -04:00
|
|
|
go r.Run(context.Background(), new(BasicStateBag))
|
2018-01-18 01:49:03 -05:00
|
|
|
// wait until really running
|
|
|
|
<-ch
|
|
|
|
|
|
|
|
// now try to run aain
|
2019-03-22 10:09:20 -04:00
|
|
|
r.Run(context.Background(), new(BasicStateBag))
|
2018-01-18 01:49:03 -05:00
|
|
|
|
|
|
|
// should not get here in nominal codepath
|
|
|
|
t.Errorf("Was able to run an already running BasicRunner")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBasicRunner_Cancel(t *testing.T) {
|
|
|
|
|
2019-03-27 07:29:09 -04:00
|
|
|
topCtx, topCtxCancel := context.WithCancel(context.Background())
|
2018-01-18 01:49:03 -05:00
|
|
|
|
2019-03-27 07:29:09 -04:00
|
|
|
checkCancelled := func(data StateBag) {
|
|
|
|
cancelled := data.Get(StateCancelled).(bool)
|
|
|
|
if !cancelled {
|
|
|
|
t.Fatal("state should be cancelled")
|
2018-01-18 01:49:03 -05:00
|
|
|
}
|
2019-03-27 07:29:09 -04:00
|
|
|
}
|
2018-01-18 01:49:03 -05:00
|
|
|
|
2019-03-27 07:29:09 -04:00
|
|
|
data := new(BasicStateBag)
|
|
|
|
r := &BasicRunner{}
|
|
|
|
r.Steps = []Step{
|
|
|
|
&TestStepAcc{Data: "a"},
|
|
|
|
&TestStepAcc{Data: "b"},
|
|
|
|
TestStepFn{
|
|
|
|
run: func(ctx context.Context, sb StateBag) StepAction {
|
|
|
|
return ActionContinue
|
|
|
|
},
|
|
|
|
cleanup: checkCancelled,
|
|
|
|
},
|
|
|
|
TestStepFn{
|
|
|
|
run: func(ctx context.Context, sb StateBag) StepAction {
|
|
|
|
topCtxCancel()
|
|
|
|
<-ctx.Done()
|
|
|
|
return ActionContinue
|
|
|
|
},
|
|
|
|
cleanup: checkCancelled,
|
|
|
|
},
|
|
|
|
TestStepFn{
|
|
|
|
run: func(context.Context, StateBag) StepAction {
|
|
|
|
t.Fatal("I should not be called")
|
|
|
|
return ActionContinue
|
|
|
|
},
|
|
|
|
cleanup: func(StateBag) {
|
|
|
|
t.Fatal("I should not be called")
|
|
|
|
},
|
|
|
|
},
|
2018-01-18 01:49:03 -05:00
|
|
|
}
|
|
|
|
|
2019-03-27 07:29:09 -04:00
|
|
|
r.Run(topCtx, data)
|
2018-01-18 01:49:03 -05:00
|
|
|
|
|
|
|
// Test run data
|
|
|
|
expected := []string{"a", "b"}
|
|
|
|
results := data.Get("data").([]string)
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
|
|
t.Errorf("unexpected result: %#v", results)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test cleanup data
|
|
|
|
expected = []string{"b", "a"}
|
|
|
|
results = data.Get("cleanup").([]string)
|
|
|
|
if !reflect.DeepEqual(results, expected) {
|
|
|
|
t.Errorf("unexpected result: %#v", results)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that it says it is cancelled
|
2019-03-27 07:29:09 -04:00
|
|
|
checkCancelled(data)
|
|
|
|
|
2018-01-18 01:49:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBasicRunner_Cancel_Special(t *testing.T) {
|
|
|
|
stepOne := &TestStepInjectCancel{}
|
|
|
|
stepTwo := &TestStepInjectCancel{}
|
|
|
|
r := &BasicRunner{Steps: []Step{stepOne, stepTwo}}
|
|
|
|
|
|
|
|
state := new(BasicStateBag)
|
|
|
|
state.Put("runner", r)
|
2019-03-22 10:09:20 -04:00
|
|
|
r.Run(context.Background(), state)
|
2018-01-18 01:49:03 -05:00
|
|
|
|
|
|
|
// test that state contains cancelled
|
|
|
|
if _, ok := state.GetOk(StateCancelled); !ok {
|
|
|
|
t.Errorf("cancelled should be in state bag")
|
|
|
|
}
|
|
|
|
}
|