github.com/HashDataInc/packer@v1.3.2/helper/multistep/basic_runner_test.go (about)

     1  package multistep
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  	"time"
     7  )
     8  
     9  func TestBasicRunner_ImplRunner(t *testing.T) {
    10  	var raw interface{}
    11  	raw = &BasicRunner{}
    12  	if _, ok := raw.(Runner); !ok {
    13  		t.Fatalf("BasicRunner must be a Runner")
    14  	}
    15  }
    16  
    17  func TestBasicRunner_Run(t *testing.T) {
    18  	data := new(BasicStateBag)
    19  	stepA := &TestStepAcc{Data: "a"}
    20  	stepB := &TestStepAcc{Data: "b"}
    21  
    22  	r := &BasicRunner{Steps: []Step{stepA, stepB}}
    23  	r.Run(data)
    24  
    25  	// Test run data
    26  	expected := []string{"a", "b"}
    27  	results := data.Get("data").([]string)
    28  	if !reflect.DeepEqual(results, expected) {
    29  		t.Errorf("unexpected result: %#v", results)
    30  	}
    31  
    32  	// Test cleanup data
    33  	expected = []string{"b", "a"}
    34  	results = data.Get("cleanup").([]string)
    35  	if !reflect.DeepEqual(results, expected) {
    36  		t.Errorf("unexpected result: %#v", results)
    37  	}
    38  
    39  	// Test no halted or cancelled
    40  	if _, ok := data.GetOk(StateCancelled); ok {
    41  		t.Errorf("cancelled should not be in state bag")
    42  	}
    43  
    44  	if _, ok := data.GetOk(StateHalted); ok {
    45  		t.Errorf("halted should not be in state bag")
    46  	}
    47  }
    48  
    49  func TestBasicRunner_Run_Halt(t *testing.T) {
    50  	data := new(BasicStateBag)
    51  	stepA := &TestStepAcc{Data: "a"}
    52  	stepB := &TestStepAcc{Data: "b", Halt: true}
    53  	stepC := &TestStepAcc{Data: "c"}
    54  
    55  	r := &BasicRunner{Steps: []Step{stepA, stepB, stepC}}
    56  	r.Run(data)
    57  
    58  	// Test run data
    59  	expected := []string{"a", "b"}
    60  	results := data.Get("data").([]string)
    61  	if !reflect.DeepEqual(results, expected) {
    62  		t.Errorf("unexpected result: %#v", results)
    63  	}
    64  
    65  	// Test cleanup data
    66  	expected = []string{"b", "a"}
    67  	results = data.Get("cleanup").([]string)
    68  	if !reflect.DeepEqual(results, expected) {
    69  		t.Errorf("unexpected result: %#v", results)
    70  	}
    71  
    72  	// Test that it says it is halted
    73  	halted := data.Get(StateHalted).(bool)
    74  	if !halted {
    75  		t.Errorf("not halted")
    76  	}
    77  }
    78  
    79  // confirm that can't run twice
    80  func TestBasicRunner_Run_Run(t *testing.T) {
    81  	defer func() {
    82  		recover()
    83  	}()
    84  	ch := make(chan chan bool)
    85  	stepInt := &TestStepSync{ch}
    86  	stepWait := &TestStepWaitForever{}
    87  	r := &BasicRunner{Steps: []Step{stepInt, stepWait}}
    88  
    89  	go r.Run(new(BasicStateBag))
    90  	// wait until really running
    91  	<-ch
    92  
    93  	// now try to run aain
    94  	r.Run(new(BasicStateBag))
    95  
    96  	// should not get here in nominal codepath
    97  	t.Errorf("Was able to run an already running BasicRunner")
    98  }
    99  
   100  func TestBasicRunner_Cancel(t *testing.T) {
   101  	ch := make(chan chan bool)
   102  	data := new(BasicStateBag)
   103  	stepA := &TestStepAcc{Data: "a"}
   104  	stepB := &TestStepAcc{Data: "b"}
   105  	stepInt := &TestStepSync{ch}
   106  	stepC := &TestStepAcc{Data: "c"}
   107  
   108  	r := &BasicRunner{Steps: []Step{stepA, stepB, stepInt, stepC}}
   109  
   110  	// cancelling an idle Runner is a no-op
   111  	r.Cancel()
   112  
   113  	go r.Run(data)
   114  
   115  	// Wait until we reach the sync point
   116  	responseCh := <-ch
   117  
   118  	// Cancel then continue chain
   119  	cancelCh := make(chan bool)
   120  	go func() {
   121  		r.Cancel()
   122  		cancelCh <- true
   123  	}()
   124  
   125  	for {
   126  		if _, ok := data.GetOk(StateCancelled); ok {
   127  			responseCh <- true
   128  			break
   129  		}
   130  
   131  		time.Sleep(10 * time.Millisecond)
   132  	}
   133  
   134  	<-cancelCh
   135  
   136  	// Test run data
   137  	expected := []string{"a", "b"}
   138  	results := data.Get("data").([]string)
   139  	if !reflect.DeepEqual(results, expected) {
   140  		t.Errorf("unexpected result: %#v", results)
   141  	}
   142  
   143  	// Test cleanup data
   144  	expected = []string{"b", "a"}
   145  	results = data.Get("cleanup").([]string)
   146  	if !reflect.DeepEqual(results, expected) {
   147  		t.Errorf("unexpected result: %#v", results)
   148  	}
   149  
   150  	// Test that it says it is cancelled
   151  	cancelled := data.Get(StateCancelled).(bool)
   152  	if !cancelled {
   153  		t.Errorf("not cancelled")
   154  	}
   155  }
   156  
   157  func TestBasicRunner_Cancel_Special(t *testing.T) {
   158  	stepOne := &TestStepInjectCancel{}
   159  	stepTwo := &TestStepInjectCancel{}
   160  	r := &BasicRunner{Steps: []Step{stepOne, stepTwo}}
   161  
   162  	state := new(BasicStateBag)
   163  	state.Put("runner", r)
   164  	r.Run(state)
   165  
   166  	// test that state contains cancelled
   167  	if _, ok := state.GetOk(StateCancelled); !ok {
   168  		t.Errorf("cancelled should be in state bag")
   169  	}
   170  }