stackfu 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/CHANGELOG +24 -0
  2. data/Manifest +118 -0
  3. data/README +0 -0
  4. data/README.md +218 -0
  5. data/Rakefile +73 -0
  6. data/bin/stackfu +10 -0
  7. data/lib/stackfu/api_hooks.rb +17 -0
  8. data/lib/stackfu/app.rb +69 -0
  9. data/lib/stackfu/commands/command.rb +127 -0
  10. data/lib/stackfu/commands/config_command.rb +43 -0
  11. data/lib/stackfu/commands/deploy_command.rb +144 -0
  12. data/lib/stackfu/commands/dump_command.rb +101 -0
  13. data/lib/stackfu/commands/generate_command.rb +107 -0
  14. data/lib/stackfu/commands/help_command.rb +28 -0
  15. data/lib/stackfu/commands/list_command.rb +26 -0
  16. data/lib/stackfu/commands/publish_command.rb +108 -0
  17. data/lib/stackfu/commands/server_command.rb +124 -0
  18. data/lib/stackfu/helpers/providers_credentials.rb +82 -0
  19. data/lib/stackfu/helpers/rendering.rb +201 -0
  20. data/lib/stackfu/operating_systems.rb +30 -0
  21. data/lib/stackfu.rb +88 -0
  22. data/stackfu-installer/config/01-controls.yml +17 -0
  23. data/stackfu-installer/config/02-requirements.yml +3 -0
  24. data/stackfu-installer/config/03-scripts.yml +16 -0
  25. data/stackfu-installer/config/04-validations.yml +3 -0
  26. data/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
  27. data/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
  28. data/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
  29. data/stackfu-installer/script/redis_installation.sh.erb +33 -0
  30. data/stackfu-installer/script/resque_installation.sh.erb +7 -0
  31. data/stackfu-installer/script/ruby_environment.sh.erb +20 -0
  32. data/stackfu-installer/script/stackfu.sh.erb +114 -0
  33. data/stackfu-installer/stack.yml +5 -0
  34. data/stackfu.gemspec +60 -0
  35. data/templates/01-controls.yml.erb +31 -0
  36. data/templates/02-requirements.yml.erb +26 -0
  37. data/templates/03-scripts.yml.erb +34 -0
  38. data/templates/04-validations.yml.erb +17 -0
  39. data/templates/script.sh.erb +7 -0
  40. data/templates/stack.yml.erb +17 -0
  41. data/test/fixtures/add_server_error +7 -0
  42. data/test/fixtures/deployment_add +7 -0
  43. data/test/fixtures/deployment_add_error +8 -0
  44. data/test/fixtures/deployments +7 -0
  45. data/test/fixtures/logs +7 -0
  46. data/test/fixtures/logs_partial +7 -0
  47. data/test/fixtures/plugin_add +6 -0
  48. data/test/fixtures/plugin_add_error +8 -0
  49. data/test/fixtures/plugin_deployment_add +7 -0
  50. data/test/fixtures/plugin_not_found +7 -0
  51. data/test/fixtures/plugin_unauthorized +8 -0
  52. data/test/fixtures/plugins +7 -0
  53. data/test/fixtures/plugins_by_name +7 -0
  54. data/test/fixtures/plugins_by_name_other +7 -0
  55. data/test/fixtures/plugins_empty +7 -0
  56. data/test/fixtures/plugins_multiple +7 -0
  57. data/test/fixtures/providers +7 -0
  58. data/test/fixtures/providers_servers +7 -0
  59. data/test/fixtures/server_add +6 -0
  60. data/test/fixtures/server_add_dupe +7 -0
  61. data/test/fixtures/server_add_error +7 -0
  62. data/test/fixtures/server_delete +7 -0
  63. data/test/fixtures/server_delete_error +7 -0
  64. data/test/fixtures/servers +7 -0
  65. data/test/fixtures/servers_by_name +7 -0
  66. data/test/fixtures/servers_empty +8 -0
  67. data/test/fixtures/servers_not_found +26 -0
  68. data/test/fixtures/servers_unauthorized +8 -0
  69. data/test/fixtures/servers_webbynode +7 -0
  70. data/test/fixtures/stack/stackfu-installer/config/01-controls.yml +22 -0
  71. data/test/fixtures/stack/stackfu-installer/config/02-requirements.yml +1 -0
  72. data/test/fixtures/stack/stackfu-installer/config/03-scripts.yml +23 -0
  73. data/test/fixtures/stack/stackfu-installer/config/04-validations.yml +1 -0
  74. data/test/fixtures/stack/stackfu-installer/script/dotfiles_installation.sh.erb +22 -0
  75. data/test/fixtures/stack/stackfu-installer/script/github_credentials_setup.sh.erb +31 -0
  76. data/test/fixtures/stack/stackfu-installer/script/nginx_and_passenger.sh.erb +83 -0
  77. data/test/fixtures/stack/stackfu-installer/script/redis_installation.sh.erb +33 -0
  78. data/test/fixtures/stack/stackfu-installer/script/resque_installation.sh.erb +7 -0
  79. data/test/fixtures/stack/stackfu-installer/script/ruby_environment.sh.erb +20 -0
  80. data/test/fixtures/stack/stackfu-installer/script/stackfu.sh.erb +76 -0
  81. data/test/fixtures/stack/stackfu-installer/stack.yml +5 -0
  82. data/test/fixtures/stack_add +6 -0
  83. data/test/fixtures/stack_add_error +8 -0
  84. data/test/fixtures/stack_add_error_dupe +8 -0
  85. data/test/fixtures/stack_adds_by_name +7 -0
  86. data/test/fixtures/stack_delete_not_found +7 -0
  87. data/test/fixtures/stacks +7 -0
  88. data/test/fixtures/stacks_by_name +7 -0
  89. data/test/fixtures/stacks_by_name_other +7 -0
  90. data/test/fixtures/stacks_empty +7 -0
  91. data/test/fixtures/stacks_multiple +7 -0
  92. data/test/fixtures/stacks_not_found +7 -0
  93. data/test/fixtures/stacks_realworld +7 -0
  94. data/test/fixtures/stacks_stackfu-installer +7 -0
  95. data/test/fixtures/stacks_unauthorized +8 -0
  96. data/test/fixtures/stacks_with_controls +0 -0
  97. data/test/fixtures/users +7 -0
  98. data/test/fixtures/users_no_credentials +7 -0
  99. data/test/fixtures/users_update +6 -0
  100. data/test/stack.yml +26 -0
  101. data/test/support/custom_matchers.rb +69 -0
  102. data/test/support/fixtures.rb +98 -0
  103. data/test/support/io_stub.rb +10 -0
  104. data/test/support/web_fixtures.rb +91 -0
  105. data/test/test_helper.rb +186 -0
  106. data/test/unit/commands/test_command.rb +112 -0
  107. data/test/unit/commands/test_config_command.rb +92 -0
  108. data/test/unit/commands/test_deploy_command.rb +303 -0
  109. data/test/unit/commands/test_dump_command.rb +155 -0
  110. data/test/unit/commands/test_generate_command.rb +112 -0
  111. data/test/unit/commands/test_help_command.rb +33 -0
  112. data/test/unit/commands/test_list_command.rb +63 -0
  113. data/test/unit/commands/test_publish_command.rb +265 -0
  114. data/test/unit/commands/test_server_command.rb +259 -0
  115. data/test/unit/helpers/test_rendering.rb +141 -0
  116. data/test/unit/test_array.rb +26 -0
  117. data/test/unit/test_provider.rb +14 -0
  118. data/test/unit/test_stackfu.rb +27 -0
  119. 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