github.com/kevinklinger/open_terraform@v1.3.6/noninternal/communicator/winrm/communicator_test.go (about)

     1  package winrm
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"regexp"
     7  	"strconv"
     8  	"testing"
     9  
    10  	"github.com/dylanmei/winrmtest"
    11  	"github.com/kevinklinger/open_terraform/noninternal/communicator/remote"
    12  	"github.com/kevinklinger/open_terraform/noninternal/communicator/shared"
    13  	"github.com/zclconf/go-cty/cty"
    14  )
    15  
    16  func newMockWinRMServer(t *testing.T) *winrmtest.Remote {
    17  	wrm := winrmtest.NewRemote()
    18  
    19  	wrm.CommandFunc(
    20  		winrmtest.MatchText("echo foo"),
    21  		func(out, err io.Writer) int {
    22  			out.Write([]byte("foo"))
    23  			return 0
    24  		})
    25  
    26  	wrm.CommandFunc(
    27  		winrmtest.MatchPattern(`^echo c29tZXRoaW5n >> ".*"$`),
    28  		func(out, err io.Writer) int {
    29  			return 0
    30  		})
    31  
    32  	wrm.CommandFunc(
    33  		winrmtest.MatchPattern(`^powershell.exe -EncodedCommand .*$`),
    34  		func(out, err io.Writer) int {
    35  			return 0
    36  		})
    37  
    38  	wrm.CommandFunc(
    39  		winrmtest.MatchText("powershell"),
    40  		func(out, err io.Writer) int {
    41  			return 0
    42  		})
    43  
    44  	return wrm
    45  }
    46  
    47  func TestStart(t *testing.T) {
    48  	wrm := newMockWinRMServer(t)
    49  	defer wrm.Close()
    50  
    51  	v := cty.ObjectVal(map[string]cty.Value{
    52  		"type":     cty.StringVal("winrm"),
    53  		"user":     cty.StringVal("user"),
    54  		"password": cty.StringVal("pass"),
    55  		"host":     cty.StringVal(wrm.Host),
    56  		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
    57  		"timeout":  cty.StringVal("30s"),
    58  	})
    59  
    60  	c, err := New(v)
    61  	if err != nil {
    62  		t.Fatalf("error creating communicator: %s", err)
    63  	}
    64  
    65  	var cmd remote.Cmd
    66  	stdout := new(bytes.Buffer)
    67  	cmd.Command = "echo foo"
    68  	cmd.Stdout = stdout
    69  
    70  	err = c.Start(&cmd)
    71  	if err != nil {
    72  		t.Fatalf("error executing remote command: %s", err)
    73  	}
    74  	cmd.Wait()
    75  
    76  	if stdout.String() != "foo" {
    77  		t.Fatalf("bad command response: expected %q, got %q", "foo", stdout.String())
    78  	}
    79  }
    80  
    81  func TestUpload(t *testing.T) {
    82  	wrm := newMockWinRMServer(t)
    83  	defer wrm.Close()
    84  	v := cty.ObjectVal(map[string]cty.Value{
    85  		"type":     cty.StringVal("winrm"),
    86  		"user":     cty.StringVal("user"),
    87  		"password": cty.StringVal("pass"),
    88  		"host":     cty.StringVal(wrm.Host),
    89  		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
    90  		"timeout":  cty.StringVal("30s"),
    91  	})
    92  
    93  	c, err := New(v)
    94  	if err != nil {
    95  		t.Fatalf("error creating communicator: %s", err)
    96  	}
    97  
    98  	err = c.Connect(nil)
    99  	if err != nil {
   100  		t.Fatalf("error connecting communicator: %s", err)
   101  	}
   102  	defer c.Disconnect()
   103  
   104  	err = c.Upload("C:/Temp/terraform.cmd", bytes.NewReader([]byte("something")))
   105  	if err != nil {
   106  		t.Fatalf("error uploading file: %s", err)
   107  	}
   108  }
   109  
   110  func TestScriptPath(t *testing.T) {
   111  	cases := []struct {
   112  		Input   string
   113  		Pattern string
   114  	}{
   115  		{
   116  			"/tmp/script.sh",
   117  			`^/tmp/script\.sh$`,
   118  		},
   119  		{
   120  			"/tmp/script_%RAND%.sh",
   121  			`^/tmp/script_(\d+)\.sh$`,
   122  		},
   123  	}
   124  
   125  	for _, tc := range cases {
   126  		v := cty.ObjectVal(map[string]cty.Value{
   127  			"host":        cty.StringVal(""),
   128  			"type":        cty.StringVal("winrm"),
   129  			"script_path": cty.StringVal(tc.Input),
   130  		})
   131  
   132  		comm, err := New(v)
   133  		if err != nil {
   134  			t.Fatalf("err: %s", err)
   135  		}
   136  		output := comm.ScriptPath()
   137  
   138  		match, err := regexp.Match(tc.Pattern, []byte(output))
   139  		if err != nil {
   140  			t.Fatalf("bad: %s\n\nerr: %s", tc.Input, err)
   141  		}
   142  		if !match {
   143  			t.Fatalf("bad: %s\n\n%s", tc.Input, output)
   144  		}
   145  	}
   146  }
   147  
   148  func TestNoTransportDecorator(t *testing.T) {
   149  	wrm := newMockWinRMServer(t)
   150  	defer wrm.Close()
   151  	v := cty.ObjectVal(map[string]cty.Value{
   152  		"type":     cty.StringVal("winrm"),
   153  		"user":     cty.StringVal("user"),
   154  		"password": cty.StringVal("pass"),
   155  		"host":     cty.StringVal(wrm.Host),
   156  		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
   157  		"timeout":  cty.StringVal("30s"),
   158  	})
   159  
   160  	c, err := New(v)
   161  	if err != nil {
   162  		t.Fatalf("error creating communicator: %s", err)
   163  	}
   164  
   165  	err = c.Connect(nil)
   166  	if err != nil {
   167  		t.Fatalf("error connecting communicator: %s", err)
   168  	}
   169  	defer c.Disconnect()
   170  
   171  	if c.client.TransportDecorator != nil {
   172  		t.Fatal("bad TransportDecorator: expected nil, got non-nil")
   173  	}
   174  }
   175  
   176  func TestTransportDecorator(t *testing.T) {
   177  	wrm := newMockWinRMServer(t)
   178  	defer wrm.Close()
   179  
   180  	v := cty.ObjectVal(map[string]cty.Value{
   181  		"type":     cty.StringVal("winrm"),
   182  		"user":     cty.StringVal("user"),
   183  		"password": cty.StringVal("pass"),
   184  		"host":     cty.StringVal(wrm.Host),
   185  		"port":     cty.StringVal(strconv.Itoa(wrm.Port)),
   186  		"use_ntlm": cty.StringVal("true"),
   187  		"timeout":  cty.StringVal("30s"),
   188  	})
   189  
   190  	c, err := New(v)
   191  	if err != nil {
   192  		t.Fatalf("error creating communicator: %s", err)
   193  	}
   194  
   195  	err = c.Connect(nil)
   196  	if err != nil {
   197  		t.Fatalf("error connecting communicator: %s", err)
   198  	}
   199  	defer c.Disconnect()
   200  
   201  	if c.client.TransportDecorator == nil {
   202  		t.Fatal("bad TransportDecorator: expected non-nil, got nil")
   203  	}
   204  }
   205  
   206  func TestScriptPath_randSeed(t *testing.T) {
   207  	// Pre GH-4186 fix, this value was the deterministic start the pseudorandom
   208  	// chain of unseeded math/rand values for Int31().
   209  	staticSeedPath := "C:/Temp/terraform_1298498081.cmd"
   210  	c, err := New(cty.NullVal(shared.ConnectionBlockSupersetSchema.ImpliedType()))
   211  	if err != nil {
   212  		t.Fatalf("err: %s", err)
   213  	}
   214  	path := c.ScriptPath()
   215  	if path == staticSeedPath {
   216  		t.Fatalf("rand not seeded! got: %s", path)
   217  	}
   218  }