nodespec 0.1.9 → 0.1.10

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 (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