stackfu 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +24 -0
- data/Manifest +118 -0
- data/README +0 -0
- data/README.md +218 -0
- data/Rakefile +73 -0
- data/bin/stackfu +10 -0
- data/lib/stackfu/api_hooks.rb +17 -0
- data/lib/stackfu/app.rb +69 -0
- data/lib/stackfu/commands/command.rb +127 -0
- data/lib/stackfu/commands/config_command.rb +43 -0
- data/lib/stackfu/commands/deploy_command.rb +144 -0
- data/lib/stackfu/commands/dump_command.rb +101 -0
- data/lib/stackfu/commands/generate_command.rb +107 -0
- data/lib/stackfu/commands/help_command.rb +28 -0
- data/lib/stackfu/commands/list_command.rb +26 -0
- data/lib/stackfu/commands/publish_command.rb +108 -0
- data/lib/stackfu/commands/server_command.rb +124 -0
- data/lib/stackfu/helpers/providers_credentials.rb +82 -0
- data/lib/stackfu/helpers/rendering.rb +201 -0
- data/lib/stackfu/operating_systems.rb +30 -0
- data/lib/stackfu.rb +88 -0
- data/stackfu-installer/config/01-controls.yml +17 -0
- data/stackfu-installer/config/02-requirements.yml +3 -0
- data/stackfu-installer/config/03-scripts.yml +16 -0
- data/stackfu-installer/config/04-validations.yml +3 -0
- data/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
- data/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
- data/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
- data/stackfu-installer/script/redis_installation.sh.erb +33 -0
- data/stackfu-installer/script/resque_installation.sh.erb +7 -0
- data/stackfu-installer/script/ruby_environment.sh.erb +20 -0
- data/stackfu-installer/script/stackfu.sh.erb +114 -0
- data/stackfu-installer/stack.yml +5 -0
- data/stackfu.gemspec +60 -0
- data/templates/01-controls.yml.erb +31 -0
- data/templates/02-requirements.yml.erb +26 -0
- data/templates/03-scripts.yml.erb +34 -0
- data/templates/04-validations.yml.erb +17 -0
- data/templates/script.sh.erb +7 -0
- data/templates/stack.yml.erb +17 -0
- data/test/fixtures/add_server_error +7 -0
- data/test/fixtures/deployment_add +7 -0
- data/test/fixtures/deployment_add_error +8 -0
- data/test/fixtures/deployments +7 -0
- data/test/fixtures/logs +7 -0
- data/test/fixtures/logs_partial +7 -0
- data/test/fixtures/plugin_add +6 -0
- data/test/fixtures/plugin_add_error +8 -0
- data/test/fixtures/plugin_deployment_add +7 -0
- data/test/fixtures/plugin_not_found +7 -0
- data/test/fixtures/plugin_unauthorized +8 -0
- data/test/fixtures/plugins +7 -0
- data/test/fixtures/plugins_by_name +7 -0
- data/test/fixtures/plugins_by_name_other +7 -0
- data/test/fixtures/plugins_empty +7 -0
- data/test/fixtures/plugins_multiple +7 -0
- data/test/fixtures/providers +7 -0
- data/test/fixtures/providers_servers +7 -0
- data/test/fixtures/server_add +6 -0
- data/test/fixtures/server_add_dupe +7 -0
- data/test/fixtures/server_add_error +7 -0
- data/test/fixtures/server_delete +7 -0
- data/test/fixtures/server_delete_error +7 -0
- data/test/fixtures/servers +7 -0
- data/test/fixtures/servers_by_name +7 -0
- data/test/fixtures/servers_empty +8 -0
- data/test/fixtures/servers_not_found +26 -0
- data/test/fixtures/servers_unauthorized +8 -0
- data/test/fixtures/servers_webbynode +7 -0
- data/test/fixtures/stack/stackfu-installer/config/01-controls.yml +22 -0
- data/test/fixtures/stack/stackfu-installer/config/02-requirements.yml +1 -0
- data/test/fixtures/stack/stackfu-installer/config/03-scripts.yml +23 -0
- data/test/fixtures/stack/stackfu-installer/config/04-validations.yml +1 -0
- data/test/fixtures/stack/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
- data/test/fixtures/stack/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
- data/test/fixtures/stack/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
- data/test/fixtures/stack/stackfu-installer/script/redis_installation.sh.erb +33 -0
- data/test/fixtures/stack/stackfu-installer/script/resque_installation.sh.erb +7 -0
- data/test/fixtures/stack/stackfu-installer/script/ruby_environment.sh.erb +20 -0
- data/test/fixtures/stack/stackfu-installer/script/stackfu.sh.erb +76 -0
- data/test/fixtures/stack/stackfu-installer/stack.yml +5 -0
- data/test/fixtures/stack_add +6 -0
- data/test/fixtures/stack_add_error +8 -0
- data/test/fixtures/stack_add_error_dupe +8 -0
- data/test/fixtures/stack_adds_by_name +7 -0
- data/test/fixtures/stack_delete_not_found +7 -0
- data/test/fixtures/stacks +7 -0
- data/test/fixtures/stacks_by_name +7 -0
- data/test/fixtures/stacks_by_name_other +7 -0
- data/test/fixtures/stacks_empty +7 -0
- data/test/fixtures/stacks_multiple +7 -0
- data/test/fixtures/stacks_not_found +7 -0
- data/test/fixtures/stacks_realworld +7 -0
- data/test/fixtures/stacks_stackfu-installer +7 -0
- data/test/fixtures/stacks_unauthorized +8 -0
- data/test/fixtures/stacks_with_controls +0 -0
- data/test/fixtures/users +7 -0
- data/test/fixtures/users_no_credentials +7 -0
- data/test/fixtures/users_update +6 -0
- data/test/stack.yml +26 -0
- data/test/support/custom_matchers.rb +69 -0
- data/test/support/fixtures.rb +98 -0
- data/test/support/io_stub.rb +10 -0
- data/test/support/web_fixtures.rb +91 -0
- data/test/test_helper.rb +186 -0
- data/test/unit/commands/test_command.rb +112 -0
- data/test/unit/commands/test_config_command.rb +92 -0
- data/test/unit/commands/test_deploy_command.rb +303 -0
- data/test/unit/commands/test_dump_command.rb +155 -0
- data/test/unit/commands/test_generate_command.rb +112 -0
- data/test/unit/commands/test_help_command.rb +33 -0
- data/test/unit/commands/test_list_command.rb +63 -0
- data/test/unit/commands/test_publish_command.rb +265 -0
- data/test/unit/commands/test_server_command.rb +259 -0
- data/test/unit/helpers/test_rendering.rb +141 -0
- data/test/unit/test_array.rb +26 -0
- data/test/unit/test_provider.rb +14 -0
- data/test/unit/test_stackfu.rb +27 -0
- metadata +311 -0
@@ -0,0 +1,303 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper.rb'
|
2
|
+
|
3
|
+
class TestDeployCommand < Test::Unit::TestCase
|
4
|
+
should "map 'deploy' to DeployCommand" do
|
5
|
+
Command.create("deploy").class.should == DeployCommand
|
6
|
+
end
|
7
|
+
|
8
|
+
should "present the options when none given" do
|
9
|
+
command "deploy"
|
10
|
+
stdout.should =~ /You have to tell what you want to deploy \(a stack or a plugin\) and to which server/
|
11
|
+
end
|
12
|
+
|
13
|
+
should "show an error when the wrong item is set to deploy" do
|
14
|
+
command "deploy something"
|
15
|
+
stdout.should_not =~ /Command deploy is invalid/
|
16
|
+
stdout.should =~ /You have to tell what you want to deploy \(a stack or a plugin\) and to which server/
|
17
|
+
end
|
18
|
+
|
19
|
+
# === PLUGIN DEPLOYMENT ===
|
20
|
+
|
21
|
+
should "show an error when the plugin is not found" do
|
22
|
+
with_plugins("empty", "plugin%5Bname%5D=my_plugin")
|
23
|
+
command "deploy plugin my_plugin server"
|
24
|
+
stdout.should =~ /Plugin 'my_plugin' was not found/
|
25
|
+
end
|
26
|
+
|
27
|
+
should "show an error when plugin found but server not found" do
|
28
|
+
with_plugins("by_name", "plugin%5Bname%5D=my_plugin")
|
29
|
+
with_server_list("empty", "server%5Bhostname%5D=slicey")
|
30
|
+
command "deploy plugin my_plugin slicey"
|
31
|
+
stdout.should =~ /Server 'slicey' was not found/
|
32
|
+
end
|
33
|
+
|
34
|
+
should "tell the user if there's a problem submitting the deployment of a plugin" do
|
35
|
+
with_plugins("by_name", "plugin%5Bname%5D=my_plugin")
|
36
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
37
|
+
with_new_deployment("error")
|
38
|
+
|
39
|
+
when_asked " Nome: ", :answer => "Felipe"
|
40
|
+
when_asked " Idade: ", :answer => "31"
|
41
|
+
|
42
|
+
agree_with "Continue with plugin installation?\n"
|
43
|
+
|
44
|
+
command "deploy plugin my_plugin slicey"
|
45
|
+
stdout.should =~ /There was a problem submitting your deployment: This is an error/
|
46
|
+
end
|
47
|
+
|
48
|
+
should "stop deploying if user disagree of continueing" do
|
49
|
+
with_plugins("by_name", "plugin%5Bname%5D=my_plugin")
|
50
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
51
|
+
with_new_deployment("error")
|
52
|
+
|
53
|
+
when_asked " Nome: ", :answer => "Felipe"
|
54
|
+
when_asked " Idade: ", :answer => "31"
|
55
|
+
|
56
|
+
disagree_of "Continue with plugin installation?\n"
|
57
|
+
|
58
|
+
command "deploy plugin my_plugin slicey"
|
59
|
+
stdout.should =~ /Aborted./
|
60
|
+
end
|
61
|
+
|
62
|
+
should "submit the deployment when plugin and server exists" do
|
63
|
+
with_plugins("by_name", "plugin%5Bname%5D=my_plugin")
|
64
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
65
|
+
with_new_deployment
|
66
|
+
|
67
|
+
when_asked " Nome: ", :answer => "Felipe"
|
68
|
+
when_asked " Idade: ", :answer => "31"
|
69
|
+
|
70
|
+
agree_with "Continue with plugin installation?\n"
|
71
|
+
|
72
|
+
uri = StackFu::API.gsub(/api/, "flipper:abc123@api")
|
73
|
+
FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001.json",
|
74
|
+
:response => fixture("deployments"))
|
75
|
+
|
76
|
+
FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=",
|
77
|
+
:response => fixture("logs"))
|
78
|
+
|
79
|
+
FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true",
|
80
|
+
:response => fixture("logs"))
|
81
|
+
|
82
|
+
FakeWeb.register_uri(:get,
|
83
|
+
"#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=4b0b34c9e1054e3104000109",
|
84
|
+
:response => fixture("logs_partial"))
|
85
|
+
|
86
|
+
command "deploy plugin my_plugin slicey"
|
87
|
+
|
88
|
+
stdout.should =~ /Preparing:/
|
89
|
+
stdout.should =~ /my_plugin/
|
90
|
+
stdout.should =~ /This will deploy my plugin/
|
91
|
+
stdout.should =~ /Enqueued for execution \(deployment id 4b0b3421e1054e3102000001 at Tue Nov 24 01:17:25 UTC 2009\)/
|
92
|
+
stdout.should_not =~ /Please review the configuration for your deployment:/
|
93
|
+
end
|
94
|
+
|
95
|
+
should "indicate an error ocurred" # do
|
96
|
+
# with_plugins("by_name", "plugin%5Bname%5D=my_plugin")
|
97
|
+
# with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
98
|
+
# with_new_deployment
|
99
|
+
#
|
100
|
+
# when_asked " Nome: ", :answer => "Felipe"
|
101
|
+
# when_asked " Idade: ", :answer => "31"
|
102
|
+
#
|
103
|
+
# agree_with "Continue with plugin installation?\n"
|
104
|
+
#
|
105
|
+
# uri = StackFu::API.gsub(/api/, "flipper:abc123@api")
|
106
|
+
# FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001.json",
|
107
|
+
# :response => fixture("deployments"))
|
108
|
+
#
|
109
|
+
# FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=",
|
110
|
+
# :response => fixture("logs"))
|
111
|
+
#
|
112
|
+
# FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true",
|
113
|
+
# :response => fixture("logs"))
|
114
|
+
#
|
115
|
+
# FakeWeb.register_uri(:get,
|
116
|
+
# "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=4b0b34c9e1054e3104000109",
|
117
|
+
# :response => fixture("logs_partial"))
|
118
|
+
#
|
119
|
+
# d "\n--start--"
|
120
|
+
# command "deploy plugin my_plugin slicey"
|
121
|
+
# d "--end--\n"
|
122
|
+
#
|
123
|
+
# stdout.should =~ /Preparing:/
|
124
|
+
# stdout.should =~ /my_plugin/
|
125
|
+
# stdout.should =~ /This will deploy my plugin/
|
126
|
+
# stdout.should =~ /Enqueued for execution \(deployment id 4b0b3421e1054e3102000001 at Tue Nov 24 01:17:25 UTC 2009\)/
|
127
|
+
# stdout.should =~ /Please review the configuration for your deployment:/
|
128
|
+
# stdout.should =~ /Nome: Felipe/
|
129
|
+
# stdout.should =~ /Idade: Felipe/
|
130
|
+
#end
|
131
|
+
|
132
|
+
# === STACK DEPLOYMENT ===
|
133
|
+
|
134
|
+
should "show an error when the stack is not found" do
|
135
|
+
with_stacks("empty", "stack%5Bname%5D=my_stack")
|
136
|
+
command "deploy stack my_stack server"
|
137
|
+
stdout.should =~ /Stack 'my_stack' was not found/
|
138
|
+
end
|
139
|
+
|
140
|
+
should "show an error when server not found" do
|
141
|
+
with_stacks("by_name", "stack%5Bname%5D=my_stack")
|
142
|
+
with_server_list("empty", "server%5Bhostname%5D=slicey")
|
143
|
+
command "deploy stack my_stack slicey"
|
144
|
+
stdout.should =~ /Server 'slicey' was not found/
|
145
|
+
end
|
146
|
+
|
147
|
+
should "tell the user if there's a problem submitting the deployment" do
|
148
|
+
with_stacks("by_name", "stack%5Bname%5D=my_stack")
|
149
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
150
|
+
with_new_deployment("error")
|
151
|
+
|
152
|
+
when_asked " Nome: ", :answer => "Felipe"
|
153
|
+
when_asked " Idade: ", :answer => "31"
|
154
|
+
|
155
|
+
agree_with "This will destroy current contents of your server. Are you sure?\n"
|
156
|
+
|
157
|
+
command "deploy stack my_stack slicey"
|
158
|
+
stdout.should =~ /There was a problem submitting your deployment: This is an error/
|
159
|
+
end
|
160
|
+
|
161
|
+
should "submit the deployment when stack and server exists" do
|
162
|
+
with_stacks("by_name", "stack%5Bname%5D=my_stack")
|
163
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
164
|
+
with_new_deployment
|
165
|
+
|
166
|
+
uri = StackFu::API.gsub(/api/, "flipper:abc123@api")
|
167
|
+
FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001.json",
|
168
|
+
:response => fixture("deployments"))
|
169
|
+
|
170
|
+
FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=",
|
171
|
+
:response => fixture("logs"))
|
172
|
+
|
173
|
+
FakeWeb.register_uri(:get, "#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true",
|
174
|
+
:response => fixture("logs"))
|
175
|
+
|
176
|
+
FakeWeb.register_uri(:get,
|
177
|
+
"#{uri}/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=4b0b34c9e1054e3104000109",
|
178
|
+
:response => fixture("logs_partial"))
|
179
|
+
|
180
|
+
# require 'net/http'
|
181
|
+
# require 'uri'
|
182
|
+
#
|
183
|
+
# Net::HTTP.start('api.stackfu.com') {|http|
|
184
|
+
# req = Net::HTTP::Get.new('/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true')
|
185
|
+
# req.basic_auth 'flipper', 'abc123'
|
186
|
+
# response = http.request(req)
|
187
|
+
# # ppd JSON.load(response.body)
|
188
|
+
# }
|
189
|
+
#
|
190
|
+
# Net::HTTP.start('api.stackfu.com') {|http|
|
191
|
+
# req = Net::HTTP::Get.new('/deployments/4b0b3421e1054e3102000001/logs.json?formatted=true&from=4b0b34c9e1054e3104000109')
|
192
|
+
# req.basic_auth 'flipper', 'abc123'
|
193
|
+
# response = http.request(req)
|
194
|
+
# # d response.body
|
195
|
+
# # d JSON.load(response.body)["id"]
|
196
|
+
# # d JSON.load(response.body)["log"]
|
197
|
+
# }
|
198
|
+
|
199
|
+
when_asked " Nome: ", :answer => "Felipe"
|
200
|
+
when_asked " Idade: ", :answer => "31"
|
201
|
+
|
202
|
+
agree_with "This will destroy current contents of your server. Are you sure?\n"
|
203
|
+
|
204
|
+
command "deploy stack my_stack slicey"
|
205
|
+
|
206
|
+
stdout.should =~ /Deploying:/
|
207
|
+
stdout.should =~ /Ubuntu 8.10/
|
208
|
+
stdout.should =~ /my_stack/
|
209
|
+
stdout.should =~ /This will deploy my stack/
|
210
|
+
stdout.should =~ /Enqueued for execution \(deployment id 4b0b3421e1054e3102000001 at Tue Nov 24 01:17:25 UTC 2009\)/
|
211
|
+
stdout.should_not =~ /Please review the configuration for your deployment:/
|
212
|
+
end
|
213
|
+
|
214
|
+
should "pass the params" do
|
215
|
+
stack = mock("stack")
|
216
|
+
stack.expects(:name).returns("my_stack")
|
217
|
+
stack.expects(:operating_system).returns("ubuntu_810")
|
218
|
+
stack.expects(:description).returns("My stack description")
|
219
|
+
|
220
|
+
control = mock("control")
|
221
|
+
control.expects(:label).at_least_once.returns("Nome")
|
222
|
+
control.expects(:name).at_least_once.returns("name")
|
223
|
+
control.expects(:_type).at_least_once.returns("Textbox")
|
224
|
+
stack.expects(:controls).at_least_once.returns([control])
|
225
|
+
|
226
|
+
ApiHooks::Stack.expects(:find).returns([stack])
|
227
|
+
|
228
|
+
server = mock("server")
|
229
|
+
server.expects(:id).twice.returns(123)
|
230
|
+
ApiHooks::Server.expects(:find).returns([server])
|
231
|
+
|
232
|
+
deployment = mock("deployment")
|
233
|
+
deployment.expects(:save).returns(true)
|
234
|
+
|
235
|
+
ApiHooks::Deployment.expects(:new).with(:stack => stack, :server_id => server.id, :params => {"name" => "Felipe"}).returns(deployment)
|
236
|
+
|
237
|
+
when_asked " Nome: ", :answer => "Felipe"
|
238
|
+
|
239
|
+
agree_with "This will destroy current contents of your server. Are you sure?\n"
|
240
|
+
|
241
|
+
command "deploy stack my_stack slicey --no-follow"
|
242
|
+
stdout.should =~ /Deploying:/
|
243
|
+
end
|
244
|
+
|
245
|
+
should "not tell the user to enter values if they are all provided" do
|
246
|
+
with_stacks("by_name", "stack%5Bname%5D=my_stack")
|
247
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
248
|
+
with_new_deployment
|
249
|
+
|
250
|
+
agree_with "This will destroy current contents of your server. Are you sure?\n"
|
251
|
+
|
252
|
+
command "deploy stack my_stack slicey --nome=Felipe --idade=31 --no-follow"
|
253
|
+
|
254
|
+
stdout.should =~ /Deploying:/
|
255
|
+
stdout.should =~ /Ubuntu 8.10/
|
256
|
+
stdout.should =~ /my_stack/
|
257
|
+
stdout.should =~ /This will deploy my stack/
|
258
|
+
stdout.should_not =~ /Please configure your deployment by answering the configuration settings below./
|
259
|
+
stdout.should =~ /Please review the configuration for your deployment:/
|
260
|
+
stdout.should =~ /Nome/
|
261
|
+
stdout.should =~ /Felipe/
|
262
|
+
stdout.should =~ /Idade/
|
263
|
+
stdout.should =~ /31/
|
264
|
+
end
|
265
|
+
|
266
|
+
should "submit the deployment asking only for parameters not provided" do
|
267
|
+
with_stacks("by_name", "stack%5Bname%5D=my_stack")
|
268
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
269
|
+
with_new_deployment
|
270
|
+
|
271
|
+
when_asked " Idade: ", :answer => "31"
|
272
|
+
|
273
|
+
agree_with "This will destroy current contents of your server. Are you sure?\n"
|
274
|
+
|
275
|
+
command "deploy stack my_stack slicey --nome=Felipe --no-follow"
|
276
|
+
|
277
|
+
stdout.should =~ /Deploying:/
|
278
|
+
stdout.should =~ /Ubuntu 8.10/
|
279
|
+
stdout.should =~ /my_stack/
|
280
|
+
stdout.should =~ /This will deploy my stack/
|
281
|
+
stdout.should =~ /Please review the configuration for your deployment:/
|
282
|
+
stdout.should =~ /Nome/
|
283
|
+
stdout.should =~ /Felipe/
|
284
|
+
stdout.should =~ /Idade/
|
285
|
+
stdout.should =~ /31/
|
286
|
+
end
|
287
|
+
|
288
|
+
should "submit the deployment using options should validate values" do
|
289
|
+
with_stacks("by_name", "stack%5Bname%5D=my_stack")
|
290
|
+
with_server_list("by_name", "server%5Bhostname%5D=slicey")
|
291
|
+
with_new_deployment
|
292
|
+
|
293
|
+
when_asked " Nome: ", :answer => "Felipe"
|
294
|
+
when_asked " Idade: ", :answer => "31"
|
295
|
+
|
296
|
+
agree_with "This will destroy current contents of your server. Are you sure?\n"
|
297
|
+
|
298
|
+
command "deploy stack my_stack slicey --idade=Abc --no-follow"
|
299
|
+
|
300
|
+
stdout.should =~ /Value for idade should be numeric/
|
301
|
+
stdout.should_not =~ /Please review the configuration for your deployment:/
|
302
|
+
end
|
303
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper.rb'
|
2
|
+
|
3
|
+
class TestDumpCommand < Test::Unit::TestCase
|
4
|
+
context "validations" do
|
5
|
+
should "map 'dump' to DumpCommand" do
|
6
|
+
Command.create("dump").class.should == DumpCommand
|
7
|
+
end
|
8
|
+
|
9
|
+
should "require a parameter with stack or plugin" do
|
10
|
+
command "dump"
|
11
|
+
stdout.should =~ /You have to tell what you want to dump: a stack or a plugin/
|
12
|
+
end
|
13
|
+
|
14
|
+
should "require a parameter with stack or plugin" do
|
15
|
+
command "dump my_girlfriend"
|
16
|
+
stdout.should =~ /You have to tell what you want to dump: a stack or a plugin/
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "dump a stack requirements" do
|
21
|
+
should "require the stack name" do
|
22
|
+
command "dump stack"
|
23
|
+
stdout.should =~ /requires 1 parameter\./
|
24
|
+
stdout.should =~ /stackfu dump stack STACK_NAME/
|
25
|
+
end
|
26
|
+
|
27
|
+
should "display an error when the stack is not found" do
|
28
|
+
with_stacks("empty", "stack%5Bname%5D=my_stack")
|
29
|
+
command "dump stack my_stack"
|
30
|
+
stdout.should =~ /Stack 'my_stack' was not found/
|
31
|
+
end
|
32
|
+
|
33
|
+
should "display the stack name on the error message" do
|
34
|
+
with_stacks("empty", "stack%5Bname%5D=my_other_stack")
|
35
|
+
command "dump stack my_other_stack"
|
36
|
+
stdout.should =~ /Stack 'my_other_stack' was not found/
|
37
|
+
end
|
38
|
+
|
39
|
+
should "ask before overwriting an existing folder" do
|
40
|
+
with_stacks("multiple", "stack%5Bname%5D=my_stack")
|
41
|
+
|
42
|
+
DumpCommand.any_instance.expects(:directory?).with("my_stack").returns(true)
|
43
|
+
disagree_of("There is already a folder called 'my_stack'. Do you want to overwrite its contents?")
|
44
|
+
|
45
|
+
command "dump stack my_stack"
|
46
|
+
stdout.should =~ /Aborted./
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "a valid dump stack command" do
|
51
|
+
setup do
|
52
|
+
with_stacks("multiple", "stack%5Bname%5D=my_stack")
|
53
|
+
end
|
54
|
+
|
55
|
+
should "create a directory structure that describes the stack" do
|
56
|
+
expects_stack("stackfu-installer")
|
57
|
+
with_stacks("stackfu-installer", "stack%5Bname%5D=stackfu-installer")
|
58
|
+
|
59
|
+
command "dump stack stackfu-installer"
|
60
|
+
stdout.should =~ /^\tcreate stackfu-installer\//
|
61
|
+
stdout.should =~ /^\tcreate stackfu-installer\/stack.yml/
|
62
|
+
stdout.should =~ /^\tcreate stackfu-installer\/config\//
|
63
|
+
stdout.should =~ /^\tcreate stackfu-installer\/config\/01-controls.yml/
|
64
|
+
stdout.should =~ /^\tcreate stackfu-installer\/config\/02-requirements.yml/
|
65
|
+
stdout.should =~ /^\tcreate stackfu-installer\/config\/03-scripts.yml/
|
66
|
+
stdout.should =~ /^\tcreate stackfu-installer\/config\/04-validations.yml/
|
67
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\//
|
68
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\//
|
69
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/dotfiles_installation.sh.erb/
|
70
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/github_credentials_setup.sh.erb/
|
71
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/nginx_and_passenger.sh.erb/
|
72
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/redis_installation.sh.erb/
|
73
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/resque_installation.sh.erb/
|
74
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/ruby_environment.sh.erb/
|
75
|
+
stdout.should =~ /^\tcreate stackfu-installer\/script\/stackfu.sh.erb/
|
76
|
+
stdout.should =~ /^Stack stackfu-installer dumped successfully/
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "helper methods" do
|
81
|
+
should "create a folder" do
|
82
|
+
Dir.expects(:mkdir).with("my_stack")
|
83
|
+
File.stubs(:directory?).once.returns(false)
|
84
|
+
dc = DumpCommand.new(["stack", "my_stack"])
|
85
|
+
dc.send(:create_folder, "my_stack")
|
86
|
+
end
|
87
|
+
|
88
|
+
should "create a folder based on the param" do
|
89
|
+
Dir.expects(:mkdir).with("my_stack_yey")
|
90
|
+
dc = DumpCommand.new(["stack", "my_stack"])
|
91
|
+
dc.send(:create_folder, "my_stack_yey")
|
92
|
+
end
|
93
|
+
|
94
|
+
should "create a file" do
|
95
|
+
file = mock("stack.yml")
|
96
|
+
|
97
|
+
File.expects(:open).with("stack.yml", "w").yields(file)
|
98
|
+
file.expects(:write).with("abcdef")
|
99
|
+
|
100
|
+
dc = DumpCommand.new(["stack", "my_stack"])
|
101
|
+
dc.send(:create_file, "stack.yml", "abcdef")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def expects_stack(stack_name)
|
108
|
+
DumpCommand.any_instance.expects(:directory?).with(stack_name).returns(false)
|
109
|
+
|
110
|
+
expects_create_folder stack_name
|
111
|
+
expects_create_yaml_file "#{stack_name}/stack.yml"
|
112
|
+
|
113
|
+
expects_create_folder stack_name, "config"
|
114
|
+
expects_create_yaml_file "#{stack_name}/config/01-controls.yml"
|
115
|
+
expects_create_yaml_file "#{stack_name}/config/02-requirements.yml"
|
116
|
+
expects_create_yaml_file "#{stack_name}/config/03-scripts.yml"
|
117
|
+
expects_create_yaml_file "#{stack_name}/config/04-validations.yml"
|
118
|
+
|
119
|
+
expects_create_folder stack_name, "script"
|
120
|
+
expects_create_file "#{stack_name}/script/dotfiles_installation.sh.erb"
|
121
|
+
expects_create_file "#{stack_name}/script/github_credentials_setup.sh.erb"
|
122
|
+
expects_create_file "#{stack_name}/script/nginx_and_passenger.sh.erb"
|
123
|
+
expects_create_file "#{stack_name}/script/redis_installation.sh.erb"
|
124
|
+
expects_create_file "#{stack_name}/script/resque_installation.sh.erb"
|
125
|
+
expects_create_file "#{stack_name}/script/ruby_environment.sh.erb"
|
126
|
+
expects_create_file "#{stack_name}/script/stackfu.sh.erb"
|
127
|
+
end
|
128
|
+
|
129
|
+
def expects_create_file(file_name)
|
130
|
+
DumpCommand.any_instance.expects(:write_file).with(file_name, load(file_name))
|
131
|
+
end
|
132
|
+
|
133
|
+
def expects_create_yaml_file(file_name)
|
134
|
+
DumpCommand.any_instance.expects(:write_file).with do |name, attrs|
|
135
|
+
ok = name == file_name
|
136
|
+
ok = ok && YAML::load(load(file_name)) == YAML::load(attrs)
|
137
|
+
|
138
|
+
# unless ok
|
139
|
+
# d "Expected attrs: #{YAML::load(load(file_name)).inspect}"
|
140
|
+
# d " Got attrs: #{YAML::load(attrs).inspect}"
|
141
|
+
# end
|
142
|
+
|
143
|
+
ok
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def expects_create_folder(stack_name, dir_name="")
|
148
|
+
dir_name = "/#{dir_name}" if dir_name.present?
|
149
|
+
DumpCommand.any_instance.expects(:mkdir).with("#{stack_name}#{dir_name}")
|
150
|
+
end
|
151
|
+
|
152
|
+
def load(file)
|
153
|
+
File.open(File.join(File.dirname(__FILE__), "../../fixtures/stack", file)).read
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper.rb'
|
2
|
+
|
3
|
+
class TestGenerateCommand < Test::Unit::TestCase
|
4
|
+
context "empty command" do
|
5
|
+
should "present the options" do
|
6
|
+
command "generate"
|
7
|
+
stdout.should =~ /You have to tell what you want to generate/
|
8
|
+
stdout.should =~ /stack/
|
9
|
+
stdout.should =~ /plugin/
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
%w(stack plugin).each do |what|
|
14
|
+
context "command generate #{what}" do
|
15
|
+
## Normal behavior
|
16
|
+
|
17
|
+
should "show the requirement parameter if none given" do
|
18
|
+
command "generate #{what}"
|
19
|
+
stdout.should =~ /#{what.upcase}_NAME/
|
20
|
+
end
|
21
|
+
|
22
|
+
should "generate the #{what} file and the script folder even when no script is given" do
|
23
|
+
expect_create :dir => "test", :file => "#{what}.yml"
|
24
|
+
expect_create :dir => "test/script"
|
25
|
+
expect_create :dir => "test/config", :file => "01-controls.yml"
|
26
|
+
expect_create :dir => "test/config", :file => "02-requirements.yml"
|
27
|
+
expect_create :dir => "test/config", :file => "03-scripts.yml"
|
28
|
+
expect_create :dir => "test/config", :file => "04-validations.yml"
|
29
|
+
|
30
|
+
command "generate #{what} test"
|
31
|
+
stdout.should =~ /#{what.titleize} test created successfully/
|
32
|
+
end
|
33
|
+
|
34
|
+
should "generate proper tree with one scripts passed" do
|
35
|
+
expect_create :dir => "other", :file => "#{what}.yml"
|
36
|
+
expect_create :dir => "other/script", :file => "install_counter_strike_server.sh.erb"
|
37
|
+
expect_create :dir => "other/config", :file => "01-controls.yml"
|
38
|
+
expect_create :dir => "other/config", :file => "02-requirements.yml"
|
39
|
+
expect_create :dir => "other/config", :file => "03-scripts.yml",
|
40
|
+
:contents => [/install_counter_strike_server/, /Install Counter Strike Server/]
|
41
|
+
expect_create :dir => "other/config", :file => "04-validations.yml"
|
42
|
+
|
43
|
+
command "generate #{what} other install_counter_strike_server:script"
|
44
|
+
stdout.should =~ /#{what.titleize} other created successfully/
|
45
|
+
end
|
46
|
+
|
47
|
+
should "generate proper tree with scripts and controls" do
|
48
|
+
expect_create :dir => "test", :file => "#{what}.yml"
|
49
|
+
expect_create :dir => "test/script", :file => "install_counter_strike_server.sh.erb"
|
50
|
+
expect_create :dir => "test/script", :file => "show_me_the_money.sh.erb"
|
51
|
+
expect_create :dir => "test/config", :file => "01-controls.yml",
|
52
|
+
:contents => [
|
53
|
+
/name: clan_name/, /label: Clan Name/, /type: Textbox/,
|
54
|
+
/name: clan_password/, /label: Clan Password/, /type: Password/
|
55
|
+
]
|
56
|
+
expect_create :dir => "test/config", :file => "02-requirements.yml"
|
57
|
+
expect_create :dir => "test/config", :file => "03-scripts.yml",
|
58
|
+
:contents => [
|
59
|
+
/install_counter_strike_server/, /Install Counter Strike Server/,
|
60
|
+
/show_me_the_money/, /Show Me The Money/
|
61
|
+
]
|
62
|
+
expect_create :dir => "test/config", :file => "04-validations.yml"
|
63
|
+
|
64
|
+
command "generate #{what} test clan_name:textbox clan_password:password install_counter_strike_server:script show_me_the_money:script"
|
65
|
+
end
|
66
|
+
|
67
|
+
## Error conditions
|
68
|
+
|
69
|
+
should "raise an error message if one of the params is unknown" do
|
70
|
+
command "generate #{what} test abcdef"
|
71
|
+
stdout.should =~ /Don't know how to generate a #{what} with abcdef. Use 'stackfu help generate' for more information./
|
72
|
+
end
|
73
|
+
|
74
|
+
should "raise an error message if one of the params is of invalid type" do
|
75
|
+
command "generate #{what} test yogurt:food"
|
76
|
+
stdout.should =~ /Don't know how to generate a #{what} with food yogurt. Use 'stackfu help generate' for more information./
|
77
|
+
end
|
78
|
+
|
79
|
+
should "raise a nice error when mkdir fails" do
|
80
|
+
expect_create :dir => "test", :file => "#{what}.yml", :raise => [IOError, "Error description"]
|
81
|
+
command "generate #{what} test"
|
82
|
+
stdout.should =~ /There was an error creating your #{what}: Error description/
|
83
|
+
end
|
84
|
+
|
85
|
+
should "raise a nice error when mkdir fails because there is a file with same name" do
|
86
|
+
expect_create :dir => "test", :file => "#{what}.yml", :raise => [Errno::EEXIST, "Error description"]
|
87
|
+
command "generate #{what} test"
|
88
|
+
stdout.should =~ /There was an error creating your #{what}: File exists - Error description/
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def expect_create(opts={})
|
95
|
+
expect = GenerateCommand.any_instance.expects(:create).with do |dir, file, contents|
|
96
|
+
dir_match = opts[:dir] ? dir == opts[:dir] : true
|
97
|
+
file_match = opts[:file] ? file == opts[:file] : true
|
98
|
+
contents_match = opts[:contents] ?
|
99
|
+
opts[:contents].each do |c|
|
100
|
+
break true if contents =~ c
|
101
|
+
false
|
102
|
+
end : true
|
103
|
+
block_match = block_given? ? yield(dir, file, contents) : true
|
104
|
+
|
105
|
+
its_a_match = dir_match and file_match and contents_match and block_match
|
106
|
+
end
|
107
|
+
|
108
|
+
if opts[:raise]
|
109
|
+
expect.raises(opts[:raise].first, opts[:raise].last)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper.rb'
|
2
|
+
|
3
|
+
class TestHelpCommand < Test::Unit::TestCase
|
4
|
+
context "creating" do
|
5
|
+
should "show default help message if no subcommand was given" do
|
6
|
+
stackfu = "stackfu".foreground(:green).bright
|
7
|
+
|
8
|
+
cmd = HelpCommand.new([])
|
9
|
+
cmd.expects(:puts).with "#{"StackFu #{StackFu::VERSION}".foreground(:green).bright}, a server deployment manager."
|
10
|
+
cmd.expects(:puts).with " (c) 2009-2020 StackFu - http://stackfu.com"
|
11
|
+
cmd.expects(:puts).with ""
|
12
|
+
cmd.expects(:puts).with " Usage:"
|
13
|
+
cmd.expects(:puts).with " #{stackfu} #{"command".foreground(:cyan)} [arguments...] [options...]"
|
14
|
+
cmd.expects(:puts).with ""
|
15
|
+
cmd.expects(:puts).with " Examples:"
|
16
|
+
cmd.expects(:puts).with " #{stackfu} #{"generate".foreground(:cyan)} stack lamp"
|
17
|
+
cmd.expects(:puts).with " #{stackfu} #{"pub".foreground(:cyan)}"
|
18
|
+
cmd.expects(:puts).with " #{stackfu} #{"deploy".foreground(:cyan)} lamp server1"
|
19
|
+
cmd.expects(:puts).with ""
|
20
|
+
cmd.expects(:puts).with " Commands:"
|
21
|
+
cmd.expects(:puts).with " #{"help".foreground(:cyan)} you already know about this one, dontcha?"
|
22
|
+
cmd.expects(:puts).with " #{"config".foreground(:cyan)} configure StackFu CLI options"
|
23
|
+
cmd.expects(:puts).with " #{"server".foreground(:cyan)} create, delete, update and deploy to StackFu servers"
|
24
|
+
cmd.expects(:puts).with " #{"generate".foreground(:cyan)} [stack|plugin] creates a new stack or plugin in current_dir/name"
|
25
|
+
cmd.expects(:puts).with " #{"publish".foreground(:cyan)} publishes the item on the current folder to StackFu.com"
|
26
|
+
cmd.expects(:puts).with ""
|
27
|
+
cmd.expects(:puts).with " For a complete guide on using StackFu from command line:"
|
28
|
+
cmd.expects(:puts).with " #{"http://stackfu.com/guides/stackfu-cli".underline}"
|
29
|
+
|
30
|
+
cmd.run
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper.rb'
|
2
|
+
|
3
|
+
class TestListCommand < Test::Unit::TestCase
|
4
|
+
should "map 'list' to ServerCommand" do
|
5
|
+
Command.create("list").class.should == ListCommand
|
6
|
+
end
|
7
|
+
|
8
|
+
should "tell the user if no stack found" do
|
9
|
+
with_users
|
10
|
+
with_stacks("empty")
|
11
|
+
with_plugins("empty")
|
12
|
+
command "list"
|
13
|
+
stdout.should =~ /You have nothing to list yet. To generate stacks or plugins, try the 'stackfu generate' command/
|
14
|
+
end
|
15
|
+
|
16
|
+
should "list 1 stack" do
|
17
|
+
with_users
|
18
|
+
with_stacks
|
19
|
+
with_plugins("empty")
|
20
|
+
command "list"
|
21
|
+
stdout.should =~ /Listing 1 stack/
|
22
|
+
stdout.should =~ /Type/
|
23
|
+
stdout.should =~ /Name/
|
24
|
+
stdout.should =~ /my_stack/
|
25
|
+
end
|
26
|
+
|
27
|
+
should "list 1 plugin" do
|
28
|
+
with_users
|
29
|
+
with_stacks("empty")
|
30
|
+
with_plugins
|
31
|
+
command "list"
|
32
|
+
stdout.should =~ /Listing 1 plugin/
|
33
|
+
stdout.should =~ /Type/
|
34
|
+
stdout.should =~ /plugin/
|
35
|
+
stdout.should =~ /Name/
|
36
|
+
stdout.should =~ /my_plugin/
|
37
|
+
end
|
38
|
+
|
39
|
+
should "list 1 plugin and 2 stacks" do
|
40
|
+
with_users
|
41
|
+
with_stacks("multiple")
|
42
|
+
with_plugins
|
43
|
+
command "list --plain"
|
44
|
+
stdout.should =~ /Listing 2 stacks and 1 plugin/
|
45
|
+
stdout.should =~ /Type/
|
46
|
+
stdout.should =~ /plugin/
|
47
|
+
stdout.should =~ /Name/
|
48
|
+
stdout.should =~ /my_plugin plugin/
|
49
|
+
stdout.should =~ /my_stack/
|
50
|
+
end
|
51
|
+
|
52
|
+
should "list 2 stacks" do
|
53
|
+
with_users
|
54
|
+
with_stacks("multiple")
|
55
|
+
with_plugins("empty")
|
56
|
+
command "list"
|
57
|
+
stdout.should =~ /Listing 2 stacks/
|
58
|
+
stdout.should =~ /Type/
|
59
|
+
stdout.should =~ /Name/
|
60
|
+
stdout.should =~ /my_stack/
|
61
|
+
stdout.should =~ /another_stack/
|
62
|
+
end
|
63
|
+
end
|