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 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 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) } }