github.phpd.cn/hashicorp/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 }