nodespec 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +90 -0
  5. data/LICENSE.md +21 -0
  6. data/README.md +107 -0
  7. data/Rakefile +5 -0
  8. data/lib/nodespec/backend_proxy/base.rb +20 -0
  9. data/lib/nodespec/backend_proxy/cmd.rb +9 -0
  10. data/lib/nodespec/backend_proxy/exec.rb +21 -0
  11. data/lib/nodespec/backend_proxy/ssh.rb +28 -0
  12. data/lib/nodespec/backend_proxy/unixshell_utility.rb +32 -0
  13. data/lib/nodespec/backend_proxy/winrm.rb +23 -0
  14. data/lib/nodespec/backends.rb +13 -0
  15. data/lib/nodespec/command_execution.rb +16 -0
  16. data/lib/nodespec/communication_adapters/aws_ec2.rb +24 -0
  17. data/lib/nodespec/communication_adapters/local_backend.rb +15 -0
  18. data/lib/nodespec/communication_adapters/native_communicator.rb +32 -0
  19. data/lib/nodespec/communication_adapters/remote_backend.rb +15 -0
  20. data/lib/nodespec/communication_adapters/ssh.rb +14 -0
  21. data/lib/nodespec/communication_adapters/ssh_communicator.rb +54 -0
  22. data/lib/nodespec/communication_adapters/vagrant.rb +37 -0
  23. data/lib/nodespec/communication_adapters/winrm.rb +13 -0
  24. data/lib/nodespec/communication_adapters/winrm_communicator.rb +65 -0
  25. data/lib/nodespec/communication_adapters.rb +22 -0
  26. data/lib/nodespec/local_command_runner.rb +17 -0
  27. data/lib/nodespec/node.rb +56 -0
  28. data/lib/nodespec/node_configurations.rb +29 -0
  29. data/lib/nodespec/provisioning/ansible.rb +96 -0
  30. data/lib/nodespec/provisioning/chef.rb +68 -0
  31. data/lib/nodespec/provisioning/puppet.rb +55 -0
  32. data/lib/nodespec/provisioning/shellscript.rb +19 -0
  33. data/lib/nodespec/provisioning.rb +14 -0
  34. data/lib/nodespec/run_options.rb +14 -0
  35. data/lib/nodespec/runtime_gem_loader.rb +19 -0
  36. data/lib/nodespec/shared_examples_support.rb +13 -0
  37. data/lib/nodespec/verbose_output.rb +9 -0
  38. data/lib/nodespec/version.rb +3 -0
  39. data/nodespec.gemspec +28 -0
  40. data/spec/backend_proxy/base_spec.rb +29 -0
  41. data/spec/backend_proxy/exec_spec.rb +34 -0
  42. data/spec/backend_proxy/ssh_spec.rb +32 -0
  43. data/spec/backend_proxy/unixshell_utility_spec.rb +29 -0
  44. data/spec/backend_proxy/winrm_spec.rb +34 -0
  45. data/spec/command_execution_spec.rb +36 -0
  46. data/spec/communication_adapters/aws_ec2_spec.rb +70 -0
  47. data/spec/communication_adapters/local_backend_spec.rb +38 -0
  48. data/spec/communication_adapters/native_communicator_spec.rb +53 -0
  49. data/spec/communication_adapters/remote_backend_spec.rb +46 -0
  50. data/spec/communication_adapters/ssh_communicator_spec.rb +121 -0
  51. data/spec/communication_adapters/ssh_spec.rb +18 -0
  52. data/spec/communication_adapters/vagrant_spec.rb +61 -0
  53. data/spec/communication_adapters/winrm_communicator_spec.rb +111 -0
  54. data/spec/communication_adapters/winrm_spec.rb +18 -0
  55. data/spec/communication_adapters_spec.rb +29 -0
  56. data/spec/local_command_runner_spec.rb +26 -0
  57. data/spec/node_configurations_spec.rb +41 -0
  58. data/spec/node_spec.rb +110 -0
  59. data/spec/provisioning/ansible_spec.rb +143 -0
  60. data/spec/provisioning/chef_spec.rb +87 -0
  61. data/spec/provisioning/puppet_spec.rb +54 -0
  62. data/spec/provisioning/shellscript_spec.rb +20 -0
  63. data/spec/provisioning_spec.rb +52 -0
  64. data/spec/runtime_gem_loader_spec.rb +33 -0
  65. data/spec/spec_helper.rb +5 -0
  66. data/spec/support/backend.rb +10 -0
  67. data/spec/support/init_with_current_node.rb +4 -0
  68. data/spec/support/local_command.rb +12 -0
  69. data/spec/support/node_command.rb +12 -0
  70. data/spec/support/ssh_communicator.rb +9 -0
  71. data/spec/support/winrm_communicator.rb +9 -0
  72. metadata +105 -3
@@ -0,0 +1,34 @@
1
+ require 'nodespec/backend_proxy/winrm'
2
+
3
+ module NodeSpec
4
+ module BackendProxy
5
+ describe WinRM do
6
+ let(:winrm) { double('winrm session') }
7
+ let(:subject) {WinRM.new(winrm)}
8
+ before do
9
+ allow(winrm).to receive(:set_timeout).with(NodeSpec::RunOptions.command_timeout)
10
+ end
11
+
12
+ it 'returns true upon successful execution' do
13
+ result = {exitcode: 0, data: [{stdout: 'output line 1'}, {stdout: 'output line 2'}]}
14
+ allow(winrm).to receive(:powershell).and_return(result)
15
+
16
+ expect(subject.execute('command')).to be_truthy
17
+ end
18
+
19
+ it 'returns false if stderr not empty' do
20
+ result = {exitcode: 0, data: [{stdout: 'output line 1', stderr: 'error line 1'}, {stdout: 'output line 2', stderr: 'error line 2'}]}
21
+ allow(winrm).to receive(:powershell).and_return(result)
22
+
23
+ expect(subject.execute('command')).to be_falsy
24
+ end
25
+
26
+ it 'returns false if exitcode not zero' do
27
+ result = {exitcode: 1, data: [{stdout: 'output line 1'}, {stdout: 'output line 2'}]}
28
+ allow(winrm).to receive(:powershell).and_return(result)
29
+
30
+ expect(subject.execute('command')).to be_falsy
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'nodespec/command_execution'
2
+
3
+ module NodeSpec
4
+ describe CommandExecution do
5
+ let(:subject) {Object.new.extend CommandExecution}
6
+
7
+ it 'does not raise an error if the command succeeds' do
8
+ subject.execute_within_timeout('test command') { true }
9
+ end
10
+
11
+ it 'raises an error if the command fails' do
12
+ expect {
13
+ subject.execute_within_timeout('test command') { false }
14
+ }.to raise_error CommandExecution::CommandExecutionError
15
+ end
16
+
17
+ context 'custom timeout' do
18
+ it 'fails if running longer than the set timeout' do
19
+ expect {
20
+ subject.execute_within_timeout('test command', 1) { sleep(2) }
21
+ }.to raise_error Timeout::Error
22
+ end
23
+ end
24
+
25
+ context 'preset timeout' do
26
+ before do
27
+ NodeSpec::RunOptions.command_timeout = 1
28
+ end
29
+ it 'fails if running longer than the set timeout' do
30
+ expect {
31
+ subject.execute_within_timeout('test command') { sleep(2) }
32
+ }.to raise_error Timeout::Error
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,70 @@
1
+ require 'aws-sdk'
2
+ require 'spec_helper'
3
+ require 'nodespec/communication_adapters/aws_ec2'
4
+
5
+ module NodeSpec
6
+ module CommunicationAdapters
7
+ describe AwsEc2 do
8
+ let(:ec2_instance) {double('ec2 instance')}
9
+
10
+ before do
11
+ instance_collection = double
12
+ allow(AWS).to receive_message_chain(:ec2, :instances).and_return(instance_collection)
13
+ allow(instance_collection).to receive(:[]).with('test-instance').and_return(ec2_instance)
14
+ end
15
+
16
+ describe 'connecting to a running instance' do
17
+ before do
18
+ allow(ec2_instance).to receive(:exists?).ordered.and_return(true)
19
+ allow(ec2_instance).to receive(:status).ordered.and_return(:running)
20
+ allow(ec2_instance).to receive(:public_dns_name).ordered.and_return('test hostname')
21
+ end
22
+
23
+ %w[ssh winrm].each do |connection|
24
+ describe "#{connection} communicator" do
25
+ include_context "new_#{connection}_communicator", 'test hostname', 'test_os', 'foo' => 'bar'
26
+
27
+ it 'returns communicator with the instance name from the node name' do
28
+ expect(AwsEc2.communicator_for('test-instance', 'test_os', connection => {'foo' => 'bar'})).to eq("#{connection} communicator")
29
+ end
30
+
31
+ it 'returns communicator with the instance name from the options' do
32
+ expect(AwsEc2.communicator_for('test_node', 'test_os', 'instance' => 'test-instance', connection => {'foo' => 'bar'})).to eq("#{connection} communicator")
33
+ end
34
+ end
35
+ end
36
+
37
+ describe 'openssh default connection' do
38
+ include_context "new_ssh_communicator", 'test hostname', 'test_os', {}
39
+
40
+ it 'returns an ssh communicator' do
41
+ expect(AwsEc2.communicator_for('test-instance', 'test_os')).to eq("ssh communicator")
42
+ end
43
+ end
44
+ end
45
+
46
+ describe 'connecting to an unreachable instance' do
47
+ context 'not existing instance' do
48
+ before do
49
+ allow(ec2_instance).to receive(:exists?).ordered.and_return(false)
50
+ end
51
+
52
+ it 'raises an error' do
53
+ expect {AwsEc2.communicator_for('test-instance', 'test_os', 'foo' => 'bar')}.to raise_error
54
+ end
55
+ end
56
+
57
+ context 'not running instance' do
58
+ before do
59
+ allow(ec2_instance).to receive(:exists?).ordered.and_return(true)
60
+ allow(ec2_instance).to receive(:status).ordered.and_return(:whatever_else)
61
+ end
62
+
63
+ it 'raises an error' do
64
+ expect {AwsEc2.communicator_for('test-instance', 'test_os', 'foo' => 'bar')}.to raise_error
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'nodespec/communication_adapters/local_backend'
3
+
4
+ module NodeSpec
5
+ module CommunicationAdapters
6
+ describe LocalBackend do
7
+ let(:subject) {Object.new.extend LocalBackend}
8
+
9
+ context 'no os' do
10
+ before do
11
+ def subject.os
12
+ end
13
+ end
14
+ it_behaves_like 'providing a backend', 'Exec'
15
+ end
16
+
17
+ context 'UN*X os' do
18
+ before do
19
+ def subject.os
20
+ 'CentOS'
21
+ end
22
+ end
23
+
24
+ it_behaves_like 'providing a backend', 'Exec'
25
+ end
26
+
27
+ context 'Windows os' do
28
+ before do
29
+ def subject.os
30
+ 'Windows'
31
+ end
32
+ end
33
+
34
+ it_behaves_like 'providing a backend', 'Cmd'
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,53 @@
1
+ require 'nodespec/communication_adapters/native_communicator'
2
+
3
+ module NodeSpec
4
+ module CommunicationAdapters
5
+ describe NativeCommunicator do
6
+ it 'provides a local backend' do
7
+ expect(NativeCommunicator.new).to be_a(LocalBackend)
8
+ end
9
+
10
+ describe '#initialize' do
11
+ [nil, 'Test OS'].each do |os|
12
+ it 'holds the os information' do
13
+ expect(NativeCommunicator.new(os).os).to eq os
14
+ end
15
+ end
16
+ end
17
+
18
+ describe '#bind_to' do
19
+ let(:rspec_configuration) {double('rspec configuration')}
20
+
21
+ context('ssh session') do
22
+ let(:ssh_session) {double('ssh session')}
23
+
24
+ before do
25
+ allow(rspec_configuration).to receive(:ssh).and_return(ssh_session)
26
+ allow(rspec_configuration).to receive(:winrm)
27
+ [:close, :host].each {|m| allow(ssh_session).to receive(m)}
28
+ allow(ssh_session).to receive(:options).and_return({port: 'port'})
29
+ expect(rspec_configuration).to receive(:ssh=).with(nil)
30
+ end
31
+
32
+ it 'closes and removes an existing ssh session' do
33
+ subject.bind_to(rspec_configuration)
34
+ end
35
+ end
36
+
37
+ context('winrm session') do
38
+ let(:winrm_session) {double('winrm session')}
39
+
40
+ before do
41
+ allow(rspec_configuration).to receive(:ssh)
42
+ allow(rspec_configuration).to receive(:winrm).and_return(winrm_session)
43
+ expect(rspec_configuration).to receive(:winrm=).with(nil)
44
+ end
45
+
46
+ it 'removes an existing winrm session' do
47
+ subject.bind_to(rspec_configuration)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'nodespec/communication_adapters/remote_backend'
3
+
4
+ module NodeSpec
5
+ module CommunicationAdapters
6
+ describe RemoteBackend do
7
+ let(:subject) {
8
+ Object.new.tap do |obj|
9
+ obj.extend RemoteBackend
10
+ def obj.session
11
+ 'session'
12
+ end
13
+ end
14
+ }
15
+
16
+ context 'no os' do
17
+ before do
18
+ def subject.os
19
+ end
20
+ end
21
+
22
+ it_behaves_like 'providing a backend', 'Ssh'
23
+ end
24
+
25
+ context 'UN*X os' do
26
+ before do
27
+ def subject.os
28
+ 'CentOS'
29
+ end
30
+ end
31
+
32
+ it_behaves_like 'providing a backend', 'Ssh'
33
+ end
34
+
35
+ context 'Windows os' do
36
+ before do
37
+ def subject.os
38
+ 'Windows'
39
+ end
40
+ end
41
+
42
+ it_behaves_like 'providing a backend', 'WinRM'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,121 @@
1
+ require 'nodespec/communication_adapters/ssh_communicator'
2
+
3
+ module NodeSpec
4
+ module CommunicationAdapters
5
+ describe SshCommunicator do
6
+ let(:rspec_configuration) {double('rspec configuration')}
7
+ let(:ssh_session) {double('ssh session')}
8
+
9
+ before do
10
+ allow(Net::SSH).to receive(:start).with('test.host.name', 'testuser', port: 1234, password: 'testpassword', keys: 'testkeys').and_return('new session')
11
+ end
12
+
13
+ shared_context 'existing session' do |hostname, port|
14
+ before do
15
+ allow(rspec_configuration).to receive(:ssh).and_return(ssh_session)
16
+ allow(ssh_session).to receive(:host).and_return(hostname)
17
+ allow(ssh_session).to receive(:options).and_return({port: port})
18
+ end
19
+ end
20
+
21
+ shared_examples 'creating new session' do
22
+ before do
23
+ expect(rspec_configuration).to receive(:ssh=).with('new session')
24
+ expect(rspec_configuration).to receive(:host=).with('test.host.name')
25
+ end
26
+
27
+ it 'creates and holds a new session' do
28
+ subject.bind_to(rspec_configuration)
29
+
30
+ expect(subject.session).to eq('new session')
31
+ end
32
+ end
33
+
34
+ shared_examples 'binding to configuration' do
35
+ before do
36
+ allow(rspec_configuration).to receive(:winrm)
37
+ end
38
+
39
+ context 'existing winrm session' do
40
+ before do
41
+ allow(rspec_configuration).to receive(:winrm).and_return('winrm')
42
+ allow(rspec_configuration).to receive(:ssh).and_return(nil)
43
+ expect(rspec_configuration).to receive(:winrm=).with(nil)
44
+ end
45
+
46
+ include_examples 'creating new session'
47
+ end
48
+
49
+ context 'no existing ssh session' do
50
+ before do
51
+ allow(rspec_configuration).to receive(:ssh).and_return(nil)
52
+ end
53
+
54
+ include_examples 'creating new session'
55
+ end
56
+
57
+ {'another host' => 1234, 'test.host.name' => 5678}.each do |hostname, port|
58
+ context 'existing session with different connection' do
59
+ include_context 'existing session', hostname, port
60
+ before do
61
+ expect(ssh_session).to receive(:close)
62
+ allow(ssh_session).to receive(:closed?).and_return(true)
63
+ end
64
+ include_examples 'creating new session'
65
+ end
66
+ end
67
+
68
+ context 'existing ssh session with same connection' do
69
+ include_context 'existing session', 'test.host.name', 1234
70
+ context 'open session' do
71
+ before { allow(ssh_session).to receive(:closed?).and_return(false) }
72
+
73
+ it 'does not change the current rspec configuration' do
74
+ expect(Net::SSH).not_to receive(:start)
75
+ expect(rspec_configuration).not_to receive(:ssh=)
76
+ expect(rspec_configuration).not_to receive(:host=)
77
+
78
+ subject.bind_to(rspec_configuration)
79
+
80
+ expect(subject.session).to eq(ssh_session)
81
+ end
82
+ end
83
+
84
+ context 'closed session' do
85
+ before { allow(ssh_session).to receive(:closed?).and_return(true) }
86
+ include_examples 'creating new session'
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'with given credentials' do
92
+ let(:subject) {SshCommunicator.new('test.host.name', nil, 'port' => 1234, 'user' => 'testuser', 'password' => 'testpassword', 'keys' => 'testkeys')}
93
+ before do
94
+ allow(Net::SSH).to receive(:configuration_for).and_return({})
95
+ end
96
+ include_examples 'binding to configuration'
97
+ end
98
+
99
+ context 'credentials from OpenSSH config files' do
100
+ let(:subject) {SshCommunicator.new('test.host.name', nil, 'port' => 1234, 'user' => 'testuser')}
101
+ before do
102
+ allow(Net::SSH).to receive(:configuration_for).with('test.host.name').and_return(password: 'testpassword', keys: 'testkeys')
103
+ end
104
+
105
+ include_examples 'binding to configuration'
106
+ end
107
+
108
+ it 'provides a remote backend' do
109
+ expect(SshCommunicator.new('test.host.name')).to be_a(RemoteBackend)
110
+ end
111
+
112
+ describe '#initialize' do
113
+ [nil, 'Test OS'].each do |os|
114
+ it 'holds the os information' do
115
+ expect(SshCommunicator.new('test.host.name', os, {}).os).to eq os
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'nodespec/communication_adapters/ssh'
3
+
4
+ module NodeSpec
5
+ module CommunicationAdapters
6
+ describe Ssh do
7
+ include_context 'new_ssh_communicator', 'test.host.name', 'test_os', {'foo' => 'bar'}
8
+
9
+ it 'returns communicator with the host name from the node name' do
10
+ expect(Ssh.communicator_for('test.host.name', 'test_os', 'foo' => 'bar')).to eq('ssh communicator')
11
+ end
12
+
13
+ it 'returns communicator with the host name from the options' do
14
+ expect(Ssh.communicator_for('test_node', 'test_os', 'host' => 'test.host.name', 'foo' => 'bar')).to eq('ssh communicator')
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'nodespec/communication_adapters/vagrant'
3
+
4
+ module NodeSpec
5
+ module CommunicationAdapters
6
+ describe Vagrant do
7
+ [['test_vm', 'test_os'], ['test_node', 'test_os', {'vm_name' => 'test_vm'}]].each do |args|
8
+ describe "#communicator_for" do
9
+ let(:cmd_status) { double('status') }
10
+
11
+ before(:each) do
12
+ expect(Open3).to receive(:capture2e).with('vagrant --machine-readable ssh-config test_vm').and_return([cmd_output, cmd_status])
13
+ end
14
+
15
+ context 'vm not running' do
16
+ let(:cmd_output) {
17
+ '1402310908,,error-exit,Vagrant::Errors::SSHNotReady,The provider...'
18
+ }
19
+
20
+ it 'raises an error' do
21
+ allow(cmd_status).to receive(:success?).and_return(false)
22
+
23
+ expect {Vagrant.communicator_for(*args)}.to raise_error 'Vagrant::Errors::SSHNotReady,The provider...'
24
+ end
25
+ end
26
+
27
+ context 'vm running' do
28
+ let(:cmd_output) {
29
+ <<-EOS
30
+ Host test_vm
31
+ HostName test.host.name
32
+ User testuser
33
+ Port 1234
34
+ UserKnownHostsFile /dev/null
35
+ StrictHostKeyChecking no
36
+ PasswordAuthentication no
37
+ IdentityFile /test/path/private_key
38
+ IdentitiesOnly yes
39
+ LogLevel FATAL
40
+ EOS
41
+ }
42
+
43
+ include_context 'new_ssh_communicator', 'test.host.name', 'test_os', {
44
+ 'user' => 'testuser',
45
+ 'port' => 1234,
46
+ 'keys' => '/test/path/private_key'
47
+ } do
48
+ before do
49
+ allow(cmd_status).to receive(:success?).and_return(true)
50
+ end
51
+
52
+ it 'returns and ssh communicator initialized from the vagrant command output' do
53
+ expect(Vagrant.communicator_for(*args)).to eq('ssh communicator')
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,111 @@
1
+ require 'winrm'
2
+ require 'nodespec/communication_adapters/winrm_communicator'
3
+
4
+ module NodeSpec
5
+ module CommunicationAdapters
6
+ describe WinrmCommunicator do
7
+ let(:rspec_configuration) {double('rspec configuration')}
8
+ shared_examples 'creating new session' do |hostname, port, transport, options|
9
+ before do
10
+ allow(WinRM::WinRMWebService).to receive(:new).with("http://#{hostname}:#{port}/wsman", transport, options).and_return('new session')
11
+ expect(rspec_configuration).to receive(:winrm=).with('new session')
12
+ expect(rspec_configuration).to receive(:host=).with(hostname)
13
+ end
14
+
15
+ it 'creates and holds a new session' do
16
+ subject.bind_to(rspec_configuration)
17
+
18
+ expect(subject.session).to eq('new session')
19
+ end
20
+ end
21
+
22
+ describe 'connecting to the web service' do
23
+ before do
24
+ allow(rspec_configuration).to receive(:ssh)
25
+ allow(rspec_configuration).to receive(:winrm).and_return(nil)
26
+ end
27
+
28
+ context 'default port and transport' do
29
+ let(:subject) {WinrmCommunicator.new('test.host.name', nil, 'foo' => 'bar')}
30
+ include_examples 'creating new session', 'test.host.name', 5985, :plaintext, {foo: 'bar', disable_sspi: true}
31
+ end
32
+
33
+ context 'custom port and transport' do
34
+ let(:subject) {WinrmCommunicator.new('test.host.name', nil, 'port' => 1234, 'transport' => 'test_transport', 'foo' => 'bar')}
35
+ include_examples 'creating new session', 'test.host.name', 1234, :test_transport, {foo: 'bar'}
36
+ end
37
+ end
38
+
39
+ describe 'binding to configuration' do
40
+ let(:winrm_session) {double('winrm session')}
41
+ let(:subject) { WinrmCommunicator.new(
42
+ 'test.host.name', nil, 'port' => 1234, 'transport' => 'test_transport', foo: 'bar', 'baz' => 'quaz')
43
+ }
44
+
45
+ before do
46
+ allow(rspec_configuration).to receive(:ssh)
47
+ end
48
+
49
+ shared_context 'existing session' do |endpoint|
50
+ before do
51
+ allow(rspec_configuration).to receive(:winrm).and_return(winrm_session)
52
+ allow(winrm_session).to receive(:endpoint).and_return(endpoint)
53
+ end
54
+ end
55
+
56
+ context 'existing ssh session' do
57
+ let(:ssh_session) {double('ssh session')}
58
+ before do
59
+ allow(rspec_configuration).to receive(:ssh).and_return(ssh_session)
60
+ allow(rspec_configuration).to receive(:winrm).and_return(nil)
61
+ allow(ssh_session).to receive(:host)
62
+ allow(ssh_session).to receive(:options).and_return({})
63
+ expect(ssh_session).to receive(:close)
64
+ expect(rspec_configuration).to receive(:ssh=).with(nil)
65
+ end
66
+
67
+ include_examples 'creating new session', 'test.host.name', 1234, :test_transport, {foo: 'bar', baz: 'quaz'}
68
+ end
69
+
70
+ context 'no existing session' do
71
+ before do
72
+ allow(rspec_configuration).to receive(:winrm).and_return(nil)
73
+ end
74
+
75
+ include_examples 'creating new session', 'test.host.name', 1234, :test_transport, {foo: 'bar', baz: 'quaz'}
76
+ end
77
+
78
+ context 'existing session with different endpoint' do
79
+ include_context 'existing session', 'http://test.another.host.name:1234/wsman'
80
+ include_examples 'creating new session', 'test.host.name', 1234, :test_transport, {foo: 'bar', baz: 'quaz'}
81
+ end
82
+
83
+ context 'existing session with same connection' do
84
+ include_context 'existing session', "http://test.host.name:1234/wsman"
85
+
86
+ it 'does not change the current rspec configuration' do
87
+ expect(WinRM::WinRMWebService).not_to receive(:new)
88
+ expect(rspec_configuration).not_to receive(:winrm=)
89
+ expect(rspec_configuration).not_to receive(:host=)
90
+
91
+ subject.bind_to(rspec_configuration)
92
+
93
+ expect(subject.session).to eq(winrm_session)
94
+ end
95
+ end
96
+ end
97
+
98
+ it 'provides a remote backend' do
99
+ expect(WinrmCommunicator.new('test.host.name')).to be_a(RemoteBackend)
100
+ end
101
+
102
+ describe '#initialize' do
103
+ [nil, 'Test OS'].each do |os|
104
+ it 'holds the os information' do
105
+ expect(WinrmCommunicator.new('test.host.name', os, {}).os).to eq os
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'nodespec/communication_adapters/winrm'
3
+
4
+ module NodeSpec
5
+ module CommunicationAdapters
6
+ describe Winrm do
7
+ include_context 'new_winrm_communicator', 'test.host.name', 'test_os', {'foo' => 'bar'}
8
+
9
+ it 'returns communicator with the host name from the node name' do
10
+ expect(Winrm.communicator_for('test.host.name', 'test_os', 'foo' => 'bar')).to eq('winrm communicator')
11
+ end
12
+
13
+ it 'returns communicator with the host name from the options' do
14
+ expect(Winrm.communicator_for('test_node', 'test_os', 'host' => 'test.host.name', 'foo' => 'bar')).to eq('winrm communicator')
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'nodespec/communication_adapters'
2
+ %w[vagrant ssh aws_ec2 winrm].each {|f| require "nodespec/communication_adapters/#{f}"}
3
+
4
+ module NodeSpec
5
+ describe CommunicationAdapters do
6
+ {
7
+ 'vagrant' => CommunicationAdapters::Vagrant,
8
+ 'ssh' => CommunicationAdapters::Ssh,
9
+ 'aws_ec2' => CommunicationAdapters::AwsEc2,
10
+ 'winrm' => CommunicationAdapters::Winrm
11
+ }.each do |adapter_name, adapter_class|
12
+ it "retrieves a communicator from #{adapter_class}" do
13
+ expect(adapter_class).to receive(:communicator_for).with('test_node', 'test_os', 'adapter_options' => 'test_options').and_return('communicator')
14
+
15
+ communicator = CommunicationAdapters.get_communicator('test_node', 'test_os', adapter_name, 'adapter_options' => 'test_options')
16
+
17
+ expect(communicator).to eq('communicator')
18
+ end
19
+ end
20
+
21
+ it 'defaults to a NativeCommunicator' do
22
+ expect(CommunicationAdapters::NativeCommunicator).to receive(:new).with('test_os').and_return('communicator')
23
+
24
+ communicator = CommunicationAdapters.get_communicator('test_node', 'test_os', nil)
25
+
26
+ expect(communicator).to eq('communicator')
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'nodespec/local_command_runner'
3
+
4
+ module NodeSpec
5
+ describe LocalCommandRunner do
6
+ let(:subject) {Object.new.extend LocalCommandRunner}
7
+ let(:cmd_status) { double('status') }
8
+
9
+ before do
10
+ allow(Open3).to receive(:capture2e).with('test command').and_return(['test output', cmd_status])
11
+ allow(subject).to receive(:execute_within_timeout).with('test command').and_yield
12
+ end
13
+
14
+ it 'returns true if the command succeeds' do
15
+ allow(cmd_status).to receive(:success?).and_return(true)
16
+
17
+ expect(subject.run_command('test command')).to be_truthy
18
+ end
19
+
20
+ it 'returns false if the command fails' do
21
+ allow(cmd_status).to receive(:success?).and_return(false)
22
+
23
+ expect(subject.run_command('test command')).to be_falsy
24
+ end
25
+ end
26
+ end