winrm 1.8.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -11
  3. data/.rubocop.yml +26 -22
  4. data/.travis.yml +11 -12
  5. data/Gemfile +3 -9
  6. data/LICENSE +202 -202
  7. data/README.md +232 -215
  8. data/Rakefile +34 -36
  9. data/Vagrantfile +6 -9
  10. data/WinrmAppveyor.psm1 +31 -31
  11. data/appveyor.yml +51 -51
  12. data/bin/rwinrm +97 -97
  13. data/changelog.md +86 -86
  14. data/lib/winrm.rb +39 -42
  15. data/lib/winrm/connection.rb +82 -0
  16. data/lib/winrm/connection_opts.rb +87 -0
  17. data/lib/winrm/{exceptions/exceptions.rb → exceptions.rb} +76 -57
  18. data/lib/winrm/http/response_handler.rb +96 -82
  19. data/lib/winrm/http/transport.rb +424 -435
  20. data/lib/winrm/http/transport_factory.rb +68 -0
  21. data/lib/winrm/output.rb +59 -43
  22. data/lib/winrm/psrp/create_pipeline.xml.erb +167 -0
  23. data/lib/winrm/psrp/fragment.rb +70 -0
  24. data/lib/winrm/psrp/init_runspace_pool.xml.erb +224 -0
  25. data/lib/winrm/psrp/message.rb +130 -0
  26. data/lib/winrm/psrp/message_data.rb +41 -0
  27. data/lib/winrm/psrp/message_data/base.rb +49 -0
  28. data/lib/winrm/psrp/message_data/error_record.rb +68 -0
  29. data/lib/winrm/psrp/message_data/pipeline_host_call.rb +32 -0
  30. data/lib/winrm/psrp/message_data/pipeline_output.rb +49 -0
  31. data/lib/winrm/psrp/message_data/runspacepool_host_call.rb +32 -0
  32. data/lib/winrm/psrp/message_data/runspacepool_state.rb +39 -0
  33. data/lib/winrm/psrp/message_data/session_capability.rb +36 -0
  34. data/lib/winrm/psrp/message_defragmenter.rb +62 -0
  35. data/lib/winrm/psrp/message_factory.rb +75 -0
  36. data/lib/winrm/psrp/message_fragmenter.rb +60 -0
  37. data/lib/winrm/psrp/powershell_output_decoder.rb +120 -0
  38. data/lib/winrm/psrp/receive_response_reader.rb +93 -0
  39. data/lib/winrm/psrp/session_capability.xml.erb +7 -0
  40. data/lib/winrm/psrp/uuid.rb +40 -0
  41. data/lib/winrm/shells/base.rb +175 -0
  42. data/lib/winrm/shells/cmd.rb +65 -0
  43. data/lib/winrm/shells/power_shell.rb +201 -0
  44. data/lib/winrm/shells/retryable.rb +45 -0
  45. data/lib/winrm/shells/shell_factory.rb +50 -0
  46. data/lib/winrm/version.rb +7 -7
  47. data/lib/winrm/wsmv/base.rb +59 -0
  48. data/lib/winrm/wsmv/cleanup_command.rb +61 -0
  49. data/lib/winrm/wsmv/close_shell.rb +50 -0
  50. data/lib/winrm/wsmv/command.rb +101 -0
  51. data/lib/winrm/wsmv/command_output.rb +76 -0
  52. data/lib/winrm/wsmv/command_output_decoder.rb +55 -0
  53. data/lib/winrm/wsmv/configuration.rb +46 -0
  54. data/lib/winrm/wsmv/create_pipeline.rb +66 -0
  55. data/lib/winrm/wsmv/create_shell.rb +119 -0
  56. data/lib/winrm/wsmv/header.rb +203 -0
  57. data/lib/winrm/wsmv/init_runspace_pool.rb +95 -0
  58. data/lib/winrm/wsmv/iso8601_duration.rb +60 -0
  59. data/lib/winrm/wsmv/keep_alive.rb +68 -0
  60. data/lib/winrm/wsmv/receive_response_reader.rb +128 -0
  61. data/lib/winrm/wsmv/send_data.rb +68 -0
  62. data/lib/winrm/wsmv/soap.rb +51 -0
  63. data/lib/winrm/wsmv/wql_query.rb +79 -0
  64. data/lib/winrm/wsmv/write_stdin.rb +88 -0
  65. data/preamble +17 -17
  66. data/{spec → tests/integration}/auth_timeout_spec.rb +18 -16
  67. data/{spec → tests/integration}/cmd_spec.rb +104 -102
  68. data/{spec → tests/integration}/config-example.yml +16 -19
  69. data/{spec → tests/integration}/issue_59_spec.rb +26 -23
  70. data/tests/integration/powershell_spec.rb +154 -0
  71. data/{spec → tests/integration}/spec_helper.rb +65 -73
  72. data/{spec → tests/integration}/transport_spec.rb +99 -139
  73. data/{spec → tests/integration}/wql_spec.rb +16 -14
  74. data/{spec → tests}/matchers.rb +60 -74
  75. data/tests/spec/configuration_spec.rb +93 -0
  76. data/tests/spec/connection_spec.rb +39 -0
  77. data/{spec → tests/spec}/exception_spec.rb +50 -50
  78. data/tests/spec/http/transport_factory_spec.rb +68 -0
  79. data/tests/spec/http/transport_spec.rb +44 -0
  80. data/{spec → tests/spec}/output_spec.rb +127 -110
  81. data/tests/spec/psrp/fragment_spec.rb +62 -0
  82. data/tests/spec/psrp/message_data/base_spec.rb +13 -0
  83. data/tests/spec/psrp/message_data/error_record_spec.rb +41 -0
  84. data/tests/spec/psrp/message_data/pipeline_host_call_spec.rb +25 -0
  85. data/tests/spec/psrp/message_data/pipeline_output_spec.rb +32 -0
  86. data/tests/spec/psrp/message_data/runspace_pool_host_call_spec.rb +25 -0
  87. data/tests/spec/psrp/message_data/runspacepool_state_spec.rb +16 -0
  88. data/tests/spec/psrp/message_data/session_capability_spec.rb +30 -0
  89. data/tests/spec/psrp/message_data_spec.rb +35 -0
  90. data/tests/spec/psrp/message_defragmenter_spec.rb +47 -0
  91. data/tests/spec/psrp/message_fragmenter_spec.rb +105 -0
  92. data/tests/spec/psrp/powershell_output_decoder_spec.rb +84 -0
  93. data/tests/spec/psrp/psrp_message_spec.rb +70 -0
  94. data/tests/spec/psrp/recieve_response_reader_spec.rb +154 -0
  95. data/tests/spec/psrp/uuid_spec.rb +28 -0
  96. data/{spec → tests/spec}/response_handler_spec.rb +61 -61
  97. data/tests/spec/shells/base_spec.rb +202 -0
  98. data/tests/spec/shells/cmd_spec.rb +75 -0
  99. data/tests/spec/shells/powershell_spec.rb +175 -0
  100. data/tests/spec/spec_helper.rb +47 -0
  101. data/tests/spec/stubs/clixml/error_record.xml.erb +84 -0
  102. data/{spec → tests/spec}/stubs/responses/get_command_output_response.xml.erb +13 -13
  103. data/tests/spec/stubs/responses/get_command_output_response_not_done.xml.erb +10 -0
  104. data/tests/spec/stubs/responses/get_powershell_keepalive_response.xml.erb +10 -0
  105. data/tests/spec/stubs/responses/get_powershell_output_response.xml.erb +12 -0
  106. data/tests/spec/stubs/responses/get_powershell_output_response_not_done.xml.erb +9 -0
  107. data/{spec → tests/spec}/stubs/responses/open_shell_v1.xml +19 -19
  108. data/{spec → tests/spec}/stubs/responses/open_shell_v2.xml +20 -20
  109. data/{spec → tests/spec}/stubs/responses/soap_fault_v1.xml +36 -36
  110. data/{spec → tests/spec}/stubs/responses/soap_fault_v2.xml +42 -42
  111. data/{spec → tests/spec}/stubs/responses/wmi_error_v2.xml +41 -41
  112. data/tests/spec/wsmv/cleanup_command_spec.rb +22 -0
  113. data/tests/spec/wsmv/close_shell_spec.rb +17 -0
  114. data/{spec → tests/spec/wsmv}/command_output_decoder_spec.rb +37 -37
  115. data/tests/spec/wsmv/command_output_spec.rb +45 -0
  116. data/tests/spec/wsmv/command_spec.rb +19 -0
  117. data/tests/spec/wsmv/configuration_spec.rb +17 -0
  118. data/tests/spec/wsmv/create_pipeline_spec.rb +31 -0
  119. data/tests/spec/wsmv/create_shell_spec.rb +38 -0
  120. data/tests/spec/wsmv/init_runspace_pool_spec.rb +36 -0
  121. data/tests/spec/wsmv/keep_alive_spec.rb +21 -0
  122. data/tests/spec/wsmv/receive_response_reader_spec.rb +123 -0
  123. data/tests/spec/wsmv/send_data_spec.rb +30 -0
  124. data/tests/spec/wsmv/wql_query_spec.rb +13 -0
  125. data/tests/spec/wsmv/write_stdin_spec.rb +22 -0
  126. data/winrm.gemspec +42 -40
  127. metadata +140 -38
  128. data/.rspec +0 -3
  129. data/lib/winrm/command_executor.rb +0 -243
  130. data/lib/winrm/command_output_decoder.rb +0 -53
  131. data/lib/winrm/helpers/iso8601_duration.rb +0 -58
  132. data/lib/winrm/helpers/powershell_script.rb +0 -42
  133. data/lib/winrm/soap_provider.rb +0 -39
  134. data/lib/winrm/winrm_service.rb +0 -550
  135. data/spec/command_executor_spec.rb +0 -475
  136. data/spec/issue_184_spec.rb +0 -67
  137. data/spec/powershell_spec.rb +0 -97
  138. data/spec/winrm_options_spec.rb +0 -76
  139. data/spec/winrm_primitives_spec.rb +0 -51
@@ -1,475 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2015, Fletcher Nichol
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the 'License');
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an 'AS IS' BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
-
19
- require 'winrm/command_executor'
20
-
21
- require 'base64'
22
- require 'securerandom'
23
-
24
- describe WinRM::CommandExecutor, unit: true do
25
- let(:logged_output) { StringIO.new }
26
- let(:shell_id) { 'shell-123' }
27
- let(:executor_args) { [service, logger] }
28
- let(:executor) { WinRM::CommandExecutor.new(service) }
29
- let(:service) do
30
- double(
31
- 'winrm_service',
32
- logger: Logging.logger['test'],
33
- retry_limit: 1,
34
- retry_delay: 1
35
- )
36
- end
37
-
38
- let(:version_output) { { xml_fragment: [{ version: '6.3.9600' }] } }
39
-
40
- before do
41
- allow(service).to receive(:open_shell).and_return(shell_id)
42
- allow(service).to receive(:run_wql).and_return(version_output)
43
- end
44
-
45
- describe '#close' do
46
- it 'calls service#close_shell' do
47
- executor.open
48
- expect(service).to receive(:close_shell).with(shell_id)
49
-
50
- executor.close
51
- end
52
-
53
- it 'only calls service#close_shell once for multiple calls' do
54
- executor.open
55
- expect(service).to receive(:close_shell).with(shell_id).once
56
-
57
- executor.close
58
- executor.close
59
- executor.close
60
- end
61
-
62
- it 'undefines finalizer' do
63
- allow(service).to receive(:close_shell)
64
- allow(ObjectSpace).to receive(:define_finalizer) { |e, _| e == executor }
65
- expect(ObjectSpace).to receive(:undefine_finalizer).with(executor)
66
- executor.open
67
-
68
- executor.close
69
- end
70
- end
71
-
72
- describe '#open' do
73
- it 'calls service#open_shell' do
74
- expect(service).to receive(:open_shell).and_return(shell_id)
75
-
76
- executor.open
77
- end
78
-
79
- it 'defines a finalizer' do
80
- expect(ObjectSpace).to receive(:define_finalizer) do |e, _|
81
- expect(e).to eq(executor)
82
- end
83
-
84
- executor.open
85
- end
86
-
87
- it 'returns a shell id as a string' do
88
- expect(executor.open).to eq shell_id
89
- end
90
-
91
- describe 'failed connection attempts' do
92
- let(:error) { HTTPClient::ConnectTimeoutError }
93
- let(:limit) { 3 }
94
- let(:delay) { 0.1 }
95
-
96
- before do
97
- allow(service).to receive(:open_shell).and_raise(error)
98
- allow(service).to receive(:retry_delay).and_return(delay)
99
- allow(service).to receive(:retry_limit).and_return(limit)
100
- end
101
-
102
- it 'attempts to connect :retry_limit times' do
103
- begin
104
- allow(service).to receive(:open_shell).exactly.times(limit)
105
- executor.open
106
- rescue # rubocop:disable Lint/HandleExceptions
107
- # the raise is not what is being tested here, rather its side-effect
108
- end
109
- end
110
-
111
- it 'raises the inner error after retries' do
112
- expect { executor.open }.to raise_error(error)
113
- end
114
- end
115
-
116
- describe 'for modern windows distributions' do
117
- let(:version_output) { { xml_fragment: [{ version: '10.0.10586.63' }] } }
118
-
119
- it 'sets #max_commands to 1500 - 2' do
120
- expect(executor.max_commands).to eq(1500 - 2)
121
- end
122
-
123
- it 'sets code_page to UTF-8' do
124
- expect(executor.code_page).to eq 65_001
125
- end
126
- end
127
-
128
- describe 'for older/legacy windows distributions' do
129
- let(:version_output) { { xml_fragment: [{ version: '6.1.8500' }] } }
130
-
131
- it 'sets #max_commands to 15 - 2' do
132
- expect(executor.max_commands).to eq(15 - 2)
133
- end
134
-
135
- it 'sets code_page to UTF-8' do
136
- expect(executor.code_page).to eq 65_001
137
- end
138
- end
139
-
140
- describe 'for super duper older/legacy windows distributions' do
141
- let(:version_output) { { xml_fragment: [{ version: '6.0.8500' }] } }
142
-
143
- it 'sets #max_commands to 15 - 2' do
144
- expect(executor.max_commands).to eq(15 - 2)
145
- end
146
-
147
- it 'sets code_page to MS-DOS' do
148
- expect(executor.code_page).to eq 437
149
- end
150
- end
151
-
152
- describe 'when unable to find os version' do
153
- let(:version_output) { { xml_fragment: [{ funny_clowns: 'haha' }] } }
154
-
155
- it 'raises WinRMError' do
156
- expect { executor.code_page }.to raise_error(
157
- ::WinRM::WinRMError,
158
- 'Unable to determine endpoint os version'
159
- )
160
- end
161
- end
162
- end
163
-
164
- describe '#run_cmd' do
165
- describe 'when #open has not been previously called' do
166
- it 'raises a WinRMError error' do
167
- expect { executor.run_cmd('nope') }.to raise_error(
168
- ::WinRM::WinRMError,
169
- "#{executor.class}#open must be called before any run methods are invoked"
170
- )
171
- end
172
- end
173
-
174
- describe 'when #open has been previously called' do
175
- let(:command_id) { 'command-123' }
176
-
177
- let(:echo_output) do
178
- o = ::WinRM::Output.new
179
- o[:exitcode] = 0
180
- o[:data].concat([
181
- { stdout: 'Hello\r\n' },
182
- { stderr: 'Psst\r\n' }
183
- ])
184
- o
185
- end
186
-
187
- before do
188
- stub_cmd(shell_id, 'echo', ['Hello'], echo_output, command_id)
189
-
190
- executor.open
191
- end
192
-
193
- it 'calls service#run_command' do
194
- expect(service).to receive(:run_command).with(shell_id, 'echo', ['Hello'])
195
-
196
- executor.run_cmd('echo', ['Hello'])
197
- end
198
-
199
- it 'calls service#get_command_output to get results' do
200
- expect(service).to receive(:get_command_output).with(shell_id, command_id)
201
-
202
- executor.run_cmd('echo', ['Hello'])
203
- end
204
-
205
- it 'calls service#get_command_output with a block to get results' do
206
- blk = proc { |_, _| 'something' }
207
- expect(service).to receive(:get_command_output).with(shell_id, command_id, &blk)
208
-
209
- executor.run_cmd('echo', ['Hello'], &blk)
210
- end
211
-
212
- it 'returns an Output object hash' do
213
- expect(executor.run_cmd('echo', ['Hello'])).to eq echo_output
214
- end
215
-
216
- it 'runs the block in #get_command_output when given' do
217
- io_out = StringIO.new
218
- io_err = StringIO.new
219
- stub_cmd(
220
- shell_id,
221
- 'echo',
222
- ['Hello'],
223
- echo_output,
224
- command_id
225
- ).and_yield(echo_output.stdout, echo_output.stderr)
226
- output = executor.run_cmd('echo', ['Hello']) do |stdout, stderr|
227
- io_out << stdout if stdout
228
- io_err << stderr if stderr
229
- end
230
-
231
- expect(io_out.string).to eq 'Hello\r\n'
232
- expect(io_err.string).to eq 'Psst\r\n'
233
- expect(output).to eq echo_output
234
- end
235
-
236
- shared_examples 'retry shell command' do
237
- it 'does not close the current shell' do
238
- expect(service).not_to receive(:close_shell)
239
-
240
- executor.run_cmd('echo', ['Hello'])
241
- end
242
-
243
- it 'opens a new shell once' do
244
- expect(service).to receive(:open_shell).once
245
-
246
- executor.run_cmd('echo', ['Hello'])
247
- end
248
-
249
- it 'retries the command once' do
250
- expect(service).to receive(:run_command).exactly(2).times
251
-
252
- executor.run_cmd('echo', ['Hello'])
253
- end
254
- end
255
-
256
- describe 'when shell is closed on server' do
257
- before do
258
- @times_called = 0
259
-
260
- allow(service).to receive(:run_command) do
261
- @times_called += 1
262
- fail WinRM::WinRMWSManFault.new('oops', '2150858843') if @times_called == 1
263
- end
264
- end
265
-
266
- include_examples 'retry shell command'
267
- end
268
-
269
- describe 'when shell accesses a deleted registry key' do
270
- before do
271
- @times_called = 0
272
-
273
- allow(service).to receive(:run_command) do
274
- @times_called += 1
275
- fail WinRM::WinRMWSManFault.new('oops', '2147943418') if @times_called == 1
276
- end
277
- end
278
-
279
- include_examples 'retry shell command'
280
- end
281
- end
282
-
283
- describe 'when called many times over time' do
284
- # use a 'old' version of windows with lower max_commands threshold
285
- # to trigger quicker shell recyles
286
- let(:version_output) { { xml_fragment: [{ version: '6.1.8500' }] } }
287
-
288
- let(:echo_output) do
289
- o = ::WinRM::Output.new
290
- o[:exitcode] = 0
291
- o[:data].concat([{ stdout: 'Hello\r\n' }])
292
- o
293
- end
294
-
295
- before do
296
- allow(service).to receive(:open_shell).and_return('s1', 's2')
297
- allow(service).to receive(:close_shell)
298
- allow(service).to receive(:run_command).and_yield('command-xxx')
299
- allow(service).to receive(:get_command_output).and_return(echo_output)
300
- allow(service).to receive(:run_wql).with('select version from Win32_OperatingSystem')
301
- .and_return(version_output)
302
- end
303
-
304
- it 'resets the shell when #max_commands threshold is tripped' do
305
- iterations = 35
306
- reset_times = iterations / (15 - 2)
307
-
308
- expect(service).to receive(:close_shell).exactly(reset_times).times
309
- executor.open
310
- iterations.times { executor.run_cmd('echo', ['Hello']) }
311
- end
312
- end
313
- end
314
-
315
- describe '#run_powershell_script' do
316
- describe 'when #open has not been previously called' do
317
- it 'raises a WinRMError error' do
318
- expect { executor.run_powershell_script('nope') }.to raise_error(
319
- ::WinRM::WinRMError,
320
- "#{executor.class}#open must be called before any run methods are invoked"
321
- )
322
- end
323
- end
324
-
325
- describe 'when #open has been previously called' do
326
- let(:command_id) { 'command-123' }
327
-
328
- let(:echo_output) do
329
- o = ::WinRM::Output.new
330
- o[:exitcode] = 0
331
- o[:data].concat([
332
- { stdout: 'Hello\r\n' },
333
- { stderr: 'Psst\r\n' }
334
- ])
335
- o
336
- end
337
-
338
- before do
339
- stub_powershell_script(
340
- shell_id,
341
- 'echo Hello',
342
- echo_output,
343
- command_id
344
- )
345
-
346
- executor.open
347
- end
348
-
349
- it 'calls service#run_command' do
350
- expect(service).to receive(:run_command).with(
351
- shell_id,
352
- 'powershell',
353
- [
354
- '-encodedCommand',
355
- ::WinRM::PowershellScript.new('echo Hello')
356
- .encoded
357
- ]
358
- )
359
-
360
- executor.run_powershell_script('echo Hello')
361
- end
362
-
363
- it 'calls service#get_command_output to get results' do
364
- expect(service).to receive(:get_command_output).with(shell_id, command_id)
365
-
366
- executor.run_powershell_script('echo Hello')
367
- end
368
-
369
- it 'calls service#get_command_output with a block to get results' do
370
- blk = proc { |_, _| 'something' }
371
- expect(service).to receive(:get_command_output).with(shell_id, command_id, &blk)
372
-
373
- executor.run_powershell_script('echo Hello', &blk)
374
- end
375
-
376
- it 'returns an Output object hash' do
377
- expect(executor.run_powershell_script('echo Hello')).to eq echo_output
378
- end
379
-
380
- it 'runs the block in #get_command_output when given' do
381
- io_out = StringIO.new
382
- io_err = StringIO.new
383
- stub_cmd(shell_id, 'echo', ['Hello'], echo_output, command_id)
384
- .and_yield(echo_output.stdout, echo_output.stderr)
385
- output = executor.run_powershell_script('echo Hello') do |stdout, stderr|
386
- io_out << stdout if stdout
387
- io_err << stderr if stderr
388
- end
389
-
390
- expect(io_out.string).to eq 'Hello\r\n'
391
- expect(io_err.string).to eq 'Psst\r\n'
392
- expect(output).to eq echo_output
393
- end
394
- end
395
-
396
- describe 'when called many times over time' do
397
- # use a 'old' version of windows with lower max_commands threshold
398
- # to trigger quicker shell recyles
399
- let(:version_output) { { xml_fragment: [{ version: '6.1.8500' }] } }
400
-
401
- let(:echo_output) do
402
- o = ::WinRM::Output.new
403
- o[:exitcode] = 0
404
- o[:data].concat([{ stdout: 'Hello\r\n' }])
405
- o
406
- end
407
-
408
- before do
409
- allow(service).to receive(:open_shell).and_return('s1', 's2')
410
- allow(service).to receive(:close_shell)
411
- allow(service).to receive(:run_command).and_yield('command-xxx')
412
- allow(service).to receive(:get_command_output).and_return(echo_output)
413
- allow(service).to receive(:wsman_identify).with('select version from Win32_OperatingSystem')
414
- .and_return(version_output)
415
- end
416
-
417
- it 'resets the shell when #max_commands threshold is tripped' do
418
- iterations = 35
419
- reset_times = iterations / (15 - 2)
420
-
421
- expect(service).to receive(:close_shell).exactly(reset_times).times
422
- executor.open
423
- iterations.times { executor.run_powershell_script('echo Hello') }
424
- end
425
- end
426
- end
427
-
428
- describe '#shell' do
429
- it 'is initially nil' do
430
- expect(executor.shell).to eq nil
431
- end
432
-
433
- it 'is set after #open is called' do
434
- executor.open
435
-
436
- expect(executor.shell).to eq shell_id
437
- end
438
- end
439
-
440
- def decode(powershell)
441
- Base64.strict_decode64(powershell).encode('UTF-8', 'UTF-16LE')
442
- end
443
-
444
- def debug_line_with(msg)
445
- /^D, .* : #{Regexp.escape(msg)}/
446
- end
447
-
448
- def regexify(string)
449
- Regexp.new(Regexp.escape(string))
450
- end
451
-
452
- def regexify_line(string)
453
- Regexp.new("^#{Regexp.escape(string)}$")
454
- end
455
-
456
- # rubocop:disable Metrics/ParameterLists
457
- def stub_cmd(shell_id, cmd, args, output, command_id = nil, &block)
458
- command_id ||= SecureRandom.uuid
459
-
460
- allow(service).to receive(:run_command).with(shell_id, cmd, args).and_yield(command_id)
461
- allow(service).to receive(:get_command_output).with(shell_id, command_id, &block)
462
- .and_return(output)
463
- end
464
-
465
- def stub_powershell_script(shell_id, script, output, command_id = nil)
466
- stub_cmd(
467
- shell_id,
468
- 'powershell',
469
- ['-encodedCommand', ::WinRM::PowershellScript.new(script).encoded],
470
- output,
471
- command_id
472
- )
473
- end
474
- # rubocop:enable Metrics/ParameterLists
475
- end