github.com/mitchellh/packer@v1.3.2/builder/vmware/common/step_shutdown_test.go (about)

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