Skip to content
Browse files

Merge branch 'master' into echo_service

Change-Id: Iac7b2cd57c79a52013763357aa79b931f3213c96
  • Loading branch information...
2 parents 72c05ae + 3137297 commit 57ffef124f7df456e0e318beb5005130a7a1ca56 @bluesalt bluesalt committed
Showing with 4,101 additions and 815 deletions.
  1. +20 −4 README
  2. +12 −11 Rakefile
  3. +4 −4 atmos/Gemfile
  4. +64 −40 atmos/Gemfile.lock
  5. +3 −3 atmos/Rakefile
  6. BIN atmos/vendor/cache/addressable-2.2.7.gem
  7. BIN atmos/vendor/cache/addressable-2.2.8.gem
  8. BIN atmos/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  9. BIN atmos/vendor/cache/fastercsv-1.5.4.gem
  10. BIN atmos/vendor/cache/fastercsv-1.5.5.gem
  11. BIN atmos/vendor/cache/json_pure-1.7.0.gem
  12. BIN atmos/vendor/cache/json_pure-1.7.3.gem
  13. BIN atmos/vendor/cache/macaddr-1.5.0.gem
  14. BIN atmos/vendor/cache/macaddr-1.6.1.gem
  15. BIN atmos/vendor/cache/nats-0.4.22.gem
  16. BIN atmos/vendor/cache/nats-0.4.24.gem
  17. BIN atmos/vendor/cache/resque-status-0.3.2.gem
  18. BIN atmos/vendor/cache/resque-status-0.3.3.gem
  19. BIN memcached/vendor/cache/systemu-2.5.0.gem → atmos/vendor/cache/systemu-2.5.1.gem
  20. BIN atmos/vendor/cache/vcap_common-1.0.11.gem
  21. BIN atmos/vendor/cache/vcap_logging-1.0.0.gem
  22. BIN atmos/vendor/cache/vcap_services_base-0.1.10.gem
  23. +8 −8 base/Gemfile.lock
  24. +1 −0 base/lib/base/asynchronous_service_gateway.rb
  25. +12 −1 base/lib/base/job/lock.rb
  26. +35 −5 base/lib/base/job/serialization.rb
  27. +2 −1 base/lib/base/job/snapshot.rb
  28. +43 −13 base/lib/base/node.rb
  29. +2 −1 base/lib/base/node_bin.rb
  30. +9 −3 base/lib/base/provisioner.rb
  31. +5 −1 base/lib/base/service_error.rb
  32. +1 −1 base/lib/base/version.rb
  33. +2 −2 base/spec/Rakefile
  34. 0 base/spec/{ → function_test}/async_gw_spec.rb
  35. 0 base/spec/{ → function_test}/backup_spec.rb
  36. 0 base/spec/{ → function_test}/base_spec.rb
  37. 0 base/spec/{ → function_test}/job_spec.rb
  38. +34 −0 base/spec/{ → function_test}/node_spec.rb
  39. 0 base/spec/{ → function_test}/provision_spec.rb
  40. +7 −0 base/spec/helper/node_spec_helper.rb
  41. +12 −0 base/spec/helper/provision_spec_helper.rb
  42. +305 −0 base/spec/unit_test/async_gw_spec.rb
  43. +42 −0 base/spec/unit_test/backup_spec.rb
  44. +17 −0 base/spec/unit_test/base_spec.rb
  45. +118 −0 base/spec/unit_test/job_spec.rb
  46. +794 −0 base/spec/unit_test/node_spec.rb
  47. +1,202 −0 base/spec/unit_test/provision_spec.rb
  48. +1 −1 base/vcap_services_base.gemspec
  49. +4 −4 filesystem/Gemfile
  50. +64 −40 filesystem/Gemfile.lock
  51. +3 −3 filesystem/Rakefile
  52. +16 −3 filesystem/bin/filesystem_gateway
  53. +1 −0 filesystem/config/filesystem_gateway.yml
  54. +7 −45 filesystem/lib/filesystem_service/{provisioner.rb → base_provisioner.rb}
  55. +52 −0 filesystem/lib/filesystem_service/local_provisioner.rb
  56. +53 −0 filesystem/lib/filesystem_service/nfs_provisioner.rb
  57. +75 −7 filesystem/spec/provisioner_spec.rb
  58. BIN filesystem/vendor/cache/addressable-2.2.7.gem
  59. BIN filesystem/vendor/cache/addressable-2.2.8.gem
  60. BIN filesystem/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  61. BIN filesystem/vendor/cache/fastercsv-1.5.4.gem
  62. BIN filesystem/vendor/cache/fastercsv-1.5.5.gem
  63. BIN filesystem/vendor/cache/json_pure-1.7.0.gem
  64. BIN filesystem/vendor/cache/json_pure-1.7.3.gem
  65. BIN filesystem/vendor/cache/macaddr-1.5.0.gem
  66. BIN filesystem/vendor/cache/macaddr-1.6.1.gem
  67. BIN filesystem/vendor/cache/nats-0.4.22.gem
  68. BIN filesystem/vendor/cache/nats-0.4.24.gem
  69. BIN filesystem/vendor/cache/resque-status-0.3.2.gem
  70. BIN filesystem/vendor/cache/resque-status-0.3.3.gem
  71. BIN mongodb/vendor/cache/systemu-2.5.0.gem → filesystem/vendor/cache/systemu-2.5.1.gem
  72. BIN filesystem/vendor/cache/vcap_common-1.0.11.gem
  73. BIN filesystem/vendor/cache/vcap_logging-1.0.0.gem
  74. BIN filesystem/vendor/cache/vcap_services_base-0.1.10.gem
  75. +5 −5 memcached/Gemfile
  76. +71 −47 memcached/Gemfile.lock
  77. +3 −3 memcached/Rakefile
  78. +3 −5 memcached/bin/memcached_gateway
  79. +4 −3 memcached/bin/memcached_node
  80. +4 −3 memcached/config/memcached_node.yml
  81. +1 −1 memcached/lib/memcached_service/common.rb
  82. +14 −9 memcached/lib/memcached_service/memcached_node.rb
  83. +25 −18 memcached/spec/Rakefile
  84. +49 −64 memcached/spec/node_spec.rb
  85. +64 −10 memcached/spec/spec_helper.rb
  86. BIN memcached/vendor/cache/dalli-2.0.3.gem
  87. BIN memcached/vendor/cache/dalli-2.0.5.gem
  88. BIN memcached/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  89. BIN memcached/vendor/cache/fastercsv-1.5.4.gem
  90. BIN memcached/vendor/cache/fastercsv-1.5.5.gem
  91. BIN memcached/vendor/cache/json_pure-1.7.0.gem
  92. BIN memcached/vendor/cache/json_pure-1.7.3.gem
  93. BIN memcached/vendor/cache/macaddr-1.5.0.gem
  94. BIN memcached/vendor/cache/macaddr-1.6.1.gem
  95. BIN memcached/vendor/cache/multi_json-1.3.4.gem
  96. BIN memcached/vendor/cache/multi_json-1.3.6.gem
  97. BIN memcached/vendor/cache/nats-0.4.22.gem
  98. BIN memcached/vendor/cache/nats-0.4.24.gem
  99. BIN memcached/vendor/cache/rake-0.8.7.gem
  100. BIN memcached/vendor/cache/rake-0.9.2.2.gem
  101. BIN memcached/vendor/cache/rspec-core-2.10.0.gem
  102. BIN memcached/vendor/cache/rspec-core-2.10.1.gem
  103. BIN memcached/vendor/cache/rspec-mocks-2.10.0.gem
  104. BIN memcached/vendor/cache/rspec-mocks-2.10.1.gem
  105. BIN memcached/vendor/cache/simplecov-0.6.2.gem
  106. BIN memcached/vendor/cache/simplecov-0.6.4.gem
  107. BIN filesystem/vendor/cache/systemu-2.5.0.gem → memcached/vendor/cache/systemu-2.5.1.gem
  108. BIN memcached/vendor/cache/vcap_common-1.0.11.gem
  109. BIN memcached/vendor/cache/vcap_logging-1.0.1.gem
  110. BIN memcached/vendor/cache/vcap_services_base-0.1.9.gem
  111. +4 −4 mongodb/Gemfile
  112. +61 −37 mongodb/Gemfile.lock
  113. +3 −3 mongodb/Rakefile
  114. +1 −0 mongodb/config/mongodb_node.yml
  115. +4 −0 mongodb/config/mongodb_worker.yml
  116. +6 −6 mongodb/lib/mongodb_service/mongodb_error.rb
  117. BIN mongodb/vendor/cache/addressable-2.2.7.gem
  118. BIN mongodb/vendor/cache/addressable-2.2.8.gem
  119. BIN mongodb/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  120. BIN mongodb/vendor/cache/fastercsv-1.5.4.gem
  121. BIN mongodb/vendor/cache/fastercsv-1.5.5.gem
  122. BIN mongodb/vendor/cache/json_pure-1.7.0.gem
  123. BIN mongodb/vendor/cache/json_pure-1.7.3.gem
  124. BIN mongodb/vendor/cache/macaddr-1.5.0.gem
  125. BIN mongodb/vendor/cache/macaddr-1.6.1.gem
  126. BIN mongodb/vendor/cache/resque-status-0.3.2.gem
  127. BIN mongodb/vendor/cache/resque-status-0.3.3.gem
  128. BIN atmos/vendor/cache/systemu-2.5.0.gem → mongodb/vendor/cache/systemu-2.5.1.gem
  129. BIN mongodb/vendor/cache/vcap_common-1.0.11.gem
  130. BIN mongodb/vendor/cache/vcap_logging-1.0.0.gem
  131. BIN mongodb/vendor/cache/vcap_services_base-0.1.10.gem
  132. +4 −4 mysql/Gemfile
  133. +61 −37 mysql/Gemfile.lock
  134. +3 −3 mysql/Rakefile
  135. +1 −0 mysql/config/mysql_node.yml
  136. +4 −0 mysql/config/mysql_worker.yml
  137. +3 −0 mysql/lib/mysql_service/node.rb
  138. +18 −2 mysql/spec/mysql_node_spec.rb
  139. BIN mysql/vendor/cache/addressable-2.2.7.gem
  140. BIN mysql/vendor/cache/addressable-2.2.8.gem
  141. BIN mysql/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  142. BIN mysql/vendor/cache/fastercsv-1.5.4.gem
  143. BIN mysql/vendor/cache/fastercsv-1.5.5.gem
  144. BIN mysql/vendor/cache/json_pure-1.7.0.gem
  145. BIN mysql/vendor/cache/json_pure-1.7.3.gem
  146. BIN mysql/vendor/cache/macaddr-1.5.0.gem
  147. BIN mysql/vendor/cache/macaddr-1.6.1.gem
  148. BIN mysql/vendor/cache/resque-status-0.3.2.gem
  149. BIN mysql/vendor/cache/resque-status-0.3.3.gem
  150. BIN mysql/vendor/cache/systemu-2.5.0.gem
  151. BIN mysql/vendor/cache/systemu-2.5.1.gem
  152. BIN mysql/vendor/cache/vcap_common-1.0.11.gem
  153. BIN mysql/vendor/cache/vcap_logging-1.0.0.gem
  154. BIN mysql/vendor/cache/vcap_services_base-0.1.10.gem
  155. +4 −4 neo4j/Gemfile
  156. +61 −37 neo4j/Gemfile.lock
  157. +3 −3 neo4j/Rakefile
  158. +1 −0 neo4j/config/neo4j_node.yml
  159. BIN neo4j/vendor/cache/addressable-2.2.7.gem
  160. BIN neo4j/vendor/cache/addressable-2.2.8.gem
  161. BIN neo4j/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  162. BIN neo4j/vendor/cache/fastercsv-1.5.4.gem
  163. BIN neo4j/vendor/cache/fastercsv-1.5.5.gem
  164. BIN neo4j/vendor/cache/json_pure-1.7.0.gem
  165. BIN neo4j/vendor/cache/json_pure-1.7.3.gem
  166. BIN neo4j/vendor/cache/macaddr-1.5.0.gem
  167. BIN neo4j/vendor/cache/macaddr-1.6.1.gem
  168. BIN neo4j/vendor/cache/resque-status-0.3.2.gem
  169. BIN neo4j/vendor/cache/resque-status-0.3.3.gem
  170. BIN neo4j/vendor/cache/systemu-2.5.0.gem
  171. BIN neo4j/vendor/cache/systemu-2.5.1.gem
  172. BIN neo4j/vendor/cache/vcap_common-1.0.11.gem
  173. BIN neo4j/vendor/cache/vcap_logging-1.0.0.gem
  174. BIN neo4j/vendor/cache/vcap_services_base-0.1.10.gem
  175. +4 −4 postgresql/Gemfile
  176. +61 −37 postgresql/Gemfile.lock
  177. +3 −3 postgresql/Rakefile
  178. +1 −0 postgresql/config/postgresql_node.yml
  179. +4 −0 postgresql/config/postgresql_worker.yml
  180. +39 −5 postgresql/lib/postgresql_service/node.rb
  181. +6 −6 postgresql/lib/postgresql_service/postgresql_error.rb
  182. +31 −1 postgresql/lib/postgresql_service/storage_quota.rb
  183. +105 −39 postgresql/spec/postgresql_node_spec.rb
  184. BIN postgresql/vendor/cache/addressable-2.2.7.gem
  185. BIN postgresql/vendor/cache/addressable-2.2.8.gem
  186. BIN postgresql/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  187. BIN postgresql/vendor/cache/fastercsv-1.5.4.gem
  188. BIN postgresql/vendor/cache/fastercsv-1.5.5.gem
  189. BIN postgresql/vendor/cache/json_pure-1.7.0.gem
  190. BIN postgresql/vendor/cache/json_pure-1.7.3.gem
  191. BIN postgresql/vendor/cache/macaddr-1.5.0.gem
  192. BIN postgresql/vendor/cache/macaddr-1.6.1.gem
  193. BIN postgresql/vendor/cache/resque-status-0.3.2.gem
  194. BIN postgresql/vendor/cache/resque-status-0.3.3.gem
  195. BIN postgresql/vendor/cache/systemu-2.5.0.gem
  196. BIN postgresql/vendor/cache/systemu-2.5.1.gem
  197. BIN postgresql/vendor/cache/vcap_common-1.0.11.gem
  198. BIN postgresql/vendor/cache/vcap_logging-1.0.0.gem
  199. BIN postgresql/vendor/cache/vcap_services_base-0.1.10.gem
  200. +4 −4 rabbit/Gemfile
  201. +61 −37 rabbit/Gemfile.lock
  202. +3 −3 rabbit/Rakefile
  203. +1 −0 rabbit/config/rabbit_node.yml
  204. +0 −5 rabbit/lib/rabbit_service/rabbit_node.rb
  205. BIN rabbit/vendor/cache/addressable-2.2.7.gem
  206. BIN rabbit/vendor/cache/addressable-2.2.8.gem
  207. BIN rabbit/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  208. BIN rabbit/vendor/cache/fastercsv-1.5.4.gem
  209. BIN rabbit/vendor/cache/fastercsv-1.5.5.gem
  210. BIN rabbit/vendor/cache/json_pure-1.7.0.gem
  211. BIN rabbit/vendor/cache/json_pure-1.7.3.gem
  212. BIN rabbit/vendor/cache/macaddr-1.5.0.gem
  213. BIN rabbit/vendor/cache/macaddr-1.6.1.gem
  214. BIN rabbit/vendor/cache/resque-status-0.3.2.gem
  215. BIN rabbit/vendor/cache/resque-status-0.3.3.gem
  216. BIN rabbit/vendor/cache/systemu-2.5.0.gem
  217. BIN rabbit/vendor/cache/systemu-2.5.1.gem
  218. BIN rabbit/vendor/cache/vcap_common-1.0.11.gem
  219. BIN rabbit/vendor/cache/vcap_logging-1.0.0.gem
  220. BIN rabbit/vendor/cache/vcap_services_base-0.1.10.gem
  221. +4 −4 redis/Gemfile
  222. +62 −38 redis/Gemfile.lock
  223. +3 −3 redis/Rakefile
  224. +1 −0 redis/config/redis_node.yml
  225. +4 −0 redis/config/redis_worker.yml
  226. +3 −5 redis/lib/redis_service/redis_node.rb
  227. BIN redis/vendor/cache/addressable-2.2.7.gem
  228. BIN redis/vendor/cache/addressable-2.2.8.gem
  229. BIN redis/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  230. BIN redis/vendor/cache/fastercsv-1.5.4.gem
  231. BIN redis/vendor/cache/fastercsv-1.5.5.gem
  232. BIN redis/vendor/cache/json_pure-1.7.0.gem
  233. BIN redis/vendor/cache/json_pure-1.7.3.gem
  234. BIN redis/vendor/cache/macaddr-1.5.0.gem
  235. BIN redis/vendor/cache/macaddr-1.6.1.gem
  236. BIN redis/vendor/cache/nats-0.4.22.beta.8.gem
  237. BIN redis/vendor/cache/nats-0.4.22.gem
  238. BIN redis/vendor/cache/resque-status-0.3.2.gem
  239. BIN redis/vendor/cache/resque-status-0.3.3.gem
  240. BIN redis/vendor/cache/systemu-2.5.0.gem
  241. BIN redis/vendor/cache/systemu-2.5.1.gem
  242. BIN redis/vendor/cache/vcap_common-1.0.11.gem
  243. BIN redis/vendor/cache/vcap_logging-1.0.0.gem
  244. BIN redis/vendor/cache/vcap_services_base-0.1.10.gem
  245. +2 −2 serialization_data_server/Gemfile
  246. +23 −10 serialization_data_server/Gemfile.lock
  247. +3 −3 serialization_data_server/Rakefile
  248. BIN serialization_data_server/vendor/cache/rake-0.8.7.gem
  249. BIN serialization_data_server/vendor/cache/rake-0.9.2.2.gem
  250. BIN serialization_data_server/vendor/cache/vcap_common-1.0.8.gem
  251. BIN serialization_data_server/vendor/cache/vcap_logging-0.1.3.gem
  252. +4 −4 service_broker/Gemfile
  253. +61 −37 service_broker/Gemfile.lock
  254. +3 −3 service_broker/Rakefile
  255. +4 −0 service_broker/lib/service_broker/async_gateway.rb
  256. BIN service_broker/vendor/cache/addressable-2.2.7.gem
  257. BIN service_broker/vendor/cache/addressable-2.2.8.gem
  258. BIN service_broker/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  259. BIN service_broker/vendor/cache/fastercsv-1.5.4.gem
  260. BIN service_broker/vendor/cache/fastercsv-1.5.5.gem
  261. BIN service_broker/vendor/cache/json_pure-1.7.0.gem
  262. BIN service_broker/vendor/cache/json_pure-1.7.3.gem
  263. BIN service_broker/vendor/cache/macaddr-1.5.0.gem
  264. BIN service_broker/vendor/cache/macaddr-1.6.1.gem
  265. BIN service_broker/vendor/cache/resque-status-0.3.2.gem
  266. BIN service_broker/vendor/cache/resque-status-0.3.3.gem
  267. BIN service_broker/vendor/cache/systemu-2.5.0.gem
  268. BIN service_broker/vendor/cache/systemu-2.5.1.gem
  269. BIN service_broker/vendor/cache/vcap_common-1.0.11.gem
  270. BIN service_broker/vendor/cache/vcap_logging-1.0.0.gem
  271. BIN service_broker/vendor/cache/vcap_services_base-0.1.10.gem
  272. +4 −4 tools/backup/manager/Gemfile
  273. +63 −39 tools/backup/manager/Gemfile.lock
  274. +3 −3 tools/backup/manager/Rakefile
  275. +3 −0 tools/backup/manager/bin/backup_manager
  276. +4 −1 tools/backup/manager/bin/snapshot_manager
  277. +1 −0 tools/backup/manager/config/backup_manager.yml
  278. +1 −0 tools/backup/manager/config/snapshot_manager.yml
  279. +6 −6 tools/backup/manager/lib/backup_manager/snapshot_cleaner.rb
  280. BIN tools/backup/manager/vendor/cache/addressable-2.2.7.gem
  281. BIN tools/backup/manager/vendor/cache/addressable-2.2.8.gem
  282. BIN tools/backup/manager/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
  283. BIN tools/backup/manager/vendor/cache/fastercsv-1.5.4.gem
  284. BIN tools/backup/manager/vendor/cache/fastercsv-1.5.5.gem
  285. BIN tools/backup/manager/vendor/cache/json_pure-1.7.0.gem
  286. BIN tools/backup/manager/vendor/cache/json_pure-1.7.3.gem
  287. BIN tools/backup/manager/vendor/cache/macaddr-1.5.0.gem
  288. BIN tools/backup/manager/vendor/cache/macaddr-1.6.1.gem
  289. BIN tools/backup/manager/vendor/cache/multi_json-1.3.2.gem
  290. BIN tools/backup/manager/vendor/cache/multi_json-1.3.6.gem
  291. BIN tools/backup/manager/vendor/cache/redis-namespace-1.0.2.gem
  292. BIN tools/backup/manager/vendor/cache/redis-namespace-1.0.3.gem
  293. BIN tools/backup/manager/vendor/cache/resque-status-0.3.2.gem
  294. BIN tools/backup/manager/vendor/cache/resque-status-0.3.3.gem
  295. BIN tools/backup/manager/vendor/cache/systemu-2.5.0.gem
  296. BIN tools/backup/manager/vendor/cache/systemu-2.5.1.gem
  297. BIN tools/backup/manager/vendor/cache/vcap_common-1.0.11.gem
  298. BIN tools/backup/manager/vendor/cache/vcap_logging-1.0.0.gem
  299. BIN tools/backup/manager/vendor/cache/vcap_services_base-0.1.10.gem
  300. +1 −0 tools/misc/bin/nuke_service.rb
Sorry, we could not display the entire diff because too many files (320) changed.
View
24 README
@@ -1,7 +1,7 @@
Copyright (c) 2009-2011 VMware, Inc.
== What is Cloud Foundry?
-
+
Cloud Foundry is an open platform-as-a-service (PaaS). The system supports
multiple frameworks, multiple application infrastructure services and
deployment to multiple clouds.
@@ -10,13 +10,29 @@ deployment to multiple clouds.
The services repo contains a collection of sample cloud foundry services.
The repo has a position in the overall vcap namespace at
-vcap/services and uses the git submodule mechanism to be mounted in that location.
+vcap/services and uses the git submodule mechanism to be mounted in that location.
The code is exposed via the vcap-services repo.
-
+
== License
-
+
Cloud Foundry uses the Apache 2 license. See LICENSE for details.
== Installation Notes
Complete installation notes are present in the README for vcap
+
+== Unit Test Instructions
+
+To run the unit test of each service, go to the folder of the service, run
+
+bundle install --deployment --without development production
+
+, which will install the necessary gems for you, then do
+
+bundle exec rake spec
+
+to run the unit tests. Please note that you might need necessary binary files to
+pass the unit test. Normally these binaries are required to be installed in
+accordance to the path specified in the config file, i.e., the .yml file in
+the config directory. The nats information might also need to be updated to match
+the configuration of the nats server.
View
23 Rakefile
@@ -6,21 +6,22 @@ task "tests" do |t|
end
namespace "bundler" do
- desc "Update base gem"
- task "update_base" do
- system "cd base && rm -rf pkg && rake bundler:install"
+ def exec_in_svc_dir
SERVICES_DIR.each do |dir|
puts ">>>>>>>> enter #{dir}"
- system "rm -f #{dir}/vendor/cache/vcap_services_base-*.gem && cp base/pkg/vcap_services_base-*.gem #{dir}/vendor/cache && cd #{dir} && bundle install --local"
+ Dir.chdir(dir) do
+ yield dir
+ end
end
end
- desc "Update base gem and bump version using 'bundle update vcap_services_base'"
- task "update_base!" do
- system "cd base && rm -rf pkg && rake bundler:install"
- SERVICES_DIR.each do |dir|
- puts ">>>>>>>> enter #{dir}"
- system "rm -f #{dir}/vendor/cache/vcap_services_base-*.gem && cp base/pkg/vcap_services_base-*.gem #{dir}/vendor/cache && cd #{dir} && bundle update vcap_services_base && bundle install --local"
- end
+ desc "Update Gemfile"
+ task :update!, :oref, :nref do |t, args|
+ exec_in_svc_dir { |_| sh "sed -i \"s/#{args[:oref]}/#{args[:nref]}/g\" Gemfile && bundle install" }
+ end
+
+ desc "Dry run update Gemfile"
+ task :update, :oref, :nref do |t, args|
+ exec_in_svc_dir { |_| sh "sed \"s/#{args[:oref]}/#{args[:nref]}/g\" Gemfile" }
end
end
View
8 atmos/Gemfile
@@ -1,6 +1,6 @@
source :rubygems
-gem 'eventmachine'
+gem 'eventmachine', :git => 'git://github.com/cloudfoundry/eventmachine.git', :branch => 'release-0.12.11-cf'
gem "em-http-request"
gem "ruby-hmac"
gem "uuidtools"
@@ -11,9 +11,9 @@ gem "sinatra"
gem "thin"
gem "xml-simple"
-gem 'vcap_common', '>= 1.0.8', :require => ['vcap/common', 'vcap/component']
-gem 'vcap_logging', '>=0.1.3', :require => ['vcap/logging']
-gem 'vcap_services_base'
+gem 'vcap_common', :require => ['vcap/common', 'vcap/component'], :git => 'git://github.com/cloudfoundry/vcap-common.git', :ref => 'a7779114db'
+gem 'vcap_logging', :require => ['vcap/logging'], :git => 'git://github.com/cloudfoundry/common.git', :ref => 'b96ec1192'
+gem 'vcap_services_base', :git => 'git://github.com/cloudfoundry/vcap-services-base.git', :ref => '6bf11935c7'
group :test do
gem "rake"
View
104 atmos/Gemfile.lock
@@ -1,7 +1,57 @@
+GIT
+ remote: git://github.com/cloudfoundry/common.git
+ revision: b96ec1192d961925d91e17ca3831f8547489d918
+ ref: b96ec1192
+ specs:
+ vcap_logging (1.0.2)
+ rake
+
+GIT
+ remote: git://github.com/cloudfoundry/eventmachine.git
+ revision: 2806c630d8631d5dcf9fb2555f665b829052aabe
+ branch: release-0.12.11-cf
+ specs:
+ eventmachine (0.12.11.cloudfoundry.3)
+
+GIT
+ remote: git://github.com/cloudfoundry/vcap-common.git
+ revision: a7779114db666a1cf5eedf3fd1576c657ccafb6d
+ ref: a7779114db
+ specs:
+ vcap_common (1.0.13)
+ eventmachine (~> 0.12.11.cloudfoundry.3)
+ nats (~> 0.4.22.beta.8)
+ posix-spawn (~> 0.3.6)
+ thin (~> 1.3.1)
+ yajl-ruby (~> 0.8.3)
+
+GIT
+ remote: git://github.com/cloudfoundry/vcap-services-base.git
+ revision: 6bf11935c7ae88e30dc1c200161ca74e3babf3f9
+ ref: 6bf11935c7
+ specs:
+ vcap_services_base (0.1.11)
+ curb (~> 0.7.16)
+ datamapper (~> 1.1.0)
+ do_sqlite3 (~> 0.10.3)
+ em-http-request (~> 0.3.0)
+ eventmachine (~> 0.12.11.cloudfoundry.3)
+ eventmachine_httpserver (~> 0.2.1)
+ json (~> 1.4.6)
+ nats (~> 0.4.22.beta.8)
+ resque (~> 1.20)
+ resque-status (~> 0.3.2)
+ ruby-hmac (~> 0.4.0)
+ sinatra (~> 1.2.3)
+ thin (~> 1.3.1)
+ uuidtools (~> 2.1.2)
+ vcap_common (>= 1.0.8)
+ vcap_logging (>= 1.0.2)
+
GEM
remote: http://rubygems.org/
specs:
- addressable (2.2.7)
+ addressable (2.2.8)
bcrypt-ruby (2.1.4)
builder (3.0.0)
ci_reporter (1.6.4)
@@ -59,18 +109,17 @@ GEM
escape_utils
eventmachine (>= 0.12.9)
escape_utils (0.2.4)
- eventmachine (0.12.11.cloudfoundry.3)
eventmachine_httpserver (0.2.1)
- fastercsv (1.5.4)
+ fastercsv (1.5.5)
json (1.4.6)
- json_pure (1.7.0)
- macaddr (1.5.0)
- systemu (>= 2.4.0)
+ json_pure (1.7.3)
+ macaddr (1.6.1)
+ systemu (~> 2.5.0)
multi_json (1.0.4)
- nats (0.4.22)
- daemons (>= 1.1.4)
+ nats (0.4.24)
+ daemons (>= 1.1.5)
eventmachine (>= 0.12.10)
- json_pure (>= 1.6.1)
+ json_pure (>= 1.7.3)
thin (>= 1.3.1)
posix-spawn (0.3.6)
rack (1.4.1)
@@ -87,7 +136,7 @@ GEM
redis-namespace (~> 1.0.2)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
- resque-status (0.3.2)
+ resque-status (0.3.3)
redisk (>= 0.2.1)
resque (~> 1.19)
uuid (~> 2.3)
@@ -110,7 +159,7 @@ GEM
rack (~> 1.1)
tilt (>= 1.2.2, < 2.0)
stringex (1.2.2)
- systemu (2.5.0)
+ systemu (2.5.1)
thin (1.3.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
@@ -119,31 +168,6 @@ GEM
uuid (2.3.5)
macaddr (~> 1.0)
uuidtools (2.1.2)
- vcap_common (1.0.11)
- eventmachine (~> 0.12.11.cloudfoundry.3)
- nats (~> 0.4.22.beta.8)
- posix-spawn (~> 0.3.6)
- thin (~> 1.3.1)
- yajl-ruby (~> 0.8.3)
- vcap_logging (1.0.0)
- rake
- vcap_services_base (0.1.10)
- curb (~> 0.7.16)
- datamapper (~> 1.1.0)
- do_sqlite3 (~> 0.10.3)
- em-http-request (~> 0.3.0)
- eventmachine (~> 0.12.11.cloudfoundry.3)
- eventmachine_httpserver (~> 0.2.1)
- json (~> 1.4.6)
- nats (~> 0.4.22.beta.8)
- resque (~> 1.20)
- resque-status (~> 0.3.2)
- ruby-hmac (~> 0.4.0)
- sinatra (~> 1.2.3)
- thin (~> 1.3.1)
- uuidtools (~> 2.1.2)
- vcap_common (>= 1.0.8)
- vcap_logging (>= 0.1.3)
vegas (0.1.11)
rack (>= 1.0.0)
xml-simple (1.0.15)
@@ -158,7 +182,7 @@ DEPENDENCIES
dm-sqlite-adapter
do_sqlite3
em-http-request
- eventmachine
+ eventmachine!
rake
rcov
rspec
@@ -168,7 +192,7 @@ DEPENDENCIES
sinatra
thin
uuidtools
- vcap_common (>= 1.0.8)
- vcap_logging (>= 0.1.3)
- vcap_services_base
+ vcap_common!
+ vcap_logging!
+ vcap_services_base!
xml-simple
View
6 atmos/Rakefile
@@ -1,13 +1,13 @@
require 'rake'
desc "Run specs"
-task "spec" => ["bundler:install:test", "test:spec"]
+task "spec" => ["test:spec"]
desc "Run specs using SimpleCov"
-task "spec:rcov" => ["bundler:install:test", "test:spec:rcov"]
+task "spec:rcov" => ["test:spec:rcov"]
desc "Run ci using SimpleCov"
-task "spec:ci" => ["bundler:install:test", "test:spec:ci"]
+task "spec:ci" => ["test:spec:ci"]
namespace "bundler" do
desc "Install gems"
View
BIN atmos/vendor/cache/addressable-2.2.7.gem
Binary file not shown.
View
BIN atmos/vendor/cache/addressable-2.2.8.gem
Binary file not shown.
View
BIN atmos/vendor/cache/eventmachine-0.12.11.cloudfoundry.3.gem
Binary file not shown.
View
BIN atmos/vendor/cache/fastercsv-1.5.4.gem
Binary file not shown.
View
BIN atmos/vendor/cache/fastercsv-1.5.5.gem
Binary file not shown.
View
BIN atmos/vendor/cache/json_pure-1.7.0.gem
Binary file not shown.
View
BIN atmos/vendor/cache/json_pure-1.7.3.gem
Binary file not shown.
View
BIN atmos/vendor/cache/macaddr-1.5.0.gem
Binary file not shown.
View
BIN atmos/vendor/cache/macaddr-1.6.1.gem
Binary file not shown.
View
BIN atmos/vendor/cache/nats-0.4.22.gem
Binary file not shown.
View
BIN atmos/vendor/cache/nats-0.4.24.gem
Binary file not shown.
View
BIN atmos/vendor/cache/resque-status-0.3.2.gem
Binary file not shown.
View
BIN atmos/vendor/cache/resque-status-0.3.3.gem
Binary file not shown.
View
BIN memcached/vendor/cache/systemu-2.5.0.gem → atmos/vendor/cache/systemu-2.5.1.gem
Binary file not shown.
View
BIN atmos/vendor/cache/vcap_common-1.0.11.gem
Binary file not shown.
View
BIN atmos/vendor/cache/vcap_logging-1.0.0.gem
Binary file not shown.
View
BIN atmos/vendor/cache/vcap_services_base-0.1.10.gem
Binary file not shown.
View
16 base/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- vcap_services_base (0.1.10)
+ vcap_services_base (0.1.11)
curb (~> 0.7.16)
datamapper (~> 1.1.0)
do_sqlite3 (~> 0.10.3)
@@ -17,12 +17,12 @@ PATH
thin (~> 1.3.1)
uuidtools (~> 2.1.2)
vcap_common (>= 1.0.8)
- vcap_logging (>= 0.1.3)
+ vcap_logging (>= 1.0.2)
GEM
remote: http://rubygems.org/
specs:
- addressable (2.2.7)
+ addressable (2.2.8)
bcrypt-ruby (2.1.4)
builder (3.0.0)
ci_reporter (1.6.4)
@@ -76,9 +76,9 @@ GEM
escape_utils (0.2.4)
eventmachine (0.12.11.cloudfoundry.3)
eventmachine_httpserver (0.2.1)
- fastercsv (1.5.4)
+ fastercsv (1.5.5)
json (1.4.6)
- json_pure (1.7.0)
+ json_pure (1.7.3)
macaddr (1.5.0)
systemu (>= 2.4.0)
multi_json (1.0.4)
@@ -102,7 +102,7 @@ GEM
redis-namespace (~> 1.0.2)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
- resque-status (0.3.2)
+ resque-status (0.3.3)
redisk (>= 0.2.1)
resque (~> 1.19)
uuid (~> 2.3)
@@ -134,13 +134,13 @@ GEM
uuid (2.3.5)
macaddr (~> 1.0)
uuidtools (2.1.2)
- vcap_common (1.0.11)
+ vcap_common (1.0.13)
eventmachine (~> 0.12.11.cloudfoundry.3)
nats (~> 0.4.22.beta.8)
posix-spawn (~> 0.3.6)
thin (~> 1.3.1)
yajl-ruby (~> 0.8.3)
- vcap_logging (1.0.0)
+ vcap_logging (1.0.2)
rake
vegas (0.1.11)
rack (>= 1.0.0)
View
1 base/lib/base/asynchronous_service_gateway.rb
@@ -61,6 +61,7 @@ def setup(opts)
:label => @service[:label],
:url => @service[:url],
:plans => @service[:plans],
+ :cf_plan_id => @service[:cf_plan_id],
:tags => @service[:tags],
:active => true,
:description => @service[:description],
View
13 base/lib/base/job/lock.rb
@@ -12,10 +12,17 @@ class Lock
attr_reader :expiration, :timeout, :name
include VCAP::Services::Base::Error
+ # Options for lock
+ # name - The uuid of the lock
+ # timeout - The time that waits to acquire the lock, default 10 seconds
+ # expiration - Lock expires in given seconds if not refreshed, default 10 seconds
+ # logger - The logger..
+ # ttl - The max time that a thread can acquire the lock, default 600 seconds. Lock raise +JOB_TIMEOUT+ error once the ttl is exceeded.
def initialize(name, opts={})
@name = name
@timeout = opts[:timeout] || 10 #seconds
@expiration = opts[:expiration] || 10 # seconds
+ @ttl = opts[:ttl] || 600 # seconds
@logger = opts[:logger] || make_logger
config = Config.redis_config
raise "Can't find configuration of redis." unless config
@@ -52,7 +59,11 @@ def lock
@logger.debug("Lock #{@name} is acquired, will expire at #{@lock_expiration}")
begin
- yield if block_given?
+ Timeout::timeout(@ttl) do
+ yield if block_given?
+ end
+ rescue Timeout::Error =>e
+ raise ServiceError.new(ServiceError::JOB_TIMEOUT, @ttl)
ensure
release_thread(refresh_thread) if refresh_thread
delete
View
40 base/lib/base/job/serialization.rb
@@ -67,7 +67,8 @@ def initialize(*args)
def create_lock
lock_name = "lock:lifecycle:#{name}"
- lock = Lock.new(lock_name, :logger => @logger)
+ ttl = @config[:job_ttl] || 600
+ lock = Lock.new(lock_name, :logger => @logger, :ttl => ttl)
lock
end
@@ -240,11 +241,40 @@ def perform
# Fetch remote uri and stream content to file.
def fetch_url(url, file_path)
- # TODO check the file size before download?
+ max_download_size = (@config["serialization"] && @config["serialization"]["max_download_size_mb"] || 10).to_i * 1024 * 1024 # 10M by default
+ max_redirects = @config["serialization"] && @config["serialization"]["max_download_redirects"] || 5
+
File.open(file_path, "wb+") do |f|
c = Curl::Easy.new(url)
- c.on_body{|data| f.write(data)}
- c.perform
+ # force use ipv4 dns
+ c.resolve_mode = :ipv4
+ # auto redirect
+ c.follow_location = true
+ c.max_redirects = max_redirects
+
+ c.on_header do |header|
+ if c.downloaded_content_length > max_download_size
+ raise ServiceError.new(ServiceError::FILESIZE_TOO_LARGE, url, c.downloaded_content_length, max_download_size)
+ end
+
+ header.size
+ end
+
+ bytes_downloaded = 0
+ c.on_body do |data|
+ # calculate bytes downloaded for chucked response
+ bytes_downloaded += data.size
+ if bytes_downloaded > max_download_size
+ raise ServiceError.new(ServiceError::FILESIZE_TOO_LARGE, url, bytes_downloaded, max_download_size)
+ end
+ f.write(data)
+ end
+
+ begin
+ c.perform
+ rescue Curl::Err::TooManyRedirectsError
+ raise ServiceError.new(ServiceError::TOO_MANY_REDIRECTS, url, max_redirects)
+ end
end
end
@@ -275,7 +305,7 @@ def perform
end
raise "Can't find temp file: #{@temp_file_path}" unless File.exists? temp_file_path
- raise ServiceError.new(SerivceError::BAD_SERIALIZED_DATAFILE, "request") unless validate_input(temp_file_path)
+ raise ServiceError.new(ServiceError::BAD_SERIALIZED_DATAFILE, "request") unless validate_input(temp_file_path)
@snapshot_id = new_snapshot_id
@snapshot_path = get_dump_path(name, snapshot_id)
View
3 base/lib/base/job/snapshot.rb
@@ -144,7 +144,8 @@ def required_options(*args)
def create_lock
lock_name = "lock:lifecycle:#{name}"
- lock = Lock.new(lock_name, :logger => @logger)
+ ttl = @config[:job_ttl] || 600
+ lock = Lock.new(lock_name, :logger => @logger, :ttl => ttl)
lock
end
View
56 base/lib/base/node.rb
@@ -20,6 +20,7 @@ def initialize(options)
@capacity_lock = Mutex.new
@migration_nfs = options[:migration_nfs]
@fqdn_hosts = options[:fqdn_hosts]
+ @op_time_limit = options[:op_time_limit]
z_interval = options[:z_interval] || 30
EM.add_periodic_timer(z_interval) do
@@ -53,17 +54,38 @@ def on_connect_node
EM.add_periodic_timer(30) { send_node_announcement }
end
+ # raise an error if operation does not finish in time limit
+ # and perform a rollback action if rollback function is provided
+ def timing_exec(time_limit, rollback=nil)
+ return unless block_given?
+
+ start = Time.now
+ response = yield
+ if response && Time.now - start > time_limit
+ rollback.call(response) if rollback
+ raise ServiceError::new(ServiceError::NODE_OPERATION_TIMEOUT)
+ end
+ end
+
def on_provision(msg, reply)
@logger.debug("#{service_description}: Provision request: #{msg} from #{reply}")
response = ProvisionResponse.new
- provision_req = ProvisionRequest.decode(msg)
- plan = provision_req.plan
- credentials = provision_req.credentials
- credential = provision(plan, credentials)
- credential['node_id'] = @node_id
- response.credentials = credential
- @capacity_lock.synchronize{ @capacity -= capacity_unit }
- @logger.debug("#{service_description}: Successfully provisioned service for request #{msg}: #{response.inspect}")
+ rollback = lambda do |res|
+ @logger.error("#{service_description}: Provision takes too long. Rollback for #{res.inspect}")
+ unprovision(res.credentials["name"], [])
+ end
+
+ timing_exec(@op_time_limit, rollback) do
+ provision_req = ProvisionRequest.decode(msg)
+ plan = provision_req.plan
+ credentials = provision_req.credentials
+ credential = provision(plan, credentials)
+ credential['node_id'] = @node_id
+ response.credentials = credential
+ @capacity_lock.synchronize{ @capacity -= capacity_unit }
+ @logger.debug("#{service_description}: Successfully provisioned service for request #{msg}: #{response.inspect}")
+ response
+ end
publish(reply, encode_success(response))
rescue => e
@logger.warn("Exception at on_provision #{e}")
@@ -91,11 +113,19 @@ def on_unprovision(msg, reply)
def on_bind(msg, reply)
@logger.debug("#{service_description}: Bind request: #{msg} from #{reply}")
response = BindResponse.new
- bind_message = BindRequest.decode(msg)
- name = bind_message.name
- bind_opts = bind_message.bind_opts
- credentials = bind_message.credentials
- response.credentials = bind(name, bind_opts, credentials)
+ rollback = lambda do |res|
+ @logger.error("#{service_description}: Binding takes too long. Rollback for #{res.inspect}")
+ unbind(res.credentials)
+ end
+
+ timing_exec(@op_time_limit, rollback) do
+ bind_message = BindRequest.decode(msg)
+ name = bind_message.name
+ bind_opts = bind_message.bind_opts
+ credentials = bind_message.credentials
+ response.credentials = bind(name, bind_opts, credentials)
+ response
+ end
publish(reply, encode_success(response))
rescue => e
@logger.warn("Exception at on_bind #{e}")
View
3 base/lib/base/node_bin.rb
@@ -61,7 +61,8 @@ def start
:local_db => parse_property(config, "local_db", String),
:migration_nfs => parse_property(config, "migration_nfs", String, :optional => true),
:max_nats_payload => parse_property(config, "max_nats_payload", Integer, :optional => true),
- :fqdn_hosts => parse_property(config, "fqdn_hosts", Boolean, :optional => true, :default => false)
+ :fqdn_hosts => parse_property(config, "fqdn_hosts", Boolean, :optional => true, :default => false),
+ :op_time_limit => parse_property(config, "op_time_limit", Integer, :optional => true, :default => 6)
}
VCAP::Logging.setup_from_config(config["logging"])
View
12 base/lib/base/provisioner.rb
@@ -170,7 +170,9 @@ def on_node_handles(msg, reply)
@staging_orphan_instances[nid] << ins unless @instance_handles_CO.has_key?(ins)
end
response.bindings_list.each do |bind|
- key = bind["name"].concat(bind["username"] || bind["user"])
+ user = bind["username"] || bind["user"]
+ next unless user
+ key = bind["name"].concat(user)
@staging_orphan_bindings[nid] << bind unless @binding_handles_CO.has_key?(key)
end
oi_count = @staging_orphan_instances.values.reduce(0) { |m, v| m += v.count }
@@ -190,7 +192,9 @@ def indexing_handles(handles)
if h["service_id"] == h["credentials"]["name"]
ins_handles[h["service_id"]] = h
else
- key = h["credentials"]["name"].concat(h["credentials"]["username"] || h["credentials"]["user"])
+ user = h["credentials"]["username"] || h["credentials"]["user"]
+ next unless user
+ key = h["credentials"]["name"].concat(user)
bin_handles[key] = h
end
end
@@ -225,7 +229,9 @@ def double_check_orphan(handles)
@staging_orphan_bindings.each do |nid, ob_list|
@final_orphan_bindings[nid] ||= []
ob_list.each do |ob|
- key = ob["name"].concat(ob["username"] || ob["user"])
+ user = ob["username"] || ob["user"]
+ next unless user
+ key = ob["name"].concat(user)
@final_orphan_bindings[nid] << ob unless bin_handles.has_key?(key)
end
end
View
6 base/lib/base/service_error.rb
@@ -42,6 +42,7 @@ class ServiceError < StandardError
# 30500 - 30599 500 Internal Error
INTERNAL_ERROR = [30500, HTTP_INTERNAL, 'Internal Error']
EXTENSION_NOT_IMPL = [30501, HTTP_NOT_IMPLEMENTED, "Service extension %s is not implemented."]
+ NODE_OPERATION_TIMEOUT = [30502, HTTP_INTERNAL, "Node operation timeout"]
# 30600 - 30699 503 Service Unavailable
SERVICE_UNAVAILABLE = [30600, HTTP_SERVICE_UNAVAIL, 'Service unavailable']
@@ -52,7 +53,10 @@ class ServiceError < StandardError
# 30800 - 30899 500 Lifecycle error
OVER_QUOTA = [30800, HTTP_INTERNAL, "Instance %s has %s snapshots. Quota is %s "]
JOB_QUEUE_TIMEOUT = [30801, HTTP_INTERNAL, "Job timeout after waiting for %s seconds."]
- BAD_SERIALIZED_DATAFILE = [30801, HTTP_INTERNAL, "Invalid serialized data file from: %s"]
+ JOB_TIMEOUT = [30802, HTTP_INTERNAL, "Job is killed since it runs longer than ttl: %s seconds."]
+ BAD_SERIALIZED_DATAFILE = [30803, HTTP_INTERNAL, "Invalid serialized data file from: %s"]
+ FILESIZE_TOO_LARGE = [30804, HTTP_BAD_REQUEST, "Size of file from url %s is %s, max allowed %s"]
+ TOO_MANY_REDIRECTS = [30805, HTTP_BAD_REQUEST, "Too many redirects from url:%s, max redirects allowed is %s"]
# 31000 - 32000 Service-specific Error
# Defined in services directory, for example mongodb/lib/mongodb_service/
View
2 base/lib/base/version.rb
@@ -1,7 +1,7 @@
module VCAP
module Services
module Base
- VERSION = "0.1.10"
+ VERSION = "0.1.11"
end
end
end
View
4 base/spec/Rakefile
@@ -21,7 +21,7 @@ desc "Run specs using SimpleCov"
task "spec:ci" => ["ci:setup:rspec", "simcov"]
RSpec::Core::RakeTask.new do |t|
- t.pattern = "**/*_spec.rb"
+ t.pattern = "**/unit_test/*_spec.rb"
t.rspec_opts = ["--format", "documentation", "--colour"]
end
@@ -38,7 +38,7 @@ task "simcov" => "cleanup_coverage" do
SimpleCov.coverage_dir('spec_coverage')
SimpleCov.start do
add_filter "/spec/"
- spec_dir = File.expand_path("..", __FILE__)
+ spec_dir = File.expand_path("../unit_test/", __FILE__)
Rspec::Core::Runner.disable_autorun!
Rspec::Core::Runner.run([spec_dir], STDERR, STDOUT)
end
View
0 base/spec/async_gw_spec.rb → base/spec/function_test/async_gw_spec.rb
File renamed without changes.
View
0 base/spec/backup_spec.rb → base/spec/function_test/backup_spec.rb
File renamed without changes.
View
0 base/spec/base_spec.rb → base/spec/function_test/base_spec.rb
File renamed without changes.
View
0 base/spec/job_spec.rb → base/spec/function_test/job_spec.rb
File renamed without changes.
View
34 base/spec/node_spec.rb → base/spec/function_test/node_spec.rb
@@ -3,6 +3,7 @@
require 'eventmachine'
describe NodeTests do
+ include VCAP::Services::Internal
it "should announce on startup" do
node = nil
@@ -148,6 +149,22 @@
(original_capacity - node.capacity).should == 0
end
+ it "should handle long time provision" do
+ node = nil
+ provisioner = nil
+ EM.run do
+ Do.sec(0) do
+ node = NodeTests.create_node;
+ node.stub!(:provision){ sleep 6; {"name" => "test"} }
+ node.should_receive(:provision)
+ end
+ Do.sec(1) { provisioner = NodeTests.create_error_provisioner}
+ Do.sec(2) { provisioner.send_provision_request }
+ Do.sec(10) { EM.stop }
+ end
+ provisioner.response["success"].should be_true
+ end
+
it "should support unprovision" do
node = nil
provisioner = nil
@@ -228,6 +245,23 @@
provisioner.response.should =~ /Service unavailable/
end
+ it "should handle long time bind" do
+ node = nil
+ provisioner = nil
+ EM.run do
+ Do.sec(0) do
+ node = NodeTests.create_node;
+ node.stub!(:bind){ sleep 6; BindResponse.new }
+ node.should_receive(:bind)
+ end
+ Do.sec(1) { provisioner = NodeTests.create_error_provisioner}
+ Do.sec(2) { provisioner.send_bind_request }
+ Do.sec(10) { EM.stop }
+ end
+ provisioner.response["success"].should be_true
+ end
+
+
it "should support unbind" do
node = nil
provisioner = nil
View
0 base/spec/provision_spec.rb → base/spec/function_test/provision_spec.rb
File renamed without changes.
View
7 base/spec/helper/node_spec_helper.rb
@@ -41,6 +41,7 @@ class NodeTester < VCAP::Services::Base::Node
def initialize(options)
super(options)
@ready = true
+ @op_time_limit = 5
@announcement_invoked = false
@provision_invoked = false
@unprovision_invoked = false
@@ -65,6 +66,9 @@ def initialize(options)
def service_name
SERVICE_NAME
end
+ def nats=(mock_nats)
+ @node_nats = mock_nats
+ end
def set_ready(r)
@ready = r
end
@@ -287,6 +291,9 @@ def announcement
@announcement_invoked = true
Hash.new
end
+ def nats=(mock_nats)
+ @node_nats = mock_nats
+ end
def provision(plan, credential)
@provision_invoked = true
raise ServiceError.new(ServiceError::SERVICE_UNAVAILABLE)
View
12 base/spec/helper/provision_spec_helper.rb
@@ -28,6 +28,12 @@ def self.setup_fake_instance(gateway, provisioner, node)
provisioner.prov_svcs[instance_id] = {:credentials => {'node_id' =>node.node_id }}
end
+ def self.setup_fake_instance_by_id(gateway, provisioner, node_id)
+ instance_id = "fake_instance"
+ gateway.instance_id = instance_id
+ provisioner.prov_svcs[instance_id] = {:credentials => {'node_id' => node_id }}
+ end
+
class ProvisionerTester < VCAP::Services::Base::Provisioner
attr_accessor :prov_svcs
attr_accessor :varz_invoked
@@ -41,6 +47,12 @@ def initialize(options)
@varz_invoked = false
@healthz_invoked = false
end
+ def nats=(mock_nats)
+ @node_nats = mock_nats
+ end
+ def nodes=(mock_nodes)
+ @nodes = mock_nodes
+ end
SERVICE_NAME = "Test"
def service_name
SERVICE_NAME
View
305 base/spec/unit_test/async_gw_spec.rb
@@ -0,0 +1,305 @@
+# Copyright (c) 2009-2011 VMware, Inc.
+require 'helper/spec_helper'
+require 'eventmachine'
+
+describe AsyncGatewayTests do
+
+ it "should invoke check_orphan in check_orphan_interval time" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_check_orphan_gateway(true, 5, 3); gateway.start }
+ Do.at(20) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.check_orphan_invoked.should be_true
+ gateway.double_check_orphan_invoked.should be_true
+ end
+
+ it "should be able to purge_orphan" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_purge_orphan_request}
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.purge_orphan_http_code.should == 200
+ end
+
+ it "should be able to return error when purge_orphan failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_purge_orphan_request}
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.purge_orphan_http_code.should == 500
+ end
+
+ it "should be able to check_orphan" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_check_orphan_gateway(true, 10, 3); gateway.start }
+ Do.at(2) { gateway.send_check_orphan_request}
+ Do.at(10) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.check_orphan_invoked.should be_true
+ gateway.double_check_orphan_invoked.should be_true
+ gateway.check_orphan_http_code.should == 200
+ end
+
+ it "should be able to return error when check_orphan failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_check_orphan_request}
+ Do.at(10) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.check_orphan_invoked.should be_true
+ gateway.double_check_orphan_invoked.should be_false
+ gateway.check_orphan_http_code.should == 500
+ end
+
+ it "should be able to provision" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 200
+ end
+
+ it "should be able to unprovision" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(3) { gateway.send_unprovision_request }
+ Do.at(4) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 200
+ gateway.unprovision_http_code.should == 200
+ end
+
+ it "should be able to bind" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(3) { gateway.send_bind_request }
+ Do.at(4) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 200
+ gateway.bind_http_code.should == 200
+ end
+
+ it "should be able to unbind" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(3) { gateway.send_bind_request }
+ Do.at(4) { gateway.send_unbind_request }
+ Do.at(5) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 200
+ gateway.bind_http_code.should == 200
+ gateway.unbind_http_code.should == 200
+ end
+
+ it "should be able to restore" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_restore_request('s_id') }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.restore_http_code.should == 200
+ end
+
+ it "should be able to recover" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_recover_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.recover_http_code.should == 200
+ end
+
+ it "should be able to migrate instance" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_migrate_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.migrate_http_code.should == 200
+ end
+
+ it "should be able to get instance id list" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_instances_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.instances_http_code.should == 200
+ end
+
+ it "should not serve request when handle is not fetched" do
+ gateway = nil
+ EM.run do
+ # We don't start cc here, so gateway will fail to fetch handles
+ Do.at(0) { gateway = AsyncGatewayTests.create_nice_gateway ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(3) { gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 503
+ end
+
+ it "should work if provisioner finishes within timeout" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_timeout_gateway(true, 3) ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(13) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 200
+ end
+
+ it "should be able to report timeout if provisioner cannot finish within timeout" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_timeout_gateway(false, 3) ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(13) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 503
+ end
+
+ it "should be able to return error when provision failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_provision_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.provision_http_code.should == 500
+ end
+
+ it "should be able to return error when unprovision failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_unprovision_request('s_id') }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.unprovision_http_code.should == 500
+ end
+
+ it "should be able to return error when bind failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_bind_request('s_id') }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.bind_http_code.should == 500
+ end
+
+ it "should be able to return error when unbind failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_unbind_request('s_id', 'b_id') }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.unbind_http_code.should == 500
+ end
+
+ it "should be able to return error when restore failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_restore_request('s_id') }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.restore_http_code.should == 500
+ end
+
+ it "should be able to return error when recover failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_recover_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.recover_http_code.should == 500
+ end
+
+ it "should be able to return error when migrate instance failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_migrate_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.migrate_http_code.should == 500
+ end
+
+ it "should be able to return error when get instance id list failed" do
+ cc = nil
+ gateway = nil
+ EM.run do
+ Do.at(0) { cc = AsyncGatewayTests.create_cloudcontroller ; cc.start }
+ Do.at(1) { gateway = AsyncGatewayTests.create_nasty_gateway ; gateway.start }
+ Do.at(2) { gateway.send_instances_request }
+ Do.at(3) { cc.stop ; gateway.stop ; EM.stop }
+ end
+ gateway.instances_http_code.should == 500
+ end
+end
View
42 base/spec/unit_test/backup_spec.rb
@@ -0,0 +1,42 @@
+# Copyright (c) 2009-2011 VMware, Inc.
+require 'helper/spec_helper'
+require 'eventmachine'
+
+describe BackupTest do
+ it "should exit after receive TERM signal" do
+ EM.run do
+ pid = Process.pid
+ backup = BackupTest::ZombieBackup.new
+ EM.defer do
+ backup.start
+ end
+ EM.add_timer(1) { Process.kill("TERM", pid) }
+ EM.add_timer(5) do
+ backup.exit_invoked.should be_true
+ EM.stop
+ end
+ end
+ end
+
+ it "should return true if execution suceeds" do
+ errback_called = false
+ on_err = Proc.new do |cmd, code, msg|
+ errback_called = true
+ end
+ res = CMDHandle.execute("echo", 1, on_err)
+ res.should be_true
+ errback_called.should be_false
+ end
+
+ it "should handle errors if the executable is not found or execution fails" do
+ ["cmdnotfound", "ls filenotfound"].each do |cmd|
+ errback_called = false
+ on_err = Proc.new do |cmd, code, msg|
+ errback_called = true
+ end
+ res = CMDHandle.execute(cmd, 1, on_err)
+ res.should be_false
+ errback_called.should be_true
+ end
+ end
+end
View
17 base/spec/unit_test/base_spec.rb
@@ -0,0 +1,17 @@
+# Copyright (c) 2009-2011 VMware, Inc.
+require 'helper/spec_helper'
+require 'eventmachine'
+
+describe BaseTests do
+
+ it "should connect to node message bus" do
+ base = nil
+ EM.run do
+ Do.at(0) { base = BaseTests.create_base }
+ Do.at(1) { EM.stop }
+ end
+ base.node_mbus_connected.should be_true
+ end
+
+end
+
View
118 base/spec/unit_test/job_spec.rb
@@ -0,0 +1,118 @@
+# Copyright (c) 2009-2012 VMware, Inc.
+require 'helper/job_spec_helper'
+
+describe VCAP::Services::Base::AsyncJob::Lock do
+
+ before :all do
+ @timeout = 10
+ @expiration = 5
+ @logger = Logger.new(STDOUT)
+ @logger.level = Logger::ERROR
+ @name = "foo"
+ end
+
+ before :each do
+ @redis = mock("redis")
+
+ @stored_value = nil
+ Redis.should_receive(:new).any_number_of_times.and_return(@redis)
+ VCAP::Services::Base::AsyncJob::Config.redis_config = {}
+
+ @redis.should_receive(:setnx).with(@name, anything).any_number_of_times.and_return do |_, value|
+ if @stored_value.nil?
+ @stored_value = value
+ true
+ else
+ nil
+ end
+ end
+ @redis.should_receive(:get).with(@name).any_number_of_times.and_return do
+ @stored_value
+ end
+ @redis.should_receive(:set).with(@name, anything).any_number_of_times.and_return do |_, value|
+ @stored_value = value
+ end
+ @redis.should_receive(:del).with(@name).and_return do
+ @stored_value = nil
+ nil
+ end
+ end
+
+ it "should acquire and release a lock" do
+ @redis.should_receive(:watch).with(@name).any_number_of_times
+ @redis.should_receive(:multi).any_number_of_times.and_yield
+
+ lock = VCAP::Services::Base::AsyncJob::Lock.new(@name,:timeout => @timeout, :expiration => @expiration)
+
+ ran_once = false
+ lock.lock do
+ ran_once = true
+ end
+
+ ran_once.should be_true
+ end
+
+ it "should not let two clients acquire the same lock at the same time" do
+ @redis.should_receive(:watch).with(@name).any_number_of_times
+ @redis.should_receive(:multi).any_number_of_times.and_yield
+
+ lock_a = VCAP::Services::Base::AsyncJob::Lock.new(@name,:timeout => @timeout, :expiration => @expiration, :logger => @logger)
+ lock_b = VCAP::Services::Base::AsyncJob::Lock.new(@name,:timeout => 0.1, :logger => @logger)
+
+ lock_a_ran = false
+ lock_b_ran = false
+ lock_a.lock do
+ lock_a_ran = true
+ expect{lock_b.lock{ lock_b_ran = true } }.should raise_error(VCAP::Services::Base::Error::ServiceError, /Job timeout/)
+ end
+
+ lock_a_ran.should be_true
+ lock_b_ran.should_not be_true
+ end
+
+ it "should acquire an expired lock" do
+ start = Time.now.to_f
+ @stored_value = (start + 3) #lock that expires in 3 seconds
+
+ @redis.should_receive(:watch).with(@name).any_number_of_times
+ @redis.should_receive(:multi).any_number_of_times.and_yield
+
+ lock = VCAP::Services::Base::AsyncJob::Lock.new(@name,:timeout => @timeout, :expiration => @expiration, :logger => @logger)
+
+ ran_once = false
+ lock.lock{ran_once = true}
+
+ ran_once.should be_true
+ (@stored_value == start - 1).should_not be_true
+ end
+
+ it "should not update expiration time after the lock is released" do
+ start = Time.now.to_f
+
+ @redis.should_receive(:watch).with(@name).any_number_of_times
+ @redis.should_receive(:multi).any_number_of_times.and_yield
+
+ expiration = 0.5
+ lock = VCAP::Services::Base::AsyncJob::Lock.new(@name,:timeout => @timeout, :expiration => expiration, :logger => @logger)
+
+ ran_once = false
+ lock.lock{ran_once = true; sleep expiration *2 }
+
+ current_value = @stored_value
+ sleep expiration * 2
+ current_value.should == @stored_value
+ ran_once.should be_true
+ end
+
+ it "should raise error if lock exceed ttl" do
+ @redis.should_receive(:watch).with(@name).any_number_of_times
+ @redis.should_receive(:multi).any_number_of_times.and_yield
+
+ ttl = 1
+ lock = VCAP::Services::Base::AsyncJob::Lock.new(@name, :logger => @logger, :ttl => ttl)
+
+ ran_once = false
+ expect { lock.lock{ ran_once = true; sleep ttl * 2} }.should raise_error(VCAP::Services::Base::Error::ServiceError, /ttl: #{ttl} seconds/)
+ ran_once.should be_true
+ end
+end
View
794 base/spec/unit_test/node_spec.rb
@@ -0,0 +1,794 @@
+# Copyright (c) 2009-2011 VMware, Inc.
+require 'helper/spec_helper'
+require 'eventmachine'
+
+describe NodeTests do
+ include VCAP::Services::Internal
+
+ it "should announce on startup" do
+ node = nil
+ provisioner = nil
+ EM.run do
+ # start provisioner then node
+ Do.at(0) { provisioner = NodeTests.create_provisioner }
+ Do.at(1) { node = NodeTests.create_node }
+ Do.at(2) { EM.stop }
+ end
+ provisioner.got_announcement.should be_true
+ end
+
+ it "should call varz & report healthz ok" do
+ node = nil
+ EM.run do
+ Do.at(0) { node = NodeTests.create_node }
+ Do.at(12) { EM.stop }
+ end
+ node.varz_invoked.should be_true
+ node.healthz_ok.should == "ok\n"
+ end
+
+ it "should announce on request" do
+ node = nil
+ provisioner = nil
+ EM.run do
+ # start node then provisioner
+ Do.at(0) { node = NodeTests.create_node }
+ Do.at(1) { provisioner = NodeTests.create_provisioner }
+ Do.at(2) { EM.stop }
+ end
+ node.announcement_invoked.should be_true
+ provisioner.got_announcement.should be_true
+ end
+
+ it "should announce on identical plan" do
+ node = nil
+ mock_nats = nil
+ EM.run do
+ mock_nats = mock("test_mock_nats")
+ node = NodeTests.create_node(:plan => "free")
+ # assign mock nats to node
+ node.nats = mock_nats
+
+ mock_nats.should_receive(:publish).with(any_args())
+
+ req = Yajl::Encoder.encode({"plan" => "free"})
+ node.send_node_announcement(req)
+
+ EM.stop
+ end
+ end
+
+ it "should not announce on different plan" do
+ node = nil
+ mock_nats = nil
+ EM.run do
+ mock_nats = mock("test_mock_nats")
+ node = NodeTests.create_node(:plan => "free")
+ # assign mock nats to node
+ node.nats = mock_nats
+
+ mock_nats.should_not_receive(:publish).with(any_args())
+
+ req = Yajl::Encoder.encode({"plan" => "nonfree"})
+ node.send_node_announcement(req)
+
+ EM.stop
+ end
+ end
+
+ it "should not announce if not ready" do
+ node = nil
+ mock_nats = nil
+ EM.run do
+ mock_nats = mock("test_mock_nats")
+ node = NodeTests.create_node(:plan => "free")
+ # assign mock nats to node
+ node.nats = mock_nats
+ node.set_ready(false)
+
+ mock_nats.should_not_receive(:publish).with(any_args())
+
+ node.send_node_announcement
+
+ EM.stop
+ end
+ end
+
+ it "should support concurrent provision" do
+ node = nil
+ provisioner = nil
+ EM.run do
+ # start node then provisioner
+ Do.sec(0) { node = NodeTests.create_node }
+ Do.sec(1) { provisioner = NodeTests.create_provisioner }
+ # Start 5 concurrent provision requests, each of which takes 5 seconds to finish
+ # Non-concurrent provision handler won't finish in 10 seconds
+ Do.sec(2) { 5.times { provisioner.send_provision_request } }
+ Do.sec(20) { EM.stop }
+ end
+ node.provision_invoked.should be_true
+ node.provision_times.should == 5
+ provisioner.got_provision_response.should be_true
+ end
+
+ it "should handle error in node provision" do
+ node = nil
+ mock_nats = nil
+ response = nil
+ EM.run do
+ mock_nats = mock("test_mock_nats")
+ node = NodeTests.create_error_node
+ # assign mock nats to node
+ node.nats = mock_nats
+
+ mock_nats.should_receive(:publish).with(any_args()).and_return { |*args|
+ response = VCAP::Services::Internal::SimpleResponse.decode(args[1])
+ }
+
+ req = VCAP::Services::Internal::ProvisionRequest.new
+ req.plan = "free"
+ node.on_provision(req.encode, nil)
+
+ node.provision_invoked.should be_true
+ response.success.should be_false
+ response.error["status"].should == 503
+ response.error["msg"]["code"].should == 30600
+
+ EM.stop
+ end
+ end
+
+ it "should decrease capacity after successful provision" do
+ node = nil
+ mock_nats = nil
+ original_capacity = 0
+ EM.run do
+ mock_nats = mock("test_mock_nats")
+ node = NodeTests.create_node
+ # assign mock nats to node
+ node.nats = mock_nats
+
+ mock_nats.should_receive(:publish).with(any_args())
+
+ original_capacity = node.capacity
+ req = VCAP::Services::Internal::ProvisionRequest.new
+ req.plan = "free"
+ node.on_provision(req.encode, nil)
+
+ (original_capacity - node.capacity).should > 0
+
+ EM.stop
+ end
+ end
+
+ it "should not decrease capacity after erroneous provision" do
+ node = nil
+ mock_nats = nil
+ original_capacity = 0
+ EM.run do
+ mock_nats = mock("test_mock_nats")
+ node = NodeTests.create_error_node
+ # assign mock nats to node
+ node.nats = mock_nats
+
+ mock_nats.should_receive(:publish).with(any_args())
+
+ original_capacity = node.capacity
+ req = VCAP::Services::Internal::ProvisionRequest.new
+ req.plan = "free"
+ node.on_provision(req.encode, nil)
+
+ (original_capacity - node.capacity).should == 0
+
+ EM.stop
+ end
+ end
+
+ it "should handle long time provision" do
+ node = nil