ridley 0.10.2 → 0.11.0.rc1

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 (85) hide show
  1. data/README.md +147 -216
  2. data/lib/ridley.rb +2 -0
  3. data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +21 -25
  4. data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +29 -34
  5. data/lib/ridley/bootstrapper.rb +2 -2
  6. data/lib/ridley/bootstrapper/context.rb +5 -5
  7. data/lib/ridley/chef.rb +0 -1
  8. data/lib/ridley/chef/cookbook.rb +0 -9
  9. data/lib/ridley/chef_object.rb +128 -0
  10. data/lib/ridley/chef_objects.rb +3 -0
  11. data/lib/ridley/chef_objects/client_object.rb +55 -0
  12. data/lib/ridley/chef_objects/cookbook_object.rb +190 -0
  13. data/lib/ridley/chef_objects/data_bag_item_obect.rb +104 -0
  14. data/lib/ridley/chef_objects/data_bag_object.rb +31 -0
  15. data/lib/ridley/chef_objects/environment_object.rb +59 -0
  16. data/lib/ridley/chef_objects/node_object.rb +161 -0
  17. data/lib/ridley/chef_objects/role_object.rb +62 -0
  18. data/lib/ridley/chef_objects/sandbox_object.rb +58 -0
  19. data/lib/ridley/client.rb +76 -45
  20. data/lib/ridley/connection.rb +1 -1
  21. data/lib/ridley/errors.rb +8 -1
  22. data/lib/ridley/host_connector.rb +26 -6
  23. data/lib/ridley/host_connector/ssh.rb +3 -3
  24. data/lib/ridley/host_connector/ssh/worker.rb +7 -9
  25. data/lib/ridley/host_connector/winrm/worker.rb +4 -5
  26. data/lib/ridley/mixin/bootstrap_binding.rb +1 -12
  27. data/lib/ridley/resource.rb +51 -171
  28. data/lib/ridley/resources/client_resource.rb +18 -68
  29. data/lib/ridley/resources/cookbook_resource.rb +181 -381
  30. data/lib/ridley/resources/data_bag_item_resource.rb +55 -161
  31. data/lib/ridley/resources/data_bag_resource.rb +20 -61
  32. data/lib/ridley/resources/environment_resource.rb +9 -64
  33. data/lib/ridley/resources/node_resource.rb +135 -311
  34. data/lib/ridley/resources/role_resource.rb +1 -57
  35. data/lib/ridley/resources/sandbox_resource.rb +80 -65
  36. data/lib/ridley/resources/search_resource.rb +99 -0
  37. data/lib/ridley/sandbox_uploader.rb +12 -52
  38. data/lib/ridley/version.rb +1 -1
  39. data/spec/acceptance/bootstrapping_spec.rb +1 -1
  40. data/spec/acceptance/client_resource_spec.rb +15 -37
  41. data/spec/acceptance/data_bag_item_resource_spec.rb +8 -14
  42. data/spec/acceptance/data_bag_resource_spec.rb +1 -1
  43. data/spec/acceptance/environment_resource_spec.rb +13 -22
  44. data/spec/acceptance/node_resource_spec.rb +10 -29
  45. data/spec/acceptance/role_resource_spec.rb +14 -13
  46. data/spec/acceptance/sandbox_resource_spec.rb +2 -2
  47. data/spec/support/shared_examples/ridley_resource.rb +2 -23
  48. data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +3 -4
  49. data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +3 -5
  50. data/spec/unit/ridley/bootstrapper/context_spec.rb +2 -3
  51. data/spec/unit/ridley/bootstrapper_spec.rb +1 -1
  52. data/spec/unit/ridley/chef_object_spec.rb +240 -0
  53. data/spec/unit/ridley/chef_objects/client_object_spec.rb +11 -0
  54. data/spec/unit/ridley/chef_objects/cookbook_object_spec.rb +93 -0
  55. data/spec/unit/ridley/chef_objects/data_bag_item_object_spec.rb +74 -0
  56. data/spec/unit/ridley/chef_objects/data_bag_object_spec.rb +9 -0
  57. data/spec/unit/ridley/chef_objects/environment_object_spec.rb +57 -0
  58. data/spec/unit/ridley/chef_objects/node_object_spec.rb +252 -0
  59. data/spec/unit/ridley/chef_objects/role_object_spec.rb +57 -0
  60. data/spec/unit/ridley/chef_objects/sandbox_object_spec.rb +66 -0
  61. data/spec/unit/ridley/client_spec.rb +51 -51
  62. data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +4 -4
  63. data/spec/unit/ridley/host_connector/ssh_spec.rb +26 -24
  64. data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +3 -4
  65. data/spec/unit/ridley/host_connector/winrm_spec.rb +4 -4
  66. data/spec/unit/ridley/host_connector_spec.rb +40 -3
  67. data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +1 -1
  68. data/spec/unit/ridley/resource_spec.rb +81 -109
  69. data/spec/unit/ridley/resources/client_resource_spec.rb +18 -33
  70. data/spec/unit/ridley/resources/cookbook_resource_spec.rb +56 -230
  71. data/spec/unit/ridley/resources/data_bag_item_resource_spec.rb +2 -57
  72. data/spec/unit/ridley/resources/data_bag_resource_spec.rb +12 -7
  73. data/spec/unit/ridley/resources/environment_resource_spec.rb +10 -118
  74. data/spec/unit/ridley/resources/node_resource_spec.rb +83 -394
  75. data/spec/unit/ridley/resources/role_resource_spec.rb +2 -56
  76. data/spec/unit/ridley/resources/sandbox_resource_spec.rb +139 -136
  77. data/spec/unit/ridley/resources/search_resource_spec.rb +234 -0
  78. data/spec/unit/ridley/sandbox_uploader_spec.rb +13 -58
  79. metadata +36 -17
  80. data/lib/ridley/chef/chefignore.rb +0 -76
  81. data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +0 -55
  82. data/lib/ridley/resources/search.rb +0 -101
  83. data/spec/fixtures/chefignore +0 -8
  84. data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
  85. data/spec/unit/ridley/resources/search_spec.rb +0 -221
@@ -1,62 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::DataBagItemResource do
4
- let(:connection) { double('connection') }
5
- let(:data_bag) { double('data_bag') }
4
+ subject { described_class.new(double) }
6
5
 
7
- subject { Ridley::DataBagItemResource.new(connection, data_bag) }
8
-
9
- describe "::from_hash" do
10
- context "when JSON has a 'raw_data' field" do
11
- let(:response) do
12
- {
13
- "name" => "data_bag_item_ridley-test_appconfig",
14
- "raw_data" => {
15
- "id" => "appconfig",
16
- "host" => "host.local"
17
- },
18
- "json_class" => "Chef::DataBagItem",
19
- "data_bag" => "ridley-test",
20
- "chef_type" => "data_bag_item"
21
- }
22
- end
23
-
24
- it "returns a new object from attributes in the 'raw_data' field" do
25
- subject.from_hash(response).attributes.should eql(response["raw_data"])
26
- end
27
- end
28
-
29
- context "when JSON does not contain a 'raw_data' field" do
30
- let(:response) do
31
- {
32
- "id" => "appconfig",
33
- "host" => "host.local"
34
- }
35
- end
36
-
37
- it "returns a new object from the hash" do
38
- subject.from_hash(response).attributes.should eql(response)
39
- end
40
- end
41
- end
42
-
43
- describe "#decrypt" do
44
- before(:each) do
45
- encrypted_data_bag_secret = File.read(fixtures_path.join("encrypted_data_bag_secret").to_s)
46
- connection.stub(:encrypted_data_bag_secret).and_return(encrypted_data_bag_secret)
47
- end
48
-
49
- it "decrypts an encrypted value" do
50
- subject.attributes[:test] = "Xk0E8lV9r4BhZzcg4wal0X4w9ZexN3azxMjZ9r1MCZc="
51
- subject.decrypt
52
- subject.attributes[:test][:database][:username].should == "test"
53
- end
54
-
55
- it "does not decrypt the id field" do
56
- id = "dbi_id"
57
- subject.attributes[:id] = id
58
- subject.decrypt
59
- subject.attributes[:id].should == id
60
- end
61
- end
6
+ pending
62
7
  end
@@ -1,15 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::DataBagResource do
4
- it_behaves_like "a Ridley Resource", Ridley::DataBagResource
4
+ let(:secret) { "supersecretkey" }
5
+ let(:instance) { described_class.new(double, secret) }
5
6
 
6
- let(:connection) { double('connection') }
7
+ describe "#item_resource" do
8
+ subject { instance.item_resource }
7
9
 
8
- describe "ClassMethods" do
9
- subject { Ridley::DataBagResource }
10
-
11
- describe "::create_item" do
12
- pending
10
+ it "returns a DataBagItemResource" do
11
+ subject.should be_a(Ridley::DataBagItemResource)
13
12
  end
13
+
14
+ its(:data_bag_secret) { should eql(secret) }
15
+ end
16
+
17
+ describe "#find" do
18
+ pending
14
19
  end
15
20
  end
@@ -1,129 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::EnvironmentResource do
4
- it_behaves_like "a Ridley Resource", Ridley::EnvironmentResource
4
+ subject { described_class.new(double('registry')) }
5
5
 
6
- let(:connection) { double("connection") }
6
+ describe "#delete_all" do
7
+ let(:default_env) { double(name: "_default") }
8
+ let(:destroy_env) { double(name: "destroy_me") }
7
9
 
8
- let(:environment_json) do
9
- %(
10
- {
11
- "name": "crazy-town",
12
- "default_attributes": {
13
- "nested_attribute": {
14
- "status": "running",
15
- "list": [
16
- "one-thing"
17
- ],
18
- "feelin_good": true
19
- }
20
- },
21
- "description": "Single letter variables. Who the fuck do you think you are?",
22
- "cookbook_versions": {
23
-
24
- },
25
- "override_attributes": {
26
- "mysql": {
27
- "bind_address": "127.0.0.1",
28
- "server_root_password": "password_lol"
29
- }
30
- },
31
- "chef_type": "environment"
32
- }
33
- )
34
- end
35
-
36
- describe "ClassMethods" do
37
- subject { Ridley::EnvironmentResource }
38
-
39
- describe "::initialize" do
40
- before(:each) do
41
- @env = subject.new(connection, parse_json(environment_json))
42
- end
43
-
44
- it "has a value for 'name'" do
45
- @env.name.should eql("crazy-town")
46
- end
47
-
48
- it "has a value for 'default_attributes'" do
49
- @env.default_attributes.should be_a(Hash)
50
- @env.default_attributes.should have_key("nested_attribute")
51
- @env.default_attributes["nested_attribute"]["status"].should eql("running")
52
- end
53
-
54
- it "has a value for 'description'" do
55
- @env.description.should eql("Single letter variables. Who the fuck do you think you are?")
56
- end
57
-
58
- it "has a value for 'cookbook_version'" do
59
- @env.cookbook_versions.should be_a(Hash)
60
- end
61
-
62
- it "has a value for 'override_attributes'" do
63
- @env.override_attributes.should be_a(Hash)
64
- @env.override_attributes.should have_key("mysql")
65
- @env.override_attributes["mysql"].should have_key("bind_address")
66
- end
67
-
68
- it "has a value for 'chef_type'" do
69
- @env.chef_type.should eql("environment")
70
- end
10
+ before do
11
+ subject.stub(all: [ default_env, destroy_env ])
71
12
  end
72
- end
73
13
 
74
- let(:connection) { double('connection') }
75
-
76
- subject { Ridley::EnvironmentResource.new(connection) }
77
-
78
- describe "#set_override_attribute" do
79
- it "sets an override node attribute at the nested path" do
80
- subject.set_override_attribute('deep.nested.item', true)
81
-
82
- subject.override_attributes.should have_key("deep")
83
- subject.override_attributes["deep"].should have_key("nested")
84
- subject.override_attributes["deep"]["nested"].should have_key("item")
85
- subject.override_attributes["deep"]["nested"]["item"].should be_true
86
- end
87
-
88
- context "when the override attribute is already set" do
89
- it "test" do
90
- subject.override_attributes = {
91
- deep: {
92
- nested: {
93
- item: false
94
- }
95
- }
96
- }
97
- subject.set_override_attribute('deep.nested.item', true)
98
-
99
- subject.override_attributes["deep"]["nested"]["item"].should be_true
100
- end
101
- end
102
- end
103
-
104
- describe "#set_default_attribute" do
105
- it "sets an override node attribute at the nested path" do
106
- subject.set_default_attribute('deep.nested.item', true)
107
-
108
- subject.default_attributes.should have_key("deep")
109
- subject.default_attributes["deep"].should have_key("nested")
110
- subject.default_attributes["deep"]["nested"].should have_key("item")
111
- subject.default_attributes["deep"]["nested"]["item"].should be_true
112
- end
14
+ it "does not destroy the '_default' environment" do
15
+ subject.stub(future: double('future', value: nil))
16
+ subject.should_not_receive(:future).with(:delete, default_env)
113
17
 
114
- context "when the override attribute is already set" do
115
- it "test" do
116
- subject.default_attributes = {
117
- deep: {
118
- nested: {
119
- item: false
120
- }
121
- }
122
- }
123
- subject.set_default_attribute('deep.nested.item', true)
124
-
125
- subject.default_attributes["deep"]["nested"]["item"].should be_true
126
- end
18
+ subject.delete_all
127
19
  end
128
20
  end
129
21
  end
@@ -1,12 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::NodeResource do
4
- it_behaves_like "a Ridley Resource", Ridley::NodeResource
5
-
6
- let(:connection) do
7
- double('conn',
4
+ let(:host) { "33.33.33.10" }
5
+ let(:worker) { double('worker', alive?: true, terminate: nil) }
6
+ let(:options) do
7
+ {
8
8
  server_url: "https://api.opscode.com/organizations/vialstudios",
9
+ validator_path: "/some/path",
9
10
  validator_client: "chef-validator",
11
+ encrypted_data_bag_secret: "hellokitty",
10
12
  ssh: {
11
13
  user: "reset",
12
14
  password: "lol"
@@ -15,446 +17,133 @@ describe Ridley::NodeResource do
15
17
  user: "Administrator",
16
18
  password: "secret"
17
19
  },
18
- encrypted_data_bag_secret_path: nil
19
- )
20
- end
21
- let(:host) { "33.33.33.10" }
22
-
23
- describe "ClassMethods" do
24
- subject { Ridley::NodeResource }
25
-
26
- let(:worker) { double('worker', alive?: true, terminate: nil) }
27
-
28
- describe "::bootstrap" do
29
- let(:boot_options) do
30
- {
31
- validator_path: fixtures_path.join("reset.pem").to_s,
32
- encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s
33
- }
34
- end
35
-
36
- it "bootstraps a single node" do
37
- pending
38
- subject.bootstrap(connection, "33.33.33.10", boot_options)
39
- end
40
-
41
- it "bootstraps multiple nodes" do
42
- pending
43
- subject.bootstrap(connection, "33.33.33.10", "33.33.33.11", boot_options)
44
- end
45
- end
46
-
47
- describe "::chef_run" do
48
- subject { chef_run }
49
- let(:chef_run) { described_class.chef_run(connection, host) }
50
- let(:response) { [:ok, double('response', stdout: 'success_message')] }
51
-
52
- before do
53
- Ridley::NodeResource.stub(:configured_worker_for).and_return(worker)
54
- worker.stub(:chef_client).and_return(response)
55
- end
56
-
57
- it { should eq(response) }
58
-
59
- context "when it executes unsuccessfully" do
60
- let(:response) { [:error, double('response', stderr: 'failure_message')] }
61
-
62
- it {should eq(response)}
63
- end
64
-
65
- it "terminates the worker" do
66
- worker.should_receive(:terminate)
67
- chef_run
68
- end
69
- end
70
-
71
- describe "::put_secret" do
72
- subject { put_secret }
73
- let(:put_secret) { described_class.put_secret(connection, host, secret_path)}
74
- let(:response) { [:ok, double('response', stdout: 'success_message')] }
75
- let(:secret_path) { fixtures_path.join("reset.pem").to_s }
76
-
77
- before do
78
- Ridley::NodeResource.stub(:configured_worker_for).and_return(worker)
79
- worker.stub(:put_secret).and_return(response)
80
- end
81
-
82
- it { should eq(response) }
83
-
84
- context "when it executes unsuccessfully" do
85
- let(:response) { [:error, double('response', stderr: 'failure_message')] }
86
-
87
- it { should eq(response) }
88
- end
89
-
90
- it "terminates the worker" do
91
- worker.should_receive(:terminate)
92
- put_secret
93
- end
94
- end
95
-
96
- describe "::ruby_script" do
97
- subject { ruby_script }
98
- let(:ruby_script) { described_class.ruby_script(connection, host, command_lines) }
99
- let(:response) { [:ok, double('response', stdout: 'success_message')] }
100
- let(:command_lines) { ["puts 'hello'", "puts 'there'"] }
101
-
102
- before do
103
- Ridley::NodeResource.stub(:configured_worker_for).and_return(worker)
104
- worker.stub(:ruby_script).and_return(response)
105
- end
106
-
107
- it { should eq(response) }
108
-
109
- context "when it executes unsuccessfully" do
110
- let(:response) { [:error, double('response', stderr: 'failure_message')] }
111
-
112
- it { should eq(response) }
113
- end
114
-
115
- it "terminates the worker" do
116
- worker.should_receive(:terminate)
117
- ruby_script
118
- end
119
- end
120
-
121
- describe "::execute_command" do
122
- subject { execute_command }
123
-
124
- let(:execute_command) { described_class.execute_command(connection, host, command) }
125
- let(:response) { [:ok, double('response', stdout: 'success_message')] }
126
- let(:command) { "echo 'hello world'" }
127
-
128
- before do
129
- Ridley::NodeResource.stub(:configured_worker_for).and_return(worker)
130
- worker.stub(:run).and_return(response)
131
- end
132
-
133
- it { should eq(response) }
134
-
135
- context "when it executes unsuccessfully" do
136
- let(:response) { [:error, double('response', stderr: 'failure_message')] }
137
-
138
- it { should eq(response) }
139
- end
140
- end
141
-
142
- describe "::configured_worker_for" do
143
- subject { configured_worker_for }
144
-
145
- let(:configured_worker_for) { described_class.send(:configured_worker_for, connection, host) }
146
-
147
- context "when the best connector is SSH" do
148
- before do
149
- Ridley::HostConnector.stub(:best_connector_for).and_yield(Ridley::HostConnector::SSH)
150
- end
151
-
152
- it "returns an SSH worker instance" do
153
- configured_worker_for.should be_a(Ridley::HostConnector::SSH::Worker)
154
- end
155
-
156
- its(:user) { should eq("reset") }
157
- end
158
-
159
- context "when the best connector is WinRM" do
160
- before do
161
- Ridley::HostConnector.stub(:best_connector_for).and_yield(Ridley::HostConnector::WinRM)
162
- Ridley::HostConnector::WinRM::CommandUploader.stub(:new)
163
- end
164
-
165
- it "returns a WinRm worker instance" do
166
- configured_worker_for.should be_a(Ridley::HostConnector::WinRM::Worker)
167
- end
168
-
169
- its(:user) { should eq("Administrator") }
170
- its(:password) { should eq("secret") }
171
- end
172
- end
173
-
174
- describe "::merge_data" do
175
- it "finds the target node and sends it the merge_data message" do
176
- data = double('data')
177
- node = double('node')
178
- node.should_receive(:merge_data).with(data)
179
- subject.should_receive(:find!).and_return(node)
180
-
181
- subject.merge_data(connection, node, data)
182
- end
183
- end
184
- end
185
-
186
- subject { node_resource }
187
- let(:node_resource) { Ridley::NodeResource.new(connection) }
188
-
189
- describe "#set_chef_attribute" do
190
- it "sets an normal node attribute at the nested path" do
191
- subject.set_chef_attribute('deep.nested.item', true)
192
-
193
- subject.normal.should have_key("deep")
194
- subject.normal["deep"].should have_key("nested")
195
- subject.normal["deep"]["nested"].should have_key("item")
196
- subject.normal["deep"]["nested"]["item"].should be_true
197
- end
198
-
199
- context "when the normal attribute is already set" do
200
- it "test" do
201
- subject.normal = {
202
- deep: {
203
- nested: {
204
- item: false
205
- }
206
- }
207
- }
208
- subject.set_chef_attribute('deep.nested.item', true)
209
-
210
- subject.normal["deep"]["nested"]["item"].should be_true
211
- end
212
- end
20
+ chef_version: "11.4.0"
21
+ }
213
22
  end
214
-
215
- describe "#cloud?" do
216
- it "returns true if the cloud automatic attribute is set" do
217
- subject.automatic = {
218
- "cloud" => Hash.new
23
+ let(:instance) { described_class.new(double, options) }
24
+
25
+ describe "#bootstrap" do
26
+ let(:hosts) { [ "192.168.1.2" ] }
27
+ let(:options) do
28
+ {
29
+ validator_path: fixtures_path.join("reset.pem").to_s,
30
+ encrypted_data_bag_secret: File.read(fixtures_path.join("reset.pem"))
219
31
  }
220
-
221
- subject.cloud?.should be_true
222
32
  end
33
+ let(:bootstrapper) { double('bootstrapper', run: nil) }
34
+ subject { instance }
35
+ before { Ridley::Bootstrapper.should_receive(:new).with(hosts, anything).and_return(bootstrapper) }
223
36
 
224
- it "returns false if the cloud automatic attribute is not set" do
225
- subject.automatic.delete(:cloud)
37
+ it "runs the Bootstrapper" do
38
+ bootstrapper.should_receive(:run)
226
39
 
227
- subject.cloud?.should be_false
40
+ subject.bootstrap("192.168.1.2", options)
228
41
  end
229
42
  end
230
43
 
231
- describe "#eucalyptus?" do
232
- it "returns true if the node is a cloud node using the eucalyptus provider" do
233
- subject.automatic = {
234
- "cloud" => {
235
- "provider" => "eucalyptus"
236
- }
237
- }
238
-
239
- subject.eucalyptus?.should be_true
240
- end
241
-
242
- it "returns false if the node is not a cloud node" do
243
- subject.automatic.delete(:cloud)
44
+ describe "#chef_run" do
45
+ let(:chef_run) { instance.chef_run(host) }
46
+ let(:response) { [:ok, double('response', stdout: 'success_message')] }
47
+ subject { chef_run }
244
48
 
245
- subject.eucalyptus?.should be_false
49
+ before do
50
+ Ridley::HostConnector.stub(:new).and_return(worker)
51
+ worker.stub(:chef_client).and_return(response)
246
52
  end
247
53
 
248
- it "returns false if the node is a cloud node but not using the eucalyptus provider" do
249
- subject.automatic = {
250
- "cloud" => {
251
- "provider" => "ec2"
252
- }
253
- }
254
-
255
- subject.eucalyptus?.should be_false
256
- end
257
- end
54
+ it { should eql(response) }
258
55
 
259
- describe "#ec2?" do
260
- it "returns true if the node is a cloud node using the ec2 provider" do
261
- subject.automatic = {
262
- "cloud" => {
263
- "provider" => "ec2"
264
- }
265
- }
56
+ context "when it executes unsuccessfully" do
57
+ let(:response) { [ :error, double('response', stderr: 'failure_message') ] }
266
58
 
267
- subject.ec2?.should be_true
59
+ it { should eql(response) }
268
60
  end
269
61
 
270
- it "returns false if the node is not a cloud node" do
271
- subject.automatic.delete(:cloud)
272
-
273
- subject.ec2?.should be_false
274
- end
275
-
276
- it "returns false if the node is a cloud node but not using the ec2 provider" do
277
- subject.automatic = {
278
- "cloud" => {
279
- "provider" => "rackspace"
280
- }
281
- }
282
-
283
- subject.ec2?.should be_false
62
+ it "terminates the worker" do
63
+ worker.should_receive(:terminate)
64
+ chef_run
284
65
  end
285
66
  end
286
67
 
287
- describe "#rackspace?" do
288
- it "returns true if the node is a cloud node using the rackspace provider" do
289
- subject.automatic = {
290
- "cloud" => {
291
- "provider" => "rackspace"
292
- }
293
- }
68
+ describe "#put_secret" do
69
+ let(:put_secret) { instance.put_secret(host) }
70
+ let(:response) { [ :ok, double('response', stdout: 'success_message') ] }
71
+ subject { put_secret }
294
72
 
295
- subject.rackspace?.should be_true
73
+ before do
74
+ Ridley::HostConnector.stub(:new).and_return(worker)
75
+ worker.stub(:put_secret).and_return(response)
296
76
  end
297
77
 
298
- it "returns false if the node is not a cloud node" do
299
- subject.automatic.delete(:cloud)
300
-
301
- subject.rackspace?.should be_false
302
- end
78
+ it { should eql(response) }
303
79
 
304
- it "returns false if the node is a cloud node but not using the rackspace provider" do
305
- subject.automatic = {
306
- "cloud" => {
307
- "provider" => "ec2"
308
- }
309
- }
80
+ context "when it executes unsuccessfully" do
81
+ let(:response) { [ :error, double('response', stderr: 'failure_message') ] }
310
82
 
311
- subject.rackspace?.should be_false
83
+ it { should eql(response) }
312
84
  end
313
- end
314
-
315
- describe "#cloud_provider" do
316
- it "returns the cloud provider if the node is a cloud node" do
317
- subject.automatic = {
318
- "cloud" => {
319
- "provider" => "ec2"
320
- }
321
- }
322
85
 
323
- subject.cloud_provider.should eql("ec2")
324
- end
325
-
326
- it "returns nil if the node is not a cloud node" do
327
- subject.automatic.delete(:cloud)
328
-
329
- subject.cloud_provider.should be_nil
86
+ it "terminates the worker" do
87
+ worker.should_receive(:terminate)
88
+ put_secret
330
89
  end
331
90
  end
332
91
 
333
- describe "#public_ipv4" do
334
- it "returns the public ipv4 address if the node is a cloud node" do
335
- subject.automatic = {
336
- "cloud" => {
337
- "provider" => "ec2",
338
- "public_ipv4" => "10.0.0.1"
339
- }
340
- }
92
+ describe "#ruby_script" do
93
+ let(:ruby_script) { instance.ruby_script(host, command_lines) }
94
+ let(:response) { [:ok, double('response', stdout: 'success_message')] }
95
+ let(:command_lines) { ["puts 'hello'", "puts 'there'"] }
96
+ subject { ruby_script }
341
97
 
342
- subject.public_ipv4.should eql("10.0.0.1")
98
+ before do
99
+ Ridley::HostConnector.stub(:new).and_return(worker)
100
+ worker.stub(:ruby_script).and_return(response)
343
101
  end
344
102
 
345
- it "returns the ipaddress if the node is not a cloud node" do
346
- subject.automatic = {
347
- "ipaddress" => "192.168.1.1"
348
- }
349
- subject.automatic.delete(:cloud)
350
-
351
- subject.public_ipv4.should eql("192.168.1.1")
352
- end
353
- end
103
+ it { should eq(response) }
354
104
 
355
- describe "#public_hostname" do
356
- it "returns the public hostname if the node is a cloud node" do
357
- subject.automatic = {
358
- "cloud" => {
359
- "public_hostname" => "reset.cloud.riotgames.com"
360
- }
361
- }
105
+ context "when it executes unsuccessfully" do
106
+ let(:response) { [:error, double('response', stderr: 'failure_message')] }
362
107
 
363
- subject.public_hostname.should eql("reset.cloud.riotgames.com")
108
+ it { should eq(response) }
364
109
  end
365
110
 
366
- it "returns the FQDN if the node is not a cloud node" do
367
- subject.automatic = {
368
- "fqdn" => "reset.internal.riotgames.com"
369
- }
370
- subject.automatic.delete(:cloud)
371
-
372
- subject.public_hostname.should eql("reset.internal.riotgames.com")
111
+ it "terminates the worker" do
112
+ worker.should_receive(:terminate)
113
+ ruby_script
373
114
  end
374
115
  end
375
116
 
376
- describe "#chef_solo" do
377
- pending
378
- end
379
-
380
- describe "#chef_client" do
381
- subject { chef_client }
382
- let(:chef_client) { node_resource.chef_client }
383
- let(:worker) { double('worker', chef_client: response) }
384
- let(:response) { [:ok, Ridley::HostConnector::Response.new(host)] }
117
+ describe "#execute_command" do
118
+ let(:execute_command) { instance.execute_command(host, command) }
119
+ let(:response) { [:ok, double('response', stdout: 'success_message')] }
120
+ let(:command) { "echo 'hello world'" }
121
+ subject { execute_command }
385
122
 
386
123
  before do
387
- Ridley::HostConnector.stub(:best_connector_for).and_yield(Ridley::HostConnector::SSH)
388
- Ridley::HostConnector::SSH.stub(:start).and_yield(worker)
124
+ Ridley::HostConnector.stub(:new).and_return(worker)
125
+ worker.stub(:run).and_return(response)
389
126
  end
390
127
 
391
- it "returns a HostConnector::Response" do
392
-
393
- chef_client.should be_a(Ridley::HostConnector::Response)
394
- end
395
- end
396
-
397
- describe "#put_secret" do
398
- subject { put_secret }
399
- let(:put_secret) { node_resource.put_secret }
400
- let(:worker) { double('worker', put_secret: response) }
401
- let(:response) { [:ok, Ridley::HostConnector::Response.new(host)] }
402
-
403
- before do
404
- Ridley::HostConnector.stub(:best_connector_for).and_yield(Ridley::HostConnector::SSH)
405
- Ridley::HostConnector::SSH.stub(:start).and_yield(worker)
406
- end
128
+ it { should eq(response) }
407
129
 
408
- context "when the client does not have an encrypted file" do
409
- it "returns nil" do
410
- put_secret.should be_nil
411
- end
412
- end
130
+ context "when it executes unsuccessfully" do
131
+ let(:response) { [:error, double('response', stderr: 'failure_message')] }
413
132
 
414
- it "returns a HostConnector::Response" do
415
- pending
133
+ it { should eq(response) }
416
134
  end
417
135
  end
418
136
 
419
137
  describe "#merge_data" do
420
- before(:each) do
421
- subject.name = "reset.riotgames.com"
422
- subject.should_receive(:update)
423
- end
138
+ subject { instance }
424
139
 
425
- it "appends items to the run_list" do
426
- subject.merge_data(run_list: ["cook::one", "cook::two"])
427
-
428
- subject.run_list.should =~ ["cook::one", "cook::two"]
429
- end
430
-
431
- it "ensures the run_list is unique if identical items are given" do
432
- subject.run_list = [ "cook::one" ]
433
- subject.merge_data(run_list: ["cook::one", "cook::two"])
434
-
435
- subject.run_list.should =~ ["cook::one", "cook::two"]
436
- end
437
-
438
- it "deep merges attributes into the normal attributes" do
439
- subject.normal = {
440
- one: {
441
- two: {
442
- four: :deep
443
- }
444
- }
445
- }
446
- subject.merge_data(attributes: {
447
- one: {
448
- two: {
449
- three: :deep
450
- }
451
- }
452
- })
140
+ it "finds the target node and sends it the merge_data message" do
141
+ data = double('data')
142
+ node = double('node')
143
+ node.should_receive(:merge_data).with(data)
144
+ subject.should_receive(:find).and_return(node)
453
145
 
454
- subject.normal[:one][:two].should have_key(:four)
455
- subject.normal[:one][:two][:four].should eql(:deep)
456
- subject.normal[:one][:two].should have_key(:three)
457
- subject.normal[:one][:two][:three].should eql(:deep)
146
+ subject.merge_data(node, data)
458
147
  end
459
148
  end
460
149
  end