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 }