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

Bring test coverate up to 100% #4

Merged
merged 1 commit into from
Apr 7, 2014
Merged
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
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) {}