trucker-cli 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (294) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +1277 -0
  3. data/Rakefile +13 -0
  4. data/bin/truck +18 -0
  5. data/lib/admin/README.md +30 -0
  6. data/lib/admin/curl.rb +59 -0
  7. data/lib/admin/guid.rb +89 -0
  8. data/lib/admin/plugin.rb +8 -0
  9. data/lib/admin/service_auth_token.rb +93 -0
  10. data/lib/admin/service_broker/add.rb +54 -0
  11. data/lib/admin/service_broker/remove.rb +33 -0
  12. data/lib/admin/service_broker/service_brokers.rb +29 -0
  13. data/lib/admin/service_broker/update.rb +60 -0
  14. data/lib/admin/set_quota.rb +44 -0
  15. data/lib/cf.rb +14 -0
  16. data/lib/cf/cli.rb +495 -0
  17. data/lib/cf/cli/app/app.rb +43 -0
  18. data/lib/cf/cli/app/apps.rb +87 -0
  19. data/lib/cf/cli/app/base.rb +72 -0
  20. data/lib/cf/cli/app/delete.rb +95 -0
  21. data/lib/cf/cli/app/deprecated.rb +11 -0
  22. data/lib/cf/cli/app/env.rb +99 -0
  23. data/lib/cf/cli/app/events.rb +45 -0
  24. data/lib/cf/cli/app/files.rb +137 -0
  25. data/lib/cf/cli/app/health.rb +26 -0
  26. data/lib/cf/cli/app/instances.rb +53 -0
  27. data/lib/cf/cli/app/logs.rb +76 -0
  28. data/lib/cf/cli/app/push.rb +104 -0
  29. data/lib/cf/cli/app/push/create.rb +108 -0
  30. data/lib/cf/cli/app/push/interactions.rb +90 -0
  31. data/lib/cf/cli/app/push/sync.rb +57 -0
  32. data/lib/cf/cli/app/rename.rb +35 -0
  33. data/lib/cf/cli/app/restart.rb +31 -0
  34. data/lib/cf/cli/app/scale.rb +63 -0
  35. data/lib/cf/cli/app/start.rb +175 -0
  36. data/lib/cf/cli/app/stats.rb +66 -0
  37. data/lib/cf/cli/app/stop.rb +27 -0
  38. data/lib/cf/cli/domain/base.rb +9 -0
  39. data/lib/cf/cli/domain/domains.rb +40 -0
  40. data/lib/cf/cli/domain/map.rb +55 -0
  41. data/lib/cf/cli/domain/unmap.rb +56 -0
  42. data/lib/cf/cli/help.rb +15 -0
  43. data/lib/cf/cli/interactive.rb +104 -0
  44. data/lib/cf/cli/login_requirements.rb +13 -0
  45. data/lib/cf/cli/organization/base.rb +12 -0
  46. data/lib/cf/cli/organization/create.rb +36 -0
  47. data/lib/cf/cli/organization/delete.rb +61 -0
  48. data/lib/cf/cli/organization/org.rb +45 -0
  49. data/lib/cf/cli/organization/orgs.rb +30 -0
  50. data/lib/cf/cli/organization/rename.rb +36 -0
  51. data/lib/cf/cli/populators/base.rb +16 -0
  52. data/lib/cf/cli/populators/organization.rb +32 -0
  53. data/lib/cf/cli/populators/populator_methods.rb +64 -0
  54. data/lib/cf/cli/populators/space.rb +33 -0
  55. data/lib/cf/cli/populators/target.rb +14 -0
  56. data/lib/cf/cli/route/base.rb +9 -0
  57. data/lib/cf/cli/route/delete.rb +28 -0
  58. data/lib/cf/cli/route/map.rb +68 -0
  59. data/lib/cf/cli/route/routes.rb +26 -0
  60. data/lib/cf/cli/route/unmap.rb +56 -0
  61. data/lib/cf/cli/service/base.rb +9 -0
  62. data/lib/cf/cli/service/bind.rb +43 -0
  63. data/lib/cf/cli/service/create.rb +158 -0
  64. data/lib/cf/cli/service/delete.rb +82 -0
  65. data/lib/cf/cli/service/rename.rb +35 -0
  66. data/lib/cf/cli/service/service.rb +40 -0
  67. data/lib/cf/cli/service/service_helper.rb +25 -0
  68. data/lib/cf/cli/service/service_instance_helper.rb +100 -0
  69. data/lib/cf/cli/service/services.rb +110 -0
  70. data/lib/cf/cli/service/unbind.rb +36 -0
  71. data/lib/cf/cli/space/base.rb +27 -0
  72. data/lib/cf/cli/space/create.rb +66 -0
  73. data/lib/cf/cli/space/delete.rb +55 -0
  74. data/lib/cf/cli/space/rename.rb +38 -0
  75. data/lib/cf/cli/space/space.rb +66 -0
  76. data/lib/cf/cli/space/spaces.rb +57 -0
  77. data/lib/cf/cli/space/switch.rb +18 -0
  78. data/lib/cf/cli/start/base.rb +35 -0
  79. data/lib/cf/cli/start/colors.rb +13 -0
  80. data/lib/cf/cli/start/login.rb +104 -0
  81. data/lib/cf/cli/start/logout.rb +17 -0
  82. data/lib/cf/cli/start/target.rb +50 -0
  83. data/lib/cf/cli/start/target_prettifier.rb +35 -0
  84. data/lib/cf/cli/start/targets.rb +16 -0
  85. data/lib/cf/cli/user/base.rb +29 -0
  86. data/lib/cf/cli/user/create.rb +51 -0
  87. data/lib/cf/cli/user/passwd.rb +36 -0
  88. data/lib/cf/cli/user/register.rb +42 -0
  89. data/lib/cf/cli/user/users.rb +32 -0
  90. data/lib/cf/constants.rb +10 -0
  91. data/lib/cf/errors.rb +19 -0
  92. data/lib/cf/plugin.rb +56 -0
  93. data/lib/cf/spacing.rb +89 -0
  94. data/lib/cf/spec_helper.rb +1 -0
  95. data/lib/cf/test_support.rb +6 -0
  96. data/lib/cf/version.rb +3 -0
  97. data/lib/console/README.md +16 -0
  98. data/lib/console/console.rb +187 -0
  99. data/lib/console/plugin.rb +32 -0
  100. data/lib/manifests/errors.rb +35 -0
  101. data/lib/manifests/loader.rb +31 -0
  102. data/lib/manifests/loader/builder.rb +39 -0
  103. data/lib/manifests/loader/normalizer.rb +145 -0
  104. data/lib/manifests/loader/resolver.rb +79 -0
  105. data/lib/manifests/manifests.rb +343 -0
  106. data/lib/manifests/plugin.rb +140 -0
  107. data/lib/micro/README.md +25 -0
  108. data/lib/micro/errors.rb +4 -0
  109. data/lib/micro/micro.rb +56 -0
  110. data/lib/micro/plugin.rb +197 -0
  111. data/lib/micro/switcher/base.rb +79 -0
  112. data/lib/micro/switcher/darwin.rb +21 -0
  113. data/lib/micro/switcher/dummy.rb +15 -0
  114. data/lib/micro/switcher/linux.rb +16 -0
  115. data/lib/micro/switcher/windows.rb +31 -0
  116. data/lib/micro/vmrun.rb +175 -0
  117. data/lib/tasks/gem_release.rake +56 -0
  118. data/lib/tasks/windows_build.rake +14 -0
  119. data/lib/tunnel/README.md +29 -0
  120. data/lib/tunnel/config/clients.yml +17 -0
  121. data/lib/tunnel/helper-app/Gemfile +10 -0
  122. data/lib/tunnel/helper-app/Gemfile.lock +48 -0
  123. data/lib/tunnel/helper-app/server.rb +43 -0
  124. data/lib/tunnel/plugin.rb +183 -0
  125. data/lib/tunnel/tunnel.rb +295 -0
  126. data/spec/admin/curl_spec.rb +52 -0
  127. data/spec/admin/guid_spec.rb +85 -0
  128. data/spec/admin/service_broker/add_spec.rb +64 -0
  129. data/spec/admin/service_broker/remove_spec.rb +46 -0
  130. data/spec/admin/service_broker/service_brokers_spec.rb +34 -0
  131. data/spec/admin/service_broker/update_spec.rb +51 -0
  132. data/spec/admin/set_quota_spec.rb +89 -0
  133. data/spec/assets/env/Gemfile +4 -0
  134. data/spec/assets/env/Gemfile.lock +20 -0
  135. data/spec/assets/env/env_test.rb +58 -0
  136. data/spec/assets/hello-sinatra/Gemfile +3 -0
  137. data/spec/assets/hello-sinatra/Gemfile.lock +17 -0
  138. data/spec/assets/hello-sinatra/config.ru +3 -0
  139. data/spec/assets/hello-sinatra/fat-cat-makes-app-larger.png +0 -0
  140. data/spec/assets/hello-sinatra/main.rb +8 -0
  141. data/spec/assets/rails328_ruby187_app/Gemfile +39 -0
  142. data/spec/assets/rails328_ruby187_app/README.rdoc +261 -0
  143. data/spec/assets/rails328_ruby187_app/Rakefile +7 -0
  144. data/spec/assets/rails328_ruby187_app/app/assets/images/rails.png +0 -0
  145. data/spec/assets/rails328_ruby187_app/app/assets/javascripts/application.js +15 -0
  146. data/spec/assets/rails328_ruby187_app/app/assets/stylesheets/application.css +13 -0
  147. data/spec/assets/rails328_ruby187_app/app/controllers/application_controller.rb +3 -0
  148. data/spec/assets/rails328_ruby187_app/app/helpers/application_helper.rb +2 -0
  149. data/spec/assets/rails328_ruby187_app/app/views/layouts/application.html.erb +14 -0
  150. data/spec/assets/rails328_ruby187_app/config.ru +4 -0
  151. data/spec/assets/rails328_ruby187_app/config/application.rb +62 -0
  152. data/spec/assets/rails328_ruby187_app/config/boot.rb +6 -0
  153. data/spec/assets/rails328_ruby187_app/config/database.yml +25 -0
  154. data/spec/assets/rails328_ruby187_app/config/environment.rb +5 -0
  155. data/spec/assets/rails328_ruby187_app/config/environments/development.rb +37 -0
  156. data/spec/assets/rails328_ruby187_app/config/environments/production.rb +67 -0
  157. data/spec/assets/rails328_ruby187_app/config/environments/test.rb +37 -0
  158. data/spec/assets/rails328_ruby187_app/config/initializers/backtrace_silencers.rb +7 -0
  159. data/spec/assets/rails328_ruby187_app/config/initializers/inflections.rb +15 -0
  160. data/spec/assets/rails328_ruby187_app/config/initializers/mime_types.rb +5 -0
  161. data/spec/assets/rails328_ruby187_app/config/initializers/secret_token.rb +7 -0
  162. data/spec/assets/rails328_ruby187_app/config/initializers/session_store.rb +8 -0
  163. data/spec/assets/rails328_ruby187_app/config/initializers/wrap_parameters.rb +14 -0
  164. data/spec/assets/rails328_ruby187_app/config/locales/en.yml +5 -0
  165. data/spec/assets/rails328_ruby187_app/config/routes.rb +58 -0
  166. data/spec/assets/rails328_ruby187_app/db/seeds.rb +7 -0
  167. data/spec/assets/rails328_ruby187_app/doc/README_FOR_APP +2 -0
  168. data/spec/assets/rails328_ruby187_app/manifest.yml +7 -0
  169. data/spec/assets/rails328_ruby187_app/public/404.html +26 -0
  170. data/spec/assets/rails328_ruby187_app/public/422.html +26 -0
  171. data/spec/assets/rails328_ruby187_app/public/500.html +25 -0
  172. data/spec/assets/rails328_ruby187_app/public/assets/application-7270767b2a9e9fff880aa5de378ca791.css +0 -0
  173. data/spec/assets/rails328_ruby187_app/public/assets/application-7270767b2a9e9fff880aa5de378ca791.css.gz +0 -0
  174. data/spec/assets/rails328_ruby187_app/public/assets/application-ccab98dc1abdf097c0af693e20aed861.js +17 -0
  175. data/spec/assets/rails328_ruby187_app/public/assets/application-ccab98dc1abdf097c0af693e20aed861.js.gz +0 -0
  176. data/spec/assets/rails328_ruby187_app/public/assets/application.css +0 -0
  177. data/spec/assets/rails328_ruby187_app/public/assets/application.css.gz +0 -0
  178. data/spec/assets/rails328_ruby187_app/public/assets/application.js +17 -0
  179. data/spec/assets/rails328_ruby187_app/public/assets/application.js.gz +0 -0
  180. data/spec/assets/rails328_ruby187_app/public/assets/manifest.yml +4 -0
  181. data/spec/assets/rails328_ruby187_app/public/assets/rails-be8732dac73d845ac5b142c8fb5f9fb0.png +0 -0
  182. data/spec/assets/rails328_ruby187_app/public/assets/rails.png +0 -0
  183. data/spec/assets/rails328_ruby187_app/public/favicon.ico +0 -0
  184. data/spec/assets/rails328_ruby187_app/public/index.html +241 -0
  185. data/spec/assets/rails328_ruby187_app/public/robots.txt +5 -0
  186. data/spec/assets/rails328_ruby187_app/script/rails +6 -0
  187. data/spec/assets/rails328_ruby187_app/test/performance/browsing_test.rb +12 -0
  188. data/spec/assets/rails328_ruby187_app/test/test_helper.rb +13 -0
  189. data/spec/cf/cli/app/base_spec.rb +17 -0
  190. data/spec/cf/cli/app/delete_spec.rb +197 -0
  191. data/spec/cf/cli/app/env_spec.rb +261 -0
  192. data/spec/cf/cli/app/events_spec.rb +72 -0
  193. data/spec/cf/cli/app/help_spec.rb +39 -0
  194. data/spec/cf/cli/app/instances_spec.rb +69 -0
  195. data/spec/cf/cli/app/push/create_spec.rb +444 -0
  196. data/spec/cf/cli/app/push/interactions_spec.rb +32 -0
  197. data/spec/cf/cli/app/push_spec.rb +332 -0
  198. data/spec/cf/cli/app/rename_spec.rb +108 -0
  199. data/spec/cf/cli/app/restart_spec.rb +47 -0
  200. data/spec/cf/cli/app/scale_spec.rb +63 -0
  201. data/spec/cf/cli/app/start_spec.rb +255 -0
  202. data/spec/cf/cli/app/stats_spec.rb +66 -0
  203. data/spec/cf/cli/domain/help_spec.rb +39 -0
  204. data/spec/cf/cli/domain/map_spec.rb +140 -0
  205. data/spec/cf/cli/domain/unmap_spec.rb +77 -0
  206. data/spec/cf/cli/help_spec.rb +21 -0
  207. data/spec/cf/cli/organization/create_spec.rb +121 -0
  208. data/spec/cf/cli/organization/delete_spec.rb +105 -0
  209. data/spec/cf/cli/organization/help_spec.rb +39 -0
  210. data/spec/cf/cli/organization/orgs_spec.rb +116 -0
  211. data/spec/cf/cli/organization/rename_spec.rb +116 -0
  212. data/spec/cf/cli/populators/organization_spec.rb +179 -0
  213. data/spec/cf/cli/populators/space_spec.rb +156 -0
  214. data/spec/cf/cli/populators/target_spec.rb +39 -0
  215. data/spec/cf/cli/route/delete_spec.rb +92 -0
  216. data/spec/cf/cli/route/help_spec.rb +32 -0
  217. data/spec/cf/cli/route/map_spec.rb +148 -0
  218. data/spec/cf/cli/route/unmap_spec.rb +114 -0
  219. data/spec/cf/cli/service/bind_spec.rb +25 -0
  220. data/spec/cf/cli/service/create_spec.rb +147 -0
  221. data/spec/cf/cli/service/delete_spec.rb +22 -0
  222. data/spec/cf/cli/service/help_spec.rb +39 -0
  223. data/spec/cf/cli/service/rename_spec.rb +103 -0
  224. data/spec/cf/cli/service/service_helper_spec.rb +66 -0
  225. data/spec/cf/cli/service/service_instance_helper_spec.rb +155 -0
  226. data/spec/cf/cli/service/service_spec.rb +23 -0
  227. data/spec/cf/cli/service/services_spec.rb +156 -0
  228. data/spec/cf/cli/service/unbind_spec.rb +25 -0
  229. data/spec/cf/cli/space/base_spec.rb +49 -0
  230. data/spec/cf/cli/space/create_spec.rb +144 -0
  231. data/spec/cf/cli/space/delete_spec.rb +109 -0
  232. data/spec/cf/cli/space/help_spec.rb +39 -0
  233. data/spec/cf/cli/space/rename_spec.rb +110 -0
  234. data/spec/cf/cli/space/space_spec.rb +80 -0
  235. data/spec/cf/cli/space/spaces_spec.rb +107 -0
  236. data/spec/cf/cli/space/switch_space_spec.rb +57 -0
  237. data/spec/cf/cli/start/help_spec.rb +39 -0
  238. data/spec/cf/cli/start/login_spec.rb +142 -0
  239. data/spec/cf/cli/start/logout_spec.rb +49 -0
  240. data/spec/cf/cli/start/target_prettifier_spec.rb +78 -0
  241. data/spec/cf/cli/start/target_spec.rb +123 -0
  242. data/spec/cf/cli/user/create_spec.rb +98 -0
  243. data/spec/cf/cli/user/help_spec.rb +32 -0
  244. data/spec/cf/cli/user/passwd_spec.rb +94 -0
  245. data/spec/cf/cli/user/register_spec.rb +145 -0
  246. data/spec/cf/cli_spec.rb +474 -0
  247. data/spec/console/console_spec.rb +189 -0
  248. data/spec/factories/cfoundry/v2/apps_factory.rb +12 -0
  249. data/spec/factories/cfoundry/v2/clients_factory.rb +7 -0
  250. data/spec/factories/cfoundry/v2/domains_factory.rb +8 -0
  251. data/spec/factories/cfoundry/v2/managed_service_instances_factory.rb +13 -0
  252. data/spec/factories/cfoundry/v2/organizations_factory.rb +14 -0
  253. data/spec/factories/cfoundry/v2/quota_definitions.rb +13 -0
  254. data/spec/factories/cfoundry/v2/routes_factory.rb +8 -0
  255. data/spec/factories/cfoundry/v2/service_bindings_factory.rb +11 -0
  256. data/spec/factories/cfoundry/v2/service_brokers_factory.rb +11 -0
  257. data/spec/factories/cfoundry/v2/service_plans_factory.rb +17 -0
  258. data/spec/factories/cfoundry/v2/services_factory.rb +14 -0
  259. data/spec/factories/cfoundry/v2/spaces_factory.rb +13 -0
  260. data/spec/factories/cfoundry/v2/stacks_factory.rb +11 -0
  261. data/spec/factories/cfoundry/v2/user_provided_service_instances_factory.rb +12 -0
  262. data/spec/factories/cfoundry/v2/users_factory.rb +7 -0
  263. data/spec/features/backspace_spec.rb +46 -0
  264. data/spec/features/create_user_spec.rb +74 -0
  265. data/spec/features/delete_orphaned_service_spec.rb +64 -0
  266. data/spec/features/login_spec.rb +65 -0
  267. data/spec/features/manifests_spec.rb +86 -0
  268. data/spec/features/org_spec.rb +50 -0
  269. data/spec/features/push_flow_spec.rb +169 -0
  270. data/spec/features/service_brokers_spec.rb +173 -0
  271. data/spec/features/services_spec.rb +122 -0
  272. data/spec/features/space_spec.rb +107 -0
  273. data/spec/features/switching_targets_spec.rb +70 -0
  274. data/spec/manifests/errors_spec.rb +43 -0
  275. data/spec/manifests/loader/builder_spec.rb +80 -0
  276. data/spec/manifests/loader/normalizer_spec.rb +158 -0
  277. data/spec/manifests/manifests_spec.rb +335 -0
  278. data/spec/manifests/plugin_spec.rb +410 -0
  279. data/spec/micro/plugin_spec.rb +64 -0
  280. data/spec/spec_helper.rb +69 -0
  281. data/spec/support/cli_helper.rb +87 -0
  282. data/spec/support/config_helper.rb +15 -0
  283. data/spec/support/factory_girl.rb +6 -0
  284. data/spec/support/fake_home_dir.rb +55 -0
  285. data/spec/support/features_helper.rb +99 -0
  286. data/spec/support/interact_helper.rb +27 -0
  287. data/spec/support/matchers.rb +16 -0
  288. data/spec/support/mock_commands/mock_restart.rb +16 -0
  289. data/spec/support/mock_commands/mock_start.rb +17 -0
  290. data/spec/support/shared_examples/errors.rb +40 -0
  291. data/spec/support/shared_examples/input.rb +14 -0
  292. data/spec/tunnel/plugin_spec.rb +31 -0
  293. data/spec/tunnel/tunnel_spec.rb +54 -0
  294. metadata +814 -0
@@ -0,0 +1,335 @@
1
+ require "spec_helper"
2
+
3
+ describe CFManifests do
4
+ let(:inputs_hash) { {} }
5
+ let(:given_hash) { {} }
6
+ let(:global_hash) { {} }
7
+ let(:inputs) { Mothership::Inputs.new(nil, nil, inputs_hash, given_hash, global_hash) }
8
+
9
+ let(:cmd) do
10
+ manifest = CF::App::Push.new(nil, inputs)
11
+ manifest.extend CFManifests
12
+ manifest.stub(:client) { client }
13
+ manifest
14
+ end
15
+
16
+ let(:target_base) { "some-cloud.com" }
17
+
18
+ let(:foo) { build(:app, :name => "foo") }
19
+ let(:bar) { build(:app, :name => "bar") }
20
+ let(:baz) { build(:app, :name => "baz") }
21
+ let(:xxx) { build(:app, :name => "xxx") }
22
+ let(:yyy) { build(:app, :name => "yyy") }
23
+
24
+ let(:client) do
25
+ build(:client).tap { |client| client.stub(:apps => [foo, bar, baz, xxx, yyy]) }
26
+ end
27
+
28
+ let(:manifest_file) { "/abc/manifest.yml" }
29
+
30
+ before do
31
+ cmd.stub(:manifest) { manifest }
32
+ cmd.stub(:manifest_file) { manifest_file }
33
+ end
34
+
35
+ describe "#resolve_symbol" do
36
+ it "resolves target-base for old manifest files" do
37
+ cmd.stub(:target_base) { 'the_really_great_target_base' }
38
+ cmd.resolve_symbol("target-base").should == 'the_really_great_target_base'
39
+ end
40
+ end
41
+
42
+ describe "#find_apps" do
43
+ subject { cmd.find_apps(nil) }
44
+
45
+ context "when there is no manifest file" do
46
+ before { cmd.stub(:manifest).and_return(nil) }
47
+ it { should eq [] }
48
+ end
49
+ end
50
+
51
+ describe "#create_manifest_for" do
52
+ let(:app) do
53
+ build :app,
54
+ :memory => 2048,
55
+ :total_instances => 2,
56
+ :command => "ruby main.rb",
57
+ :buildpack => "git://example.com/foo.git",
58
+ :routes => [
59
+ build(:route,
60
+ :host => "some-app-name",
61
+ :domain => build(:domain, :name => target_base))
62
+ ],
63
+ :service_bindings => [
64
+ build(
65
+ :service_binding,
66
+ :service_instance =>
67
+ build(
68
+ :managed_service_instance,
69
+ :name => "service-1",
70
+ :service_plan =>
71
+ build(
72
+ :service_plan,
73
+ :name => "P200",
74
+ :service => build(:service,
75
+ label: "managed",
76
+ provider: "hamazon",
77
+ version: "v3"
78
+ )
79
+ )
80
+ )
81
+ ),
82
+ build(
83
+ :service_binding,
84
+ :service_instance =>
85
+ build(
86
+ :user_provided_service_instance,
87
+ :name => "service-2",
88
+ :credentials => { uri: "mysql://example.com" }
89
+ )
90
+ )
91
+ ]
92
+ end
93
+
94
+ subject { cmd.create_manifest_for(app, "some-path") }
95
+
96
+ its(["name"]) { should eq app.name }
97
+ its(["memory"]) { should eq "2G" }
98
+ its(["instances"]) { should eq 2 }
99
+ its(["path"]) { should eq "some-path" }
100
+ its(["host"]) { should eq "some-app-name" }
101
+ its(["domain"]) { should eq app.domain }
102
+ its(["command"]) { should eq "ruby main.rb" }
103
+ its(["buildpack"]) { should eq "git://example.com/foo.git" }
104
+
105
+ it "contains the service information" do
106
+ expect(subject["services"]).to eq(
107
+ "service-1" => {
108
+ "plan" => "P200",
109
+ "label" => "managed",
110
+ "provider" => "hamazon",
111
+ "version" => "v3",
112
+ },
113
+ "service-2" => {
114
+ "credentials" => {"uri" => "mysql://example.com"},
115
+ "label" => "user-provided"
116
+ },
117
+ )
118
+ end
119
+
120
+ context "with only minimum configuration" do
121
+ let(:app) {
122
+ build :app,
123
+ :memory => 2048,
124
+ :total_instances => 2,
125
+ :routes => [],
126
+ :service_bindings => []
127
+ }
128
+
129
+ its(["host"]) { should eq "none" }
130
+ its(["domain"]) { should eq "none" }
131
+ it { should_not include "command" }
132
+ it { should_not include "services" }
133
+ end
134
+ end
135
+
136
+ describe "#setup_services" do
137
+ let(:service_bindings) { [] }
138
+ let(:app) { build :app, :service_bindings => service_bindings }
139
+
140
+ before do
141
+ dont_allow_ask(anything, anything)
142
+ end
143
+
144
+ context "when user-provided services are defined in the manifest" do
145
+ let(:client) do
146
+ build(:client).tap { |client| client.stub(:services => [], :service_instances => []) }
147
+ end
148
+
149
+ let(:info) { {:services => {'moracle' => {:label => "user-provided", :credentials =>{"k" => "v"}}}}}
150
+
151
+ it "creates the service with label user-provided" do
152
+ cmd.should_receive(:invoke).with(:create_service,
153
+ :name => 'moracle', :offering => has_label("user-provided"), :app => app, :credentials => {"k" => "v"}
154
+ )
155
+ cmd.send("setup_services", app, info)
156
+ end
157
+ end
158
+
159
+ context "when services are defined in the manifest" do
160
+ let(:info) do
161
+ {:services => {"service-1" => {:label => "mysql", :plan => "100"}}}
162
+ end
163
+
164
+ let(:service_1) { build(:managed_service_instance, :name => "service-1") }
165
+ let(:plan_100) { build :service_plan, :name => "100" }
166
+
167
+ let(:mysql) do
168
+ build(
169
+ :service,
170
+ :label => "mysql",
171
+ :provider => "core",
172
+ :service_plans => [plan_100])
173
+ end
174
+
175
+ let(:service_instances) { [] }
176
+
177
+ let(:client) do
178
+ build(:client).tap { |client| client.stub(:services => [mysql], :service_instances => service_instances) }
179
+ end
180
+
181
+ context "and the services exist" do
182
+ let(:service_instances) { [service_1] }
183
+
184
+ context "and are already bound" do
185
+ let(:service_bindings) { [build(:service_binding, :service_instance => service_1)] }
186
+
187
+ it "does neither create nor bind the service again" do
188
+ cmd.should_not_receive(:invoke).with(:create_service, anything)
189
+ cmd.should_not_receive(:invoke).with(:bind_service, anything)
190
+ cmd.send(:setup_services, app, info)
191
+ end
192
+ end
193
+
194
+ context "but are not bound" do
195
+ it "does not create the services" do
196
+ cmd.should_not_receive(:invoke).with(:create_service, anything)
197
+ cmd.stub(:invoke).with(:bind_service, anything)
198
+ cmd.send(:setup_services, app, info)
199
+ end
200
+
201
+ it "binds the service" do
202
+ cmd.should_receive(:invoke).with(:bind_service, :app => app, :service => service_1)
203
+ cmd.send(:setup_services, app, info)
204
+ end
205
+ end
206
+ end
207
+
208
+ context "and the services do not exist" do
209
+ it "creates the services" do
210
+ cmd.should_receive(:invoke).with(:create_service, :app => app,
211
+ :name => service_1.name, :offering => mysql, :plan => plan_100)
212
+ cmd.should_not_receive(:invoke).with(:bind_service, anything)
213
+ cmd.send(:setup_services, app, info)
214
+ end
215
+ end
216
+ end
217
+
218
+ context "when there are no services defined" do
219
+ let(:info) { {} }
220
+
221
+ it "does not ask anything" do
222
+ cmd.send(:setup_services, app, info)
223
+ end
224
+ end
225
+ end
226
+
227
+ describe "#apps_in_manifest" do
228
+ let(:foo_hash) { {:name => "foo", :path => "/abc/foo"} }
229
+ let(:bar_hash) { {:name => "bar", :path => "/abc/bar"} }
230
+ let(:baz_hash) { {:name => "baz", :path => "/abc/baz"} }
231
+
232
+ let(:manifest) { {:applications => [foo_hash, bar_hash, baz_hash]} }
233
+
234
+ subject { cmd.apps_in_manifest(inputs) }
235
+
236
+ context "when no apps are passed" do
237
+ let(:given_hash) { {} }
238
+
239
+ its(:first) { should eq [] }
240
+ its(:last) { should eq [] }
241
+ end
242
+
243
+ context "when app names are passed" do
244
+ context "and all of them are in the manifest" do
245
+ let(:given_hash) { {:apps => ["foo", "bar"]} }
246
+
247
+ its(:first) { should eq [foo_hash, bar_hash] }
248
+ its(:last) { should eq [] }
249
+ end
250
+
251
+ context "and one of them is in the manifest" do
252
+ let(:given_hash) { {:apps => ["foo", "xxx"]} }
253
+
254
+ its(:first) { should eq [foo_hash] }
255
+ its(:last) { should eq ["xxx"] }
256
+ end
257
+
258
+ context "and none of them are in the manifest" do
259
+ let(:given_hash) { {:apps => ["xxx", "yyy"]} }
260
+
261
+ its(:first) { should eq [] }
262
+ its(:last) { should eq ["xxx", "yyy"] }
263
+ end
264
+ end
265
+
266
+ context "when apps are passed as paths" do
267
+ context "and the paths are in the manifest" do
268
+ let(:given_hash) { {:apps => ["/abc/foo"]} }
269
+
270
+ its(:first) { should eq [foo_hash] }
271
+ its(:last) { should eq [] }
272
+ end
273
+
274
+ context "and any path is not in the manifest" do
275
+ let(:given_hash) { {:apps => ["/abc/xxx"]} }
276
+
277
+ it "fails with a manifest-specific method (i.e. path not in manifest)" do
278
+ expect { subject }.to raise_error(CF::UserError, /Path .+ is not present in manifest/)
279
+ end
280
+ end
281
+ end
282
+ end
283
+
284
+ describe "#all_apps" do
285
+ let(:applications) do
286
+ [
287
+ {:name => "foo", :path => "/abc"},
288
+ {:name => "bar", :path => "/abc"},
289
+ {:name => "baz", :path => "/abc/baz"}
290
+ ]
291
+ end
292
+
293
+ let(:manifest) do
294
+ {:applications => applications}
295
+ end
296
+
297
+ subject { cmd.all_apps }
298
+
299
+ it "returns all of the apps described in the manifest, as hashes" do
300
+ expect(subject).to eq applications
301
+ end
302
+ end
303
+
304
+ describe "#current_apps" do
305
+ let(:manifest) do
306
+ {:applications => [
307
+ {:name => "foo", :path => "/abc"},
308
+ {:name => "bar", :path => "/abc"},
309
+ {:name => "baz", :path => "/abc/baz"}
310
+ ]}
311
+ end
312
+
313
+ subject { cmd.current_apps }
314
+
315
+ it "returns the applications with the cwd as their path" do
316
+ Dir.stub(:pwd) { "/abc" }
317
+ expect(subject).to eq [{:name => "foo", :path => "/abc"}, {:name => "bar", :path => "/abc"}]
318
+ end
319
+ end
320
+
321
+ describe "#check_manifest!" do
322
+
323
+ it "prints a warning if there is some unknown attribute" do
324
+ wrong_manifest_hash = {:applications => [{:bad_attr => 'boom'}]}
325
+ output = double('output')
326
+
327
+ msg = "\033[31mWarning: bad_attr is not a valid manifest attribute. "+
328
+ "Please remove this attribute from your manifest to get rid of this"+
329
+ " warning\033[0m"
330
+
331
+ output.should_receive(:puts).with(msg)
332
+ cmd.check_manifest!(wrong_manifest_hash, output)
333
+ end
334
+ end
335
+ end
@@ -0,0 +1,410 @@
1
+ require "spec_helper"
2
+
3
+ describe ManifestsPlugin do
4
+ let(:manifest) { {} }
5
+ let(:manifest_file) { nil }
6
+ let(:inputs_hash) { {} }
7
+ let(:given_hash) { {} }
8
+ let(:global_hash) { { :quiet => true } }
9
+ let(:command) { nil }
10
+ let(:inputs) { Mothership::Inputs.new(Mothership.commands[:push], nil, inputs_hash, given_hash, global_hash) }
11
+ let(:plugin) { ManifestsPlugin.new(command, inputs) }
12
+
13
+ let(:client) { build(:client) }
14
+
15
+ before do
16
+ plugin.stub(:manifest) { manifest }
17
+ plugin.stub(:manifest_file) { manifest_file } if manifest_file
18
+ plugin.stub(:client) { client }
19
+ end
20
+
21
+ describe ".use_manifest_for_app_input" do
22
+ it "makes the app argument optional and wraps it in an around that gets the app from the manifest" do
23
+ command = described_class.commands[:app]
24
+ command.instance_variable_set(:@arguments, [{:name => :app, :type => :required, :value => nil}])
25
+
26
+ expect(command.arguments).to eq [{:name => :app, :type => :required, :value => nil}]
27
+ expect(command.around.size).to eq 1
28
+
29
+ described_class.default_to_app_from_manifest :app, false
30
+
31
+ expect(command.arguments).to eq [{:name => :app, :type => :optional, :value => nil}]
32
+ expect(command.around.size).to eq 2
33
+ end
34
+ end
35
+
36
+ describe "#wrap_with_optional_name" do
37
+ let(:name_made_optional) { true }
38
+ let(:fail_without_app) { true }
39
+ let(:wrapped) { double(:wrapped).as_null_object }
40
+
41
+ subject { plugin.send(:wrap_with_optional_name, name_made_optional, wrapped, inputs, fail_without_app) }
42
+
43
+ context "when --all is given" do
44
+ let(:inputs_hash) { { :all => true } }
45
+
46
+ it "skips all manifest-related logic, and invokes the command" do
47
+ wrapped.should_receive(:call)
48
+ plugin.should_not_receive(:show_manifest_usage)
49
+ subject
50
+ end
51
+ end
52
+
53
+ context "when there is no manifest" do
54
+ let(:manifest) { nil }
55
+
56
+ context "and an app is given" do
57
+ let(:given_hash) { { :app => "foo" } }
58
+
59
+ it "passes through to the command" do
60
+ wrapped.should_receive(:call)
61
+ plugin.should_not_receive(:show_manifest_usage)
62
+ subject
63
+ end
64
+ end
65
+
66
+ context "and an app is NOT given" do
67
+ let(:inputs_hash) { {} }
68
+
69
+ context "and we made it optional" do
70
+ it "fails manually" do
71
+ plugin.should_receive(:no_apps)
72
+ subject
73
+ end
74
+
75
+ context "when it is not supposed to fail" do
76
+ let(:fail_without_app) { false }
77
+ it "doesnt fail" do
78
+ plugin.should_not_receive(:no_apps)
79
+ subject
80
+ end
81
+ end
82
+ end
83
+
84
+ context "and we did NOT make it optional" do
85
+ let(:name_made_optional) { false }
86
+
87
+ it "passes through to the command" do
88
+ wrapped.should_receive(:call)
89
+ plugin.should_not_receive(:show_manifest_usage)
90
+ subject
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ context "when there is a manifest" do
97
+ let(:manifest_file) { "/abc/manifest.yml" }
98
+
99
+ before do
100
+ plugin.stub(:show_manifest_usage)
101
+ end
102
+
103
+ context "when no apps are given" do
104
+ context "and the user's working directory matches a particular app in the manifest" do
105
+ let(:manifest) { { :applications => [{ :name => "foo", :path => "/abc/foo" }] } }
106
+
107
+ it "calls the command for only that app" do
108
+ wrapped.should_receive(:call).with(anything) do |inputs|
109
+ expect(inputs.given[:app]).to eq "foo"
110
+ end
111
+
112
+ Dir.stub(:pwd) { "/abc/foo" }
113
+
114
+ subject
115
+ end
116
+ end
117
+
118
+ context "and the user's working directory isn't in the manifest" do
119
+ let(:manifest) { { :applications => [{ :name => "foo" }, { :name => "bar" }] } }
120
+
121
+ it "calls the command for all apps in the manifest" do
122
+ uncalled_apps = ["foo", "bar"]
123
+ wrapped.should_receive(:call).with(anything).twice do |inputs|
124
+ uncalled_apps.delete inputs.given[:app]
125
+ end
126
+
127
+ subject
128
+
129
+ expect(uncalled_apps).to be_empty
130
+ end
131
+ end
132
+ end
133
+
134
+ context "when any of the given apps are not in the manifest" do
135
+ let(:manifest) { { :applications => [{ :name => "a" }, { :name => "b" }] } }
136
+
137
+ context "and --apps is given" do
138
+ let(:given_hash) { { :apps => ["x", "a"] } }
139
+
140
+ it "passes through to the original command" do
141
+ plugin.should_receive(:show_manifest_usage)
142
+
143
+ uncalled_apps = ["a", "x"]
144
+ wrapped.should_receive(:call).with(anything).twice do |inputs|
145
+ uncalled_apps.delete inputs.given[:app]
146
+ end
147
+
148
+ subject
149
+
150
+ expect(uncalled_apps).to be_empty
151
+ subject
152
+ end
153
+ end
154
+ end
155
+
156
+ context "when none of the given apps are in the manifest" do
157
+ let(:manifest) { { :applications => [{ :name => "a" }, { :name => "b" }] } }
158
+
159
+ context "and --apps is given" do
160
+ let(:given_hash) { { :apps => ["x", "y"] } }
161
+
162
+ it "passes through to the original command" do
163
+ wrapped.should_receive(:call)
164
+ plugin.should_not_receive(:show_manifest_usage)
165
+ subject
166
+ end
167
+ end
168
+ end
169
+
170
+ context "when an app name that's in the manifest is given" do
171
+ let(:manifest) { { :applications => [{ :name => "foo" }] } }
172
+ let(:given_hash) { { :app => "foo" } }
173
+
174
+ it "calls the command with that app" do
175
+ wrapped.should_receive(:call).with(anything) do |inputs|
176
+ expect(inputs.given[:app]).to eq "foo"
177
+ end
178
+
179
+ subject
180
+ end
181
+ end
182
+
183
+ context "when a path to an app that's in the manifest is given" do
184
+ let(:manifest) { { :applications => [{ :name => "foo", :path => "/abc/foo" }] } }
185
+ let(:given_hash) { { :app => "/abc/foo" } }
186
+
187
+ it "calls the command with that app" do
188
+ wrapped.should_receive(:call).with(anything) do |inputs|
189
+ expect(inputs.given[:app]).to eq "foo"
190
+ end
191
+
192
+ subject
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ describe "#wrap_push" do
199
+ let(:wrapped) { double(:wrapped).as_null_object }
200
+ let(:command) { Mothership.commands[:push] }
201
+
202
+ subject { plugin.send(:wrap_push, wrapped, inputs) }
203
+
204
+ before do
205
+ plugin.stub(:show_manifest_usage)
206
+ end
207
+
208
+ context "with a manifest" do
209
+ let(:manifest_file) { "/abc/manifest.yml" }
210
+
211
+ let(:manifest) do
212
+ { :applications => [
213
+ { :name => "a",
214
+ :path => "/abc/a",
215
+ :instances => "200",
216
+ :memory => "128M"
217
+ }
218
+ ]
219
+ }
220
+ end
221
+
222
+ # cf push foo
223
+ context "and a name is given" do
224
+ context "and the name is present in the manifest" do
225
+ let(:given_hash) { { :name => "a" } }
226
+ let(:app) { build :app, :name => "a" }
227
+
228
+ before do
229
+ client.stub(:apps => [app])
230
+ client.stub(:app_by_name).with("a").and_return(app)
231
+ end
232
+
233
+ context "and the app exists" do
234
+
235
+ context "and --reset was given" do
236
+ let(:inputs_hash) { { :reset => true } }
237
+ let(:given_hash) { { :name => "a", :instances => "100" } }
238
+
239
+ it "rebases their inputs on the manifest's values" do
240
+ wrapped.should_receive(:call).with(anything) do |inputs|
241
+ expect(inputs.given).to eq(
242
+ :name => "a", :path => "/abc/a", :instances => "100", :memory => "128M")
243
+ end
244
+
245
+ subject
246
+ end
247
+ end
248
+ end
249
+
250
+ context "and the app does NOT exist" do
251
+ let(:app) { nil }
252
+
253
+ it "pushes a new app with the inputs from the manifest" do
254
+ wrapped.should_receive(:call).with(anything) do |inputs|
255
+ expect(inputs.given).to eq(
256
+ :name => "a", :path => "/abc/a", :instances => "200", :memory => "128M")
257
+ end
258
+
259
+ subject
260
+ end
261
+ end
262
+ end
263
+
264
+ context "and the name is NOT present in the manifest" do
265
+ let(:given_hash) { { :name => "x" } }
266
+
267
+ it "fails, saying that name was not found in the manifest" do
268
+ expect { subject }.to raise_error(CF::UserError, /Could not find .+ in the manifest./)
269
+ end
270
+ end
271
+ end
272
+
273
+ # cf push ./abc
274
+ context "and a path is given" do
275
+ context "and there are apps matching that path in the manifest" do
276
+ before do
277
+ client.stub(:apps => [build(:app), build(:app)])
278
+ client.stub(:app_by_name)
279
+ end
280
+
281
+ let(:manifest) do
282
+ { :applications => [
283
+ { :name => "a",
284
+ :path => "/abc/a",
285
+ :instances => "200",
286
+ :memory => "128M"
287
+ },
288
+ { :name => "b",
289
+ :path => "/abc/a",
290
+ :instances => "200",
291
+ :memory => "128M"
292
+ }
293
+ ]
294
+ }
295
+ end
296
+
297
+ let(:given_hash) { { :name => "/abc/a" } }
298
+
299
+ it "pushes the found apps" do
300
+ pushed_apps = []
301
+ wrapped.should_receive(:call).with(anything).twice do |inputs|
302
+ pushed_apps << inputs[:name]
303
+ end
304
+
305
+ subject
306
+
307
+ expect(pushed_apps).to eq(["a", "b"])
308
+ end
309
+ end
310
+
311
+ context "and there are NOT apps matching that path in the manifest" do
312
+ let(:given_hash) { { :name => "/abc/x" } }
313
+
314
+ it "fails, saying that the path was not found in the manifest" do
315
+ expect { subject }.to raise_error(CF::UserError, /Path .+ is not present in manifest/)
316
+ end
317
+ end
318
+ end
319
+
320
+ context "and --path is specified too" do
321
+ let(:given_hash) { { :path => "/somewhere/else" } }
322
+
323
+ it "warns the user that --path will be ignored" do
324
+ plugin.stub(:line)
325
+ plugin.stub(:push_with_manifest)
326
+
327
+ subject
328
+
329
+ expect(plugin).to have_received(:line).with("--path is ignored when using a manifest. Please specify the path in the manifest.")
330
+ end
331
+ end
332
+ end
333
+
334
+ context "without a manifest" do
335
+ let(:app) { double(:app).as_null_object }
336
+ let(:manifest) { nil }
337
+
338
+ it "asks to save the manifest when uploading the application" do
339
+ should_ask("Save configuration?", :default => false)
340
+ wrapped.stub(:call) { plugin.filter(:push_app, app) }
341
+ subject
342
+ end
343
+ end
344
+ end
345
+
346
+ describe "#push_input_for" do
347
+ context "with an existing app" do
348
+ before do
349
+ plugin.stub(:from_manifest) { "PATH" }
350
+ app.changes.clear
351
+ client.stub(:apps => [app])
352
+ end
353
+
354
+ let(:manifest_memory) { "256M" }
355
+ let(:app) { build(:app, :name => "a", :memory => 256) }
356
+ let(:manifest) { { :name => "a", :memory => manifest_memory } }
357
+
358
+ subject { plugin.send(:push_input_for, manifest, inputs) }
359
+
360
+ context "with --reset" do
361
+ let(:inputs_hash) { { :reset => true } }
362
+
363
+ context "with changes" do
364
+ let(:manifest_memory) { "128M" }
365
+
366
+ it "applies the changes" do
367
+ subject[:memory].should == "128M"
368
+ end
369
+
370
+ it "does not ask to set --reset" do
371
+ plugin.should_not_receive(:warn_reset_changes)
372
+ subject
373
+ end
374
+ end
375
+
376
+ context "without changes" do
377
+ it "does not ask to set --reset" do
378
+ plugin.should_not_receive(:warn_reset_changes)
379
+ subject
380
+ end
381
+ end
382
+ end
383
+
384
+ context "without --reset" do
385
+ let(:inputs_hash) { {} }
386
+
387
+ context "with changes" do
388
+ let(:manifest_memory) { "128M" }
389
+
390
+ it "asks user to provide --reset" do
391
+ plugin.should_receive(:warn_reset_changes)
392
+ subject
393
+ end
394
+
395
+ it "does not apply changes" do
396
+ plugin.stub(:warn_reset_changes)
397
+ subject[:memory].should == nil
398
+ end
399
+ end
400
+
401
+ context "without changes" do
402
+ it "does not ask to set --reset" do
403
+ plugin.should_not_receive(:warn_reset_changes)
404
+ subject
405
+ end
406
+ end
407
+ end
408
+ end
409
+ end
410
+ end