Skip to content

Commit

Permalink
Merge pull request mitchellh#4 from ryancox/master
Browse files Browse the repository at this point in the history
Bring test coverate up to 100%
  • Loading branch information
mitchellh committed Apr 7, 2014
2 parents 3877de9 + d16879f commit 162146f
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 7 deletions.
40 changes: 40 additions & 0 deletions basic_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ func TestBasicRunner_Run_Halt(t *testing.T) {
}
}

// 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}}

go r.Run(new(BasicStateBag))
// wait until really running
<-ch

// now try to run aain
r.Run(new(BasicStateBag))

// should not get here in nominal codepath
t.Errorf("Was able to run an already running BasicRunner")
}

func TestBasicRunner_Cancel(t *testing.T) {
ch := make(chan chan bool)
data := new(BasicStateBag)
Expand All @@ -85,6 +106,10 @@ func TestBasicRunner_Cancel(t *testing.T) {
stepC := &TestStepAcc{Data: "c"}

r := &BasicRunner{Steps: []Step{stepA, stepB, stepInt, stepC}}

// cancelling an idle Runner is a no-op
r.Cancel()

go r.Run(data)

// Wait until we reach the sync point
Expand Down Expand Up @@ -128,3 +153,18 @@ func TestBasicRunner_Cancel(t *testing.T) {
t.Errorf("not cancelled")
}
}

func TestBasicRunner_Cancel_Special(t *testing.T) {
stepOne := &TestStepInjectCancel{}
stepTwo := &TestStepInjectCancel{}
r := &BasicRunner{Steps: []Step{stepOne, stepTwo}}

state := new(BasicStateBag)
state.Put("runner", r)
r.Run(state)

// test that state contains cancelled
if _, ok := state.GetOk(StateCancelled); !ok {
t.Errorf("cancelled should be in state bag")
}
}
2 changes: 0 additions & 2 deletions debug_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ func DebugPauseDefault(loc DebugLocation, name string, state StateBag) {
locationString = "after run of"
case DebugLocationBeforeCleanup:
locationString = "before cleanup of"
default:
locationString = "at"
}

fmt.Printf("Pausing %s step '%s'. Press any key to continue.\n", locationString, name)
Expand Down
89 changes: 84 additions & 5 deletions debug_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,86 @@ func TestDebugRunner_Run(t *testing.T) {
}
}

// confirm that can't run twice
func TestDebugRunner_Run_Run(t *testing.T) {
defer func() {
recover()
}()
ch := make(chan chan bool)
stepInt := &TestStepSync{ch}
stepWait := &TestStepWaitForever{}
r := &DebugRunner{Steps: []Step{stepInt, stepWait}}

go r.Run(new(BasicStateBag))
// wait until really running
<-ch

// now try to run aain
r.Run(new(BasicStateBag))

// should not get here in nominal codepath
t.Errorf("Was able to run an already running DebugRunner")
}

func TestDebugRunner_Cancel(t *testing.T) {
ch := make(chan chan bool)
data := new(BasicStateBag)
stepA := &TestStepAcc{Data: "a"}
stepB := &TestStepAcc{Data: "b"}
stepInt := &TestStepSync{ch}
stepC := &TestStepAcc{Data: "c"}

r := &DebugRunner{}
r.Steps = []Step{stepA, stepB, stepInt, stepC}

// cancelling an idle Runner is a no-op
r.Cancel()

go r.Run(data)

// Wait until we reach the sync point
responseCh := <-ch

// Cancel then continue chain
cancelCh := make(chan bool)
go func() {
r.Cancel()
cancelCh <- true
}()

for {
if _, ok := data.GetOk(StateCancelled); ok {
responseCh <- true
break
}

time.Sleep(10 * time.Millisecond)
}

<-cancelCh

// 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
cancelled := data.Get(StateCancelled).(bool)
if !cancelled {
t.Errorf("not cancelled")
}
}

func TestDebugPauseDefault(t *testing.T) {
loc := DebugLocationAfterRun
name := "foo"
state := new(BasicStateBag)

// Create a pipe pair so that writes/reads are blocked until we do it
r, w, err := os.Pipe()
Expand All @@ -75,7 +151,10 @@ func TestDebugPauseDefault(t *testing.T) {
// Start pausing
complete := make(chan bool, 1)
go func() {
DebugPauseDefault(loc, name, state)
dr := &DebugRunner{Steps: []Step{
&TestStepAcc{Data: "a"},
}}
dr.Run(new(BasicStateBag))
complete <- true
}()

Expand All @@ -85,7 +164,7 @@ func TestDebugPauseDefault(t *testing.T) {
case <-time.After(100 * time.Millisecond):
}

w.Write([]byte("\n"))
w.Write([]byte("\n\n"))

select {
case <-complete:
Expand Down
23 changes: 23 additions & 0 deletions multistep_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ type TestStepSync struct {
Ch chan chan bool
}

// A step that sleeps forever
type TestStepWaitForever struct {
}

// A step that manually flips state to cancelling in run
type TestStepInjectCancel struct {
}

func (s TestStepAcc) Run(state StateBag) StepAction {
s.insertData(state, "data")

Expand Down Expand Up @@ -49,3 +57,18 @@ func (s TestStepSync) Run(StateBag) StepAction {
}

func (s TestStepSync) Cleanup(StateBag) {}

func (s TestStepWaitForever) Run(StateBag) StepAction {
select {}
return ActionContinue
}

func (s TestStepWaitForever) Cleanup(StateBag) {}

func (s TestStepInjectCancel) Run(state StateBag) StepAction {
r := state.Get("runner").(*BasicRunner)
r.state = stateCancelling
return ActionContinue
}

func (s TestStepInjectCancel) Cleanup(StateBag) {}

0 comments on commit 162146f

Please sign in to comment.