stackfu 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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