func TestProvision_waitForCommunicator(t *testing.T) { config := testConfig() // Defaults provided by Packer ui := testUi() p := new(Provisioner) // Defaults provided by Packer comm := new(packer.MockCommunicator) p.comm = comm p.ui = ui comm.StartStderr = "WinRM terminated" comm.StartExitStatus = 1 p.Prepare(config) err := waitForCommunicator(p) if err != nil { t.Fatalf("should not have error, got: %s", err.Error()) } expectedCommand := DefaultRestartCheckCommand // Should run the command without alteration if comm.StartCmd.Command != expectedCommand { t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command) } }
func TestProvisionerProvision_RestartCommandFail(t *testing.T) { config := testConfig() ui := testUi() p := new(Provisioner) comm := new(packer.MockCommunicator) comm.StartStderr = "WinRM terminated" comm.StartExitStatus = 1 p.Prepare(config) err := p.Provision(ui, comm) if err == nil { t.Fatal("should have error") } }
func TestStepUpdateGcloud_badExitStatus(t *testing.T) { state := testState(t) step := new(StepUpdateGcloud) defer step.Cleanup(state) comm := new(packer.MockCommunicator) comm.StartExitStatus = 12 state.Put("communicator", comm) // run the step if action := step.Run(state); action != multistep.ActionHalt { t.Fatalf("bad action: %#v", action) } if _, ok := state.GetOk("error"); !ok { t.Fatal("should have error") } }
func TestProvision_waitForCommunicatorWithCancel(t *testing.T) { config := testConfig() // Defaults provided by Packer ui := testUi() p := new(Provisioner) // Defaults provided by Packer comm := new(packer.MockCommunicator) p.comm = comm p.ui = ui retryableSleep = 5 * time.Second p.cancel = make(chan struct{}) var err error comm.StartStderr = "WinRM terminated" comm.StartExitStatus = 1 // Always fail p.Prepare(config) // Run 2 goroutines; // 1st to call waitForCommunicator (that will always fail) // 2nd to cancel the operation waitStart := make(chan bool) waitDone := make(chan bool) go func() { waitStart <- true err = waitForCommunicator(p) waitDone <- true }() go func() { time.Sleep(10 * time.Millisecond) <-waitStart p.Cancel() }() <-waitDone // Expect a Cancel error if err == nil { t.Fatalf("Should have err") } }
func TestProvisionerProvision_InvalidExitCodes(t *testing.T) { config := testConfig() delete(config, "inline") // Defaults provided by Packer config["remote_path"] = "c:/Windows/Temp/inlineScript.bat" config["inline"] = []string{"whoami"} ui := testUi() p := new(Provisioner) // Defaults provided by Packer p.config.PackerBuildName = "vmware" p.config.PackerBuilderType = "iso" p.config.ValidExitCodes = []int{0, 200} comm := new(packer.MockCommunicator) comm.StartExitStatus = 201 // Invalid! p.Prepare(config) err := p.Provision(ui, comm) if err == nil { t.Fatal("should have error") } }
func TestCommunicatorRPC(t *testing.T) { // Create the interface to test c := new(packer.MockCommunicator) // Start the server server := rpc.NewServer() RegisterCommunicator(server, c) address := serveSingleConn(server) // Create the client over RPC and run some methods to verify it works client, err := rpc.Dial("tcp", address) if err != nil { t.Fatalf("err: %s", err) } remote := Communicator(client) // The remote command we'll use stdin_r, stdin_w := io.Pipe() stdout_r, stdout_w := io.Pipe() stderr_r, stderr_w := io.Pipe() var cmd packer.RemoteCmd cmd.Command = "foo" cmd.Stdin = stdin_r cmd.Stdout = stdout_w cmd.Stderr = stderr_w // Send some data on stdout and stderr from the mock c.StartStdout = "outfoo\n" c.StartStderr = "errfoo\n" c.StartExitStatus = 42 // Test Start err = remote.Start(&cmd) if err != nil { t.Fatalf("err: %s", err) } // Test that we can read from stdout bufOut := bufio.NewReader(stdout_r) data, err := bufOut.ReadString('\n') if err != nil { t.Fatalf("err: %s", err) } if data != "outfoo\n" { t.Fatalf("bad data: %s", data) } // Test that we can read from stderr bufErr := bufio.NewReader(stderr_r) data, err = bufErr.ReadString('\n') if err != nil { t.Fatalf("err: %s", err) } if data != "errfoo\n" { t.Fatalf("bad data: %s", data) } // Test that we can write to stdin stdin_w.Write([]byte("info\n")) stdin_w.Close() cmd.Wait() if c.StartStdin != "info\n" { t.Fatalf("bad data: %s", data) } // Test that we can get the exit status properly if cmd.ExitStatus != 42 { t.Fatalf("bad exit: %d", cmd.ExitStatus) } // Test that we can upload things uploadR, uploadW := io.Pipe() go func() { defer uploadW.Close() uploadW.Write([]byte("uploadfoo\n")) }() err = remote.Upload("foo", uploadR) if err != nil { t.Fatalf("err: %s", err) } if !c.UploadCalled { t.Fatal("should have uploaded") } if c.UploadPath != "foo" { t.Fatalf("path: %s", c.UploadPath) } if c.UploadData != "uploadfoo\n" { t.Fatalf("bad: %s", c.UploadData) } // Test that we can upload directories dirDst := "foo" dirSrc := "bar" dirExcl := []string{"foo"} err = remote.UploadDir(dirDst, dirSrc, dirExcl) if err != nil { t.Fatalf("err: %s", err) } if c.UploadDirDst != dirDst { t.Fatalf("bad: %s", c.UploadDirDst) } if c.UploadDirSrc != dirSrc { t.Fatalf("bad: %s", c.UploadDirSrc) } if !reflect.DeepEqual(c.UploadDirExclude, dirExcl) { t.Fatalf("bad: %#v", c.UploadDirExclude) } // Test that we can download things downloadR, downloadW := io.Pipe() downloadDone := make(chan bool) var downloadData string var downloadErr error go func() { bufDownR := bufio.NewReader(downloadR) downloadData, downloadErr = bufDownR.ReadString('\n') downloadDone <- true }() c.DownloadData = "download\n" err = remote.Download("bar", downloadW) if err != nil { t.Fatalf("err: %s", err) } if !c.DownloadCalled { t.Fatal("download should be called") } if c.DownloadPath != "bar" { t.Fatalf("bad: %s", c.DownloadPath) } <-downloadDone if downloadErr != nil { t.Fatalf("err: %s", downloadErr) } if downloadData != "download\n" { t.Fatalf("bad: %s", downloadData) } }