ridley 0.10.2 → 0.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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