github.com/rothwerx/packer@v0.9.0/builder/vmware/common/step_shutdown_test.go (about)

     1  package common
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/mitchellh/multistep"
    11  	"github.com/mitchellh/packer/packer"
    12  )
    13  
    14  func testStepShutdownState(t *testing.T) multistep.StateBag {
    15  	dir := testOutputDir(t)
    16  	if err := dir.MkdirAll(); err != nil {
    17  		t.Fatalf("err: %s", err)
    18  	}
    19  
    20  	state := testState(t)
    21  	state.Put("communicator", new(packer.MockCommunicator))
    22  	state.Put("dir", dir)
    23  	state.Put("vmx_path", "foo")
    24  	return state
    25  }
    26  
    27  func TestStepShutdown_impl(t *testing.T) {
    28  	var _ multistep.Step = new(StepShutdown)
    29  }
    30  
    31  func TestStepShutdown_command(t *testing.T) {
    32  	state := testStepShutdownState(t)
    33  	step := new(StepShutdown)
    34  	step.Command = "foo"
    35  	step.Timeout = 10 * time.Second
    36  	step.Testing = true
    37  
    38  	comm := state.Get("communicator").(*packer.MockCommunicator)
    39  	driver := state.Get("driver").(*DriverMock)
    40  	driver.IsRunningResult = true
    41  
    42  	// Set not running after some time
    43  	go func() {
    44  		time.Sleep(100 * time.Millisecond)
    45  		driver.Lock()
    46  		defer driver.Unlock()
    47  		driver.IsRunningResult = false
    48  	}()
    49  
    50  	resultCh := make(chan multistep.StepAction, 1)
    51  	go func() {
    52  		resultCh <- step.Run(state)
    53  	}()
    54  
    55  	select {
    56  	case <-resultCh:
    57  		t.Fatal("should not have returned so quickly")
    58  	case <-time.After(50 * time.Millisecond):
    59  	}
    60  
    61  	var action multistep.StepAction
    62  	select {
    63  	case action = <-resultCh:
    64  	case <-time.After(300 * time.Millisecond):
    65  		t.Fatal("should've returned by now")
    66  	}
    67  
    68  	// Test the run
    69  	if action != multistep.ActionContinue {
    70  		t.Fatalf("bad action: %#v", action)
    71  	}
    72  	if _, ok := state.GetOk("error"); ok {
    73  		t.Fatal("should NOT have error")
    74  	}
    75  
    76  	// Test the driver
    77  	if driver.StopCalled {
    78  		t.Fatal("stop should not be called")
    79  	}
    80  
    81  	if !comm.StartCalled {
    82  		t.Fatal("start should be called")
    83  	}
    84  	if comm.StartCmd.Command != "foo" {
    85  		t.Fatalf("bad: %#v", comm.StartCmd.Command)
    86  	}
    87  }
    88  
    89  func TestStepShutdown_noCommand(t *testing.T) {
    90  	state := testStepShutdownState(t)
    91  	step := new(StepShutdown)
    92  
    93  	comm := state.Get("communicator").(*packer.MockCommunicator)
    94  	driver := state.Get("driver").(*DriverMock)
    95  
    96  	// Test the run
    97  	if action := step.Run(state); action != multistep.ActionContinue {
    98  		t.Fatalf("bad action: %#v", action)
    99  	}
   100  	if _, ok := state.GetOk("error"); ok {
   101  		t.Fatal("should NOT have error")
   102  	}
   103  
   104  	// Test the driver
   105  	if !driver.StopCalled {
   106  		t.Fatal("stop should be called")
   107  	}
   108  	if driver.StopPath != "foo" {
   109  		t.Fatal("should call with right path")
   110  	}
   111  
   112  	if comm.StartCalled {
   113  		t.Fatal("start should not be called")
   114  	}
   115  }
   116  
   117  func TestStepShutdown_locks(t *testing.T) {
   118  	state := testStepShutdownState(t)
   119  	step := new(StepShutdown)
   120  	step.Testing = true
   121  
   122  	dir := state.Get("dir").(*LocalOutputDir)
   123  	comm := state.Get("communicator").(*packer.MockCommunicator)
   124  	driver := state.Get("driver").(*DriverMock)
   125  
   126  	// Create some lock files
   127  	lockPath := filepath.Join(dir.dir, "nope.lck")
   128  	err := ioutil.WriteFile(lockPath, []byte("foo"), 0644)
   129  	if err != nil {
   130  		t.Fatalf("err: %s", err)
   131  	}
   132  
   133  	// Remove the lock file after a certain time
   134  	go func() {
   135  		time.Sleep(100 * time.Millisecond)
   136  		os.Remove(lockPath)
   137  	}()
   138  
   139  	resultCh := make(chan multistep.StepAction, 1)
   140  	go func() {
   141  		resultCh <- step.Run(state)
   142  	}()
   143  
   144  	select {
   145  	case <-resultCh:
   146  		t.Fatal("should not have returned so quickly")
   147  	case <-time.After(50 * time.Millisecond):
   148  	}
   149  
   150  	var action multistep.StepAction
   151  	select {
   152  	case action = <-resultCh:
   153  	case <-time.After(300 * time.Millisecond):
   154  		t.Fatal("should've returned by now")
   155  	}
   156  
   157  	// Test the run
   158  	if action != multistep.ActionContinue {
   159  		t.Fatalf("bad action: %#v", action)
   160  	}
   161  	if _, ok := state.GetOk("error"); ok {
   162  		t.Fatal("should NOT have error")
   163  	}
   164  
   165  	// Test the driver
   166  	if !driver.StopCalled {
   167  		t.Fatal("stop should be called")
   168  	}
   169  	if driver.StopPath != "foo" {
   170  		t.Fatal("should call with right path")
   171  	}
   172  
   173  	if comm.StartCalled {
   174  		t.Fatal("start should not be called")
   175  	}
   176  }