rhoconnect 3.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. data/CHANGELOG +208 -0
  2. data/CREDITS +38 -0
  3. data/Gemfile +18 -0
  4. data/Gemfile.lock +97 -0
  5. data/LICENSE +75 -0
  6. data/README.md +10 -0
  7. data/Rakefile +82 -0
  8. data/bench/bench +7 -0
  9. data/bench/bench_runner.rb +112 -0
  10. data/bench/benchapp/Gemfile +21 -0
  11. data/bench/benchapp/Gemfile.lock +76 -0
  12. data/bench/benchapp/Rakefile +22 -0
  13. data/bench/benchapp/application.rb +39 -0
  14. data/bench/benchapp/config.ru +36 -0
  15. data/bench/benchapp/settings/license.key +1 -0
  16. data/bench/benchapp/settings/settings.yml +20 -0
  17. data/bench/benchapp/sources/mock_adapter.rb +55 -0
  18. data/bench/benchapp/sources/queue_mock_adapter.rb +2 -0
  19. data/bench/benchapp/spec/sources/mock_adapter_spec.rb +25 -0
  20. data/bench/benchapp/spec/sources/queue_mock_adapter_spec.rb +25 -0
  21. data/bench/benchapp/spec/spec_helper.rb +42 -0
  22. data/bench/blobapp/Gemfile +31 -0
  23. data/bench/blobapp/Gemfile.lock +103 -0
  24. data/bench/blobapp/Rakefile +25 -0
  25. data/bench/blobapp/application.rb +44 -0
  26. data/bench/blobapp/config.ru +36 -0
  27. data/bench/blobapp/settings/license.key +1 -0
  28. data/bench/blobapp/settings/settings.yml +16 -0
  29. data/bench/blobapp/sources/blob_adapter.rb +71 -0
  30. data/bench/blobapp/spec/sources/blob_adapter_spec.rb +25 -0
  31. data/bench/blobapp/spec/spec_helper.rb +42 -0
  32. data/bench/lib/bench/cli.rb +16 -0
  33. data/bench/lib/bench/logging.rb +13 -0
  34. data/bench/lib/bench/mock_client.rb +41 -0
  35. data/bench/lib/bench/result.rb +50 -0
  36. data/bench/lib/bench/runner.rb +107 -0
  37. data/bench/lib/bench/session.rb +67 -0
  38. data/bench/lib/bench/statistics.rb +56 -0
  39. data/bench/lib/bench/test_data.rb +98 -0
  40. data/bench/lib/bench/timer.rb +10 -0
  41. data/bench/lib/bench/utils.rb +49 -0
  42. data/bench/lib/bench.rb +129 -0
  43. data/bench/lib/testdata/100-data.txt +148 -0
  44. data/bench/lib/testdata/5-data.txt +9 -0
  45. data/bench/lib/testdata/images/icon.ico +0 -0
  46. data/bench/lib/testdata/images/icon.png +0 -0
  47. data/bench/lib/testdata/images/loading-Landscape.png +0 -0
  48. data/bench/lib/testdata/images/loading-LandscapeLeft.png +0 -0
  49. data/bench/lib/testdata/images/loading-LandscapeRight.png +0 -0
  50. data/bench/lib/testdata/images/loading-Portrait.png +0 -0
  51. data/bench/lib/testdata/images/loading-PortraitUpsideDown.png +0 -0
  52. data/bench/lib/testdata/images/loading.png +0 -0
  53. data/bench/lib/testdata/images/loading@2x.png +0 -0
  54. data/bench/run_bench.sh +42 -0
  55. data/bench/run_blob_script.sh +3 -0
  56. data/bench/run_cud_script.sh +3 -0
  57. data/bench/run_query_md_script.sh +3 -0
  58. data/bench/run_query_only_script.sh +3 -0
  59. data/bench/run_query_script.sh +3 -0
  60. data/bench/scripts/blob_cud_script.rb +98 -0
  61. data/bench/scripts/cud_script.rb +92 -0
  62. data/bench/scripts/helpers.rb +101 -0
  63. data/bench/scripts/query_md_script.rb +45 -0
  64. data/bench/scripts/query_only_script.rb +51 -0
  65. data/bench/scripts/query_script.rb +45 -0
  66. data/bench/spec/bench_spec_helper.rb +33 -0
  67. data/bench/spec/logging_spec.rb +15 -0
  68. data/bench/spec/mock_adapter_spec.rb +61 -0
  69. data/bench/spec/mock_client_spec.rb +65 -0
  70. data/bench/spec/result_spec.rb +61 -0
  71. data/bench/spec/utils_spec.rb +36 -0
  72. data/bin/rhoconnect +34 -0
  73. data/bin/rhoconnect-setup +84 -0
  74. data/doc/async-jobs.txt +69 -0
  75. data/doc/authentication.txt +76 -0
  76. data/doc/benchmarks.txt +168 -0
  77. data/doc/blob-sync.txt +130 -0
  78. data/doc/bulk-sync.txt +102 -0
  79. data/doc/client.txt +432 -0
  80. data/doc/command-line.txt +210 -0
  81. data/doc/contributing.txt +60 -0
  82. data/doc/deploying.txt +82 -0
  83. data/doc/install.txt +28 -0
  84. data/doc/introduction.txt +20 -0
  85. data/doc/licensing.txt +18 -0
  86. data/doc/metadata.txt +458 -0
  87. data/doc/migration.txt +182 -0
  88. data/doc/public/css/print.css +29 -0
  89. data/doc/public/css/screen.css +257 -0
  90. data/doc/public/css/style.css +20 -0
  91. data/doc/push.txt +135 -0
  92. data/doc/release.txt +41 -0
  93. data/doc/rest-api.txt +367 -0
  94. data/doc/source-adapters.txt +325 -0
  95. data/doc/stats-middleware.txt +69 -0
  96. data/doc/testing.txt +222 -0
  97. data/doc/tutorial.txt +315 -0
  98. data/doc/web-console.txt +35 -0
  99. data/examples/simple/Rakefile +14 -0
  100. data/examples/simple/application.rb +27 -0
  101. data/examples/simple/config.ru +49 -0
  102. data/examples/simple/settings/license.key +1 -0
  103. data/examples/simple/settings/settings.yml +23 -0
  104. data/examples/simple/sources/sample_adapter.rb +5 -0
  105. data/examples/simple/sources/simple_adapter.rb +5 -0
  106. data/generators/rhoconnect.rb +119 -0
  107. data/generators/templates/application/Gemfile +21 -0
  108. data/generators/templates/application/Rakefile +22 -0
  109. data/generators/templates/application/application.rb +39 -0
  110. data/generators/templates/application/config.ru +36 -0
  111. data/generators/templates/application/settings/license.key +1 -0
  112. data/generators/templates/application/settings/settings.yml +14 -0
  113. data/generators/templates/application/spec/spec_helper.rb +42 -0
  114. data/generators/templates/source/source_adapter.rb +47 -0
  115. data/generators/templates/source/source_spec.rb +25 -0
  116. data/install.sh +408 -0
  117. data/installer/unix-like/rho_connect_install_checkers.rb +140 -0
  118. data/installer/unix-like/rho_connect_install_constants.rb +51 -0
  119. data/installer/unix-like/rho_connect_install_debian.rb +63 -0
  120. data/installer/unix-like/rho_connect_install_dnd.rb +58 -0
  121. data/installer/unix-like/rho_connect_install_get_params.rb +30 -0
  122. data/installer/unix-like/rho_connect_install_installers.rb +142 -0
  123. data/installer/unix-like/rho_connect_install_utilities.rb +85 -0
  124. data/installer/unix-like/rho_connect_install_yum.rb +63 -0
  125. data/installer/unix-like/rhoinstaller.rb +89 -0
  126. data/installer/utils/create_texts.rb +366 -0
  127. data/installer/utils/install_test.rb +140 -0
  128. data/installer/windows/EnvVarUpdate.nsh +328 -0
  129. data/installer/windows/ServiceLib.nsh +369 -0
  130. data/installer/windows/configUi.ini +44 -0
  131. data/installer/windows/icon.ico +0 -0
  132. data/installer/windows/rhosync.nsi +418 -0
  133. data/installer/windows/uninstall.bat +7 -0
  134. data/lib/rhoconnect/api/admin/get_api_token.rb +14 -0
  135. data/lib/rhoconnect/api/admin/get_license_info.rb +8 -0
  136. data/lib/rhoconnect/api/admin/login.rb +6 -0
  137. data/lib/rhoconnect/api/admin/reset.rb +10 -0
  138. data/lib/rhoconnect/api/admin/stats.rb +21 -0
  139. data/lib/rhoconnect/api/application/bulk_data.rb +7 -0
  140. data/lib/rhoconnect/api/application/clientcreate.rb +8 -0
  141. data/lib/rhoconnect/api/application/clientlogin.rb +6 -0
  142. data/lib/rhoconnect/api/application/clientregister.rb +6 -0
  143. data/lib/rhoconnect/api/application/clientreset.rb +6 -0
  144. data/lib/rhoconnect/api/application/query.rb +7 -0
  145. data/lib/rhoconnect/api/application/queue_updates.rb +6 -0
  146. data/lib/rhoconnect/api/application/search.rb +6 -0
  147. data/lib/rhoconnect/api/client/create_client.rb +3 -0
  148. data/lib/rhoconnect/api/client/delete_client.rb +5 -0
  149. data/lib/rhoconnect/api/client/get_client_params.rb +3 -0
  150. data/lib/rhoconnect/api/client/list_client_docs.rb +12 -0
  151. data/lib/rhoconnect/api/client/list_clients.rb +3 -0
  152. data/lib/rhoconnect/api/client/ping.rb +7 -0
  153. data/lib/rhoconnect/api/source/get_adapter.rb +3 -0
  154. data/lib/rhoconnect/api/source/get_db_doc.rb +7 -0
  155. data/lib/rhoconnect/api/source/get_source_params.rb +3 -0
  156. data/lib/rhoconnect/api/source/list_source_docs.rb +10 -0
  157. data/lib/rhoconnect/api/source/list_sources.rb +15 -0
  158. data/lib/rhoconnect/api/source/push_deletes.rb +8 -0
  159. data/lib/rhoconnect/api/source/push_objects.rb +8 -0
  160. data/lib/rhoconnect/api/source/save_adapter.rb +3 -0
  161. data/lib/rhoconnect/api/source/set_db_doc.rb +8 -0
  162. data/lib/rhoconnect/api/source/set_refresh_time.rb +8 -0
  163. data/lib/rhoconnect/api/source/upload_file.rb +4 -0
  164. data/lib/rhoconnect/api/user/create_user.rb +7 -0
  165. data/lib/rhoconnect/api/user/delete_user.rb +9 -0
  166. data/lib/rhoconnect/api/user/list_users.rb +3 -0
  167. data/lib/rhoconnect/api/user/update_user.rb +4 -0
  168. data/lib/rhoconnect/api_token.rb +19 -0
  169. data/lib/rhoconnect/app.rb +76 -0
  170. data/lib/rhoconnect/bulk_data/bulk_data.rb +88 -0
  171. data/lib/rhoconnect/bulk_data/syncdb.index.schema +4 -0
  172. data/lib/rhoconnect/bulk_data/syncdb.schema +41 -0
  173. data/lib/rhoconnect/bulk_data.rb +2 -0
  174. data/lib/rhoconnect/client.rb +96 -0
  175. data/lib/rhoconnect/client_sync.rb +412 -0
  176. data/lib/rhoconnect/console/app/helpers/auth_helper.rb +22 -0
  177. data/lib/rhoconnect/console/app/helpers/extensions.rb +19 -0
  178. data/lib/rhoconnect/console/app/helpers/helpers.rb +57 -0
  179. data/lib/rhoconnect/console/app/public/ThickBox.css +649 -0
  180. data/lib/rhoconnect/console/app/public/home.css +438 -0
  181. data/lib/rhoconnect/console/app/public/images/foot_logo_rhoconnect.png +0 -0
  182. data/lib/rhoconnect/console/app/public/images/header_halo.jpg +0 -0
  183. data/lib/rhoconnect/console/app/public/images/land_separator.gif +0 -0
  184. data/lib/rhoconnect/console/app/public/images/landing_header.jpg +0 -0
  185. data/lib/rhoconnect/console/app/public/images/logo_rhoconnect.png +0 -0
  186. data/lib/rhoconnect/console/app/public/images/rhomobile_rhohub_logo.png +0 -0
  187. data/lib/rhoconnect/console/app/public/images/tabs_separator.png +0 -0
  188. data/lib/rhoconnect/console/app/public/jqplot/excanvas.min.js +35 -0
  189. data/lib/rhoconnect/console/app/public/jqplot/jqplot.barRenderer.min.js +34 -0
  190. data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasAxisLabelRenderer.js +187 -0
  191. data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasAxisTickRenderer.js +226 -0
  192. data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasTextRenderer.js +408 -0
  193. data/lib/rhoconnect/console/app/public/jqplot/jqplot.categoryAxisRenderer.min.js +34 -0
  194. data/lib/rhoconnect/console/app/public/jqplot/jqplot.cursor.js +952 -0
  195. data/lib/rhoconnect/console/app/public/jqplot/jqplot.dateAxisRenderer.js +313 -0
  196. data/lib/rhoconnect/console/app/public/jqplot/jqplot.dateAxisRenderer.min.js +34 -0
  197. data/lib/rhoconnect/console/app/public/jqplot/jqplot.pointLabels.min.js +34 -0
  198. data/lib/rhoconnect/console/app/public/jqplot/jquery-1.4.2.min.js +154 -0
  199. data/lib/rhoconnect/console/app/public/jqplot/jquery.jqplot.min.css +1 -0
  200. data/lib/rhoconnect/console/app/public/jqplot/jquery.jqplot.min.js +34 -0
  201. data/lib/rhoconnect/console/app/public/main.css +7 -0
  202. data/lib/rhoconnect/console/app/public/reset.css +76 -0
  203. data/lib/rhoconnect/console/app/public/style.css +2201 -0
  204. data/lib/rhoconnect/console/app/public/text.txt +0 -0
  205. data/lib/rhoconnect/console/app/routes/adapter.rb +28 -0
  206. data/lib/rhoconnect/console/app/routes/auth.rb +29 -0
  207. data/lib/rhoconnect/console/app/routes/client.rb +31 -0
  208. data/lib/rhoconnect/console/app/routes/docs.rb +145 -0
  209. data/lib/rhoconnect/console/app/routes/heroku.rb +19 -0
  210. data/lib/rhoconnect/console/app/routes/home.rb +63 -0
  211. data/lib/rhoconnect/console/app/routes/timing.rb +242 -0
  212. data/lib/rhoconnect/console/app/routes/user.rb +117 -0
  213. data/lib/rhoconnect/console/app/views/adapter.erb +16 -0
  214. data/lib/rhoconnect/console/app/views/client.erb +30 -0
  215. data/lib/rhoconnect/console/app/views/content.erb +14 -0
  216. data/lib/rhoconnect/console/app/views/doc.erb +8 -0
  217. data/lib/rhoconnect/console/app/views/docdata.erb +28 -0
  218. data/lib/rhoconnect/console/app/views/docs.erb +30 -0
  219. data/lib/rhoconnect/console/app/views/edituser.erb +13 -0
  220. data/lib/rhoconnect/console/app/views/headermenu.erb +40 -0
  221. data/lib/rhoconnect/console/app/views/home.erb +24 -0
  222. data/lib/rhoconnect/console/app/views/index.erb +58 -0
  223. data/lib/rhoconnect/console/app/views/jqplot.erb +52 -0
  224. data/lib/rhoconnect/console/app/views/layout.erb +165 -0
  225. data/lib/rhoconnect/console/app/views/login.erb +26 -0
  226. data/lib/rhoconnect/console/app/views/newuser.erb +17 -0
  227. data/lib/rhoconnect/console/app/views/ping.erb +28 -0
  228. data/lib/rhoconnect/console/app/views/result.erb +11 -0
  229. data/lib/rhoconnect/console/app/views/rightboxlinks.erb +15 -0
  230. data/lib/rhoconnect/console/app/views/select_doc.erb +17 -0
  231. data/lib/rhoconnect/console/app/views/upload_doc.erb +23 -0
  232. data/lib/rhoconnect/console/app/views/user.erb +29 -0
  233. data/lib/rhoconnect/console/app/views/users.erb +12 -0
  234. data/lib/rhoconnect/console/rhoconnect_api.rb +245 -0
  235. data/lib/rhoconnect/console/server.rb +32 -0
  236. data/lib/rhoconnect/console.rb +3 -0
  237. data/lib/rhoconnect/cors.rb +229 -0
  238. data/lib/rhoconnect/credential.rb +9 -0
  239. data/lib/rhoconnect/db_adapter.rb +46 -0
  240. data/lib/rhoconnect/document.rb +49 -0
  241. data/lib/rhoconnect/dynamic_adapter.rb +91 -0
  242. data/lib/rhoconnect/generator.rb +1 -0
  243. data/lib/rhoconnect/jobs/bulk_data_job.rb +203 -0
  244. data/lib/rhoconnect/jobs/ping_job.rb +46 -0
  245. data/lib/rhoconnect/jobs/source_job.rb +16 -0
  246. data/lib/rhoconnect/license.rb +86 -0
  247. data/lib/rhoconnect/lock_ops.rb +11 -0
  248. data/lib/rhoconnect/model.rb +414 -0
  249. data/lib/rhoconnect/ping/android.rb +56 -0
  250. data/lib/rhoconnect/ping/apple.rb +52 -0
  251. data/lib/rhoconnect/ping/blackberry.rb +56 -0
  252. data/lib/rhoconnect/ping.rb +3 -0
  253. data/lib/rhoconnect/read_state.rb +31 -0
  254. data/lib/rhoconnect/rho_indifferent_access.rb +88 -0
  255. data/lib/rhoconnect/server/views/index.erb +13 -0
  256. data/lib/rhoconnect/server.rb +286 -0
  257. data/lib/rhoconnect/source.rb +289 -0
  258. data/lib/rhoconnect/source_adapter.rb +123 -0
  259. data/lib/rhoconnect/source_sync.rb +302 -0
  260. data/lib/rhoconnect/stats/middleware.rb +20 -0
  261. data/lib/rhoconnect/stats/record.rb +108 -0
  262. data/lib/rhoconnect/store.rb +232 -0
  263. data/lib/rhoconnect/tasks.rb +350 -0
  264. data/lib/rhoconnect/test_methods.rb +220 -0
  265. data/lib/rhoconnect/user.rb +95 -0
  266. data/lib/rhoconnect/version.rb +3 -0
  267. data/lib/rhoconnect/x_domain_session_wrapper.rb +53 -0
  268. data/lib/rhoconnect.rb +285 -0
  269. data/rhoconnect.gemspec +67 -0
  270. data/spec/api/admin/api_token_spec.rb +14 -0
  271. data/spec/api/admin/get_api_token_spec.rb +36 -0
  272. data/spec/api/admin/get_license_info_spec.rb +38 -0
  273. data/spec/api/admin/reset_spec.rb +22 -0
  274. data/spec/api/admin/stats_spec.rb +66 -0
  275. data/spec/api/api_helper.rb +21 -0
  276. data/spec/api/application/rhoconnect_api_spec.rb +548 -0
  277. data/spec/api/client/create_client_spec.rb +13 -0
  278. data/spec/api/client/delete_client_spec.rb +13 -0
  279. data/spec/api/client/get_client_params_spec.rb +18 -0
  280. data/spec/api/client/list_client_docs_spec.rb +32 -0
  281. data/spec/api/client/list_clients_spec.rb +22 -0
  282. data/spec/api/client/ping_spec.rb +23 -0
  283. data/spec/api/rhosync_api_spec.rb.orig +606 -0
  284. data/spec/api/source/adapter_spec.rb +29 -0
  285. data/spec/api/source/get_db_doc_spec.rb +21 -0
  286. data/spec/api/source/get_source_params_spec.rb +32 -0
  287. data/spec/api/source/list_source_docs_spec.rb +25 -0
  288. data/spec/api/source/list_sources_spec.rb +26 -0
  289. data/spec/api/source/push_deletes_spec.rb +18 -0
  290. data/spec/api/source/push_objects_spec.rb +27 -0
  291. data/spec/api/source/set_db_doc_spec.rb +19 -0
  292. data/spec/api/source/set_refresh_time_spec.rb +43 -0
  293. data/spec/api/source/upload_file_spec.rb +26 -0
  294. data/spec/api/user/create_user_spec.rb +16 -0
  295. data/spec/api/user/delete_user_spec.rb +36 -0
  296. data/spec/api/user/list_users_spec.rb +30 -0
  297. data/spec/api/user/update_user_spec.rb +31 -0
  298. data/spec/api_token_spec.rb +14 -0
  299. data/spec/app_spec.rb +18 -0
  300. data/spec/apps/emptyapp/application.rb +27 -0
  301. data/spec/apps/emptyapp/settings/license.key +1 -0
  302. data/spec/apps/emptyapp/settings/settings.yml +14 -0
  303. data/spec/apps/rhotestapp/Rakefile +1 -0
  304. data/spec/apps/rhotestapp/application.rb +19 -0
  305. data/spec/apps/rhotestapp/config.ru +1 -0
  306. data/spec/apps/rhotestapp/settings/apple_fake_cert.pem +1 -0
  307. data/spec/apps/rhotestapp/settings/license.key +1 -0
  308. data/spec/apps/rhotestapp/settings/settings.yml +36 -0
  309. data/spec/apps/rhotestapp/sources/base_adapter.rb +9 -0
  310. data/spec/apps/rhotestapp/sources/fixed_schema_adapter.rb +28 -0
  311. data/spec/apps/rhotestapp/sources/sample_adapter.rb +71 -0
  312. data/spec/apps/rhotestapp/sources/simple_adapter.rb +41 -0
  313. data/spec/apps/rhotestapp/sources/sub_adapter.rb +7 -0
  314. data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem/mygem.rb +8 -0
  315. data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem.rb +1 -0
  316. data/spec/bulk_data/bulk_data_spec.rb +97 -0
  317. data/spec/client_spec.rb +124 -0
  318. data/spec/client_sync_spec.rb +774 -0
  319. data/spec/doc/base.html +72 -0
  320. data/spec/doc/doc_spec.rb +376 -0
  321. data/spec/doc/footer.html +4 -0
  322. data/spec/doc/header.html +30 -0
  323. data/spec/document_spec.rb +31 -0
  324. data/spec/dynamic_adapter_spec.rb +43 -0
  325. data/spec/factories/factories.rb +17 -0
  326. data/spec/generator/generator_spec.rb +58 -0
  327. data/spec/generator/generator_spec_helper.rb +9 -0
  328. data/spec/jobs/bulk_data_job_spec.rb +125 -0
  329. data/spec/jobs/ping_job_spec.rb +102 -0
  330. data/spec/jobs/source_job_spec.rb +29 -0
  331. data/spec/license_spec.rb +66 -0
  332. data/spec/model_spec.rb +273 -0
  333. data/spec/perf/bulk_data_perf_spec.rb +32 -0
  334. data/spec/perf/perf_spec_helper.rb +50 -0
  335. data/spec/perf/store_perf_spec.rb +27 -0
  336. data/spec/ping/android_spec.rb +91 -0
  337. data/spec/ping/apple_spec.rb +70 -0
  338. data/spec/ping/blackberry_spec.rb +62 -0
  339. data/spec/read_state_spec.rb +35 -0
  340. data/spec/rhosync_spec.rb +75 -0
  341. data/spec/server/cors_spec.rb +287 -0
  342. data/spec/server/server_spec.rb +470 -0
  343. data/spec/server/x_domain_session_wrapper_spec.rb +150 -0
  344. data/spec/source_adapter_spec.rb +125 -0
  345. data/spec/source_spec.rb +114 -0
  346. data/spec/source_sync_spec.rb +328 -0
  347. data/spec/spec.opts +4 -0
  348. data/spec/spec_helper.rb +231 -0
  349. data/spec/stats/middleware_spec.rb +53 -0
  350. data/spec/stats/record_spec.rb +92 -0
  351. data/spec/store_spec.rb +251 -0
  352. data/spec/support/shared_examples.rb +168 -0
  353. data/spec/sync_states_spec.rb +72 -0
  354. data/spec/test_methods_spec.rb +134 -0
  355. data/spec/testdata/1000-data.txt +1414 -0
  356. data/spec/testdata/compressed/compress-data.txt +1 -0
  357. data/spec/testdata/upload1.txt +1 -0
  358. data/spec/testdata/upload2.txt +1 -0
  359. data/spec/user_spec.rb +139 -0
  360. data/tasks/redis.rake +206 -0
  361. metadata +706 -0
@@ -0,0 +1,125 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'support', 'shared_examples')
3
+
4
+ describe "BulkDataJob" do
5
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
6
+
7
+ before(:each) do
8
+ Rhoconnect.blackberry_bulk_sync = true
9
+ end
10
+ after(:each) do
11
+ delete_data_directory
12
+ end
13
+
14
+ let(:mock_schema) { {"property" => { "name" => "string", "brand" => "string" }, "version" => "1.0"} }
15
+
16
+ it "should create bulk data files from master document" do
17
+ set_state('test_db_storage' => @data)
18
+ docname = bulk_data_docname(@a.id,@u.id)
19
+ expected = { @s_fields[:name] => @data,
20
+ 'FixedSchemaAdapter' => @data
21
+ }
22
+ data = BulkData.create(:name => docname,
23
+ :state => :inprogress,
24
+ :app_id => @a.id,
25
+ :user_id => @u.id,
26
+ :sources => [@s_fields[:name], 'FixedSchemaAdapter'])
27
+ BulkDataJob.perform("data_name" => data.name)
28
+ data = BulkData.load(docname)
29
+ data.completed?.should == true
30
+ verify_result(@s.docname(:md) => @data,@s.docname(:md_copy) => @data)
31
+ validate_db(data,expected).should == true
32
+ File.exists?(data.dbfile+'.rzip').should == true
33
+ File.exists?(data.dbfile+'.gzip').should == true
34
+ File.exists?(data.dbfile+'.hsqldb.data').should == true
35
+ File.exists?(data.dbfile+'.hsqldb.data.gzip').should == true
36
+ File.exists?(data.dbfile+'.hsqldb.script').should == true
37
+ File.exists?(data.dbfile+'.hsqldb.properties').should == true
38
+ path = File.join(File.dirname(data.dbfile),'tmp')
39
+ FileUtils.mkdir_p path
40
+ unzip_file("#{data.dbfile}.rzip",path)
41
+ data.dbfile = File.join(path,File.basename(data.dbfile))
42
+ validate_db(data,expected).should == true
43
+ end
44
+
45
+ it "should not create hsql db files if blackberry_bulk_sync is disabled" do
46
+ Rhoconnect.blackberry_bulk_sync = false
47
+ set_state('test_db_storage' => @data)
48
+ docname = bulk_data_docname(@a.id,@u.id)
49
+ data = BulkData.create(:name => docname,
50
+ :state => :inprogress,
51
+ :app_id => @a.id,
52
+ :user_id => @u.id,
53
+ :sources => [@s_fields[:name]])
54
+ BulkDataJob.perform("data_name" => data.name)
55
+ data = BulkData.load(docname)
56
+ data.completed?.should == true
57
+ verify_result(@s.docname(:md) => @data,@s.docname(:md_copy) => @data)
58
+ validate_db(data,@s.name => @data).should == true
59
+ File.exists?(data.dbfile+'.hsqldb.script').should == false
60
+ File.exists?(data.dbfile+'.hsqldb.properties').should == false
61
+ end
62
+
63
+ it "should create sqlite data with source metadata" do
64
+ set_state('test_db_storage' => @data)
65
+ mock_metadata_method([SampleAdapter]) do
66
+ docname = bulk_data_docname(@a.id,@u.id)
67
+ data = BulkData.create(:name => docname,
68
+ :state => :inprogress,
69
+ :app_id => @a.id,
70
+ :user_id => @u.id,
71
+ :sources => [@s_fields[:name]])
72
+ BulkDataJob.perform("data_name" => data.name)
73
+ data = BulkData.load(docname)
74
+ data.completed?.should == true
75
+ verify_result(@s.docname(:md) => @data,
76
+ @s.docname(:metadata) => {'foo'=>'bar'}.to_json,
77
+ @s.docname(:md_copy) => @data)
78
+ validate_db(data,@s.name => @data).should == true
79
+ end
80
+ end
81
+
82
+ it "should create sqlite data with source schema" do
83
+ set_state('test_db_storage' => @data)
84
+ mock_schema_method([SampleAdapter]) do
85
+ docname = bulk_data_docname(@a.id,@u.id)
86
+ data = BulkData.create(:name => docname,
87
+ :state => :inprogress,
88
+ :app_id => @a.id,
89
+ :user_id => @u.id,
90
+ :sources => [@s_fields[:name]])
91
+ BulkDataJob.perform("data_name" => data.name)
92
+ data = BulkData.load(docname)
93
+ data.completed?.should == true
94
+ verify_result(@s.docname(:md) => @data, @s.docname(:md_copy) => @data)
95
+ JSON.parse(Store.get_value(@s.docname(:schema))).should == mock_schema
96
+ validate_db(data,@s.name => @data).should == true
97
+ end
98
+ end
99
+
100
+ it "should raise exception if hsqldata fails" do
101
+ data = BulkData.create(:name => bulk_data_docname(@a.id,@u.id),
102
+ :state => :inprogress,
103
+ :app_id => @a.id,
104
+ :user_id => @u.id,
105
+ :sources => [@s_fields[:name]])
106
+ lambda { BulkDataJob.create_hsql_data_file(data,Time.now.to_i.to_s)
107
+ }.should raise_error(Exception,"Error running hsqldata")
108
+ end
109
+
110
+ it "should delete bulk data if exception is raised" do
111
+ lambda { BulkDataJob.perform("data_name" => 'broken') }.should raise_error(Exception)
112
+ Store.db.keys('bulk_data*').should == []
113
+ end
114
+
115
+ it "should delete bulk data if exception is raised" do
116
+ data = BulkData.create(:name => bulk_data_docname('broken',@u.id),
117
+ :state => :inprogress,
118
+ :app_id => 'broken',
119
+ :user_id => @u.id,
120
+ :sources => [@s_fields[:name]])
121
+ lambda { BulkDataJob.perform("data_name" => data.name) }.should raise_error(Exception)
122
+ Store.db.keys('bulk_data*').should == []
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,102 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'support', 'shared_examples')
3
+
4
+ describe "PingJob" do
5
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
6
+
7
+ it "should perform apple ping with integer parameters" do
8
+ params = {"user_id" => @u.id, "api_token" => @api_token,
9
+ "sources" => [@s.name], "message" => 'hello world',
10
+ "vibrate" => 5, "badge" => '5', "sound" => 'hello.mp3',"phone_id"=>nil}
11
+
12
+ scrubbed_params = params.dup
13
+ scrubbed_params['vibrate'] = '5'
14
+
15
+ Apple.should_receive(:ping).once.with({'device_pin' => @c.device_pin,
16
+ 'device_port' => @c.device_port}.merge!(scrubbed_params))
17
+ PingJob.perform(params)
18
+ end
19
+
20
+ it "should perform blackberry ping with integer parameters" do
21
+ params = {"user_id" => @u.id, "api_token" => @api_token,
22
+ "sources" => [@s.name], "message" => 'hello world',
23
+ "vibrate" => 5, "badge" => '5', "sound" => 'hello.mp3',"phone_id"=>nil}
24
+
25
+ scrubbed_params = params.dup
26
+ scrubbed_params['vibrate'] = '5'
27
+
28
+ @c.device_type = 'blackberry'
29
+ Blackberry.should_receive(:ping).once.with({'device_pin' => @c.device_pin,
30
+ 'device_port' => @c.device_port}.merge!(scrubbed_params))
31
+ PingJob.perform(params)
32
+ end
33
+
34
+ it "should perform apple ping" do
35
+ params = {"user_id" => @u.id, "api_token" => @api_token,
36
+ "sources" => [@s.name], "message" => 'hello world',
37
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3',"phone_id"=>nil}
38
+ Apple.should_receive(:ping).once.with({'device_pin' => @c.device_pin,
39
+ 'device_port' => @c.device_port}.merge!(params))
40
+ PingJob.perform(params)
41
+ end
42
+
43
+ it "should perform blackberry ping" do
44
+ params = {"user_id" => @u.id, "api_token" => @api_token,
45
+ "sources" => [@s.name], "message" => 'hello world',
46
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3',"phone_id"=>nil}
47
+ @c.device_type = 'blackberry'
48
+ Blackberry.should_receive(:ping).once.with({'device_pin' => @c.device_pin,
49
+ 'device_port' => @c.device_port}.merge!(params))
50
+ PingJob.perform(params)
51
+ end
52
+
53
+ it "should skip ping for empty device_type" do
54
+ params = {"user_id" => @u.id, "api_token" => @api_token,
55
+ "sources" => [@s.name], "message" => 'hello world',
56
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3'}
57
+ @c.device_type = nil
58
+ PingJob.should_receive(:log).once.with("Skipping ping for non-registered client_id '#{@c.id}'...")
59
+ lambda { PingJob.perform(params) }.should_not raise_error
60
+ end
61
+
62
+ it "should skip ping for empty device_pin" do
63
+ params = {"user_id" => @u.id, "api_token" => @api_token,
64
+ "sources" => [@s.name], "message" => 'hello world',
65
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3'}
66
+ @c.device_type = 'blackberry'
67
+ @c.device_pin = nil
68
+ PingJob.should_receive(:log).once.with("Skipping ping for non-registered client_id '#{@c.id}'...")
69
+ lambda { PingJob.perform(params) }.should_not raise_error
70
+ end
71
+
72
+ it "should drop ping if it's already in user's device pin list" do
73
+ params = {"user_id" => @u.id, "api_token" => @api_token,
74
+ "sources" => [@s.name], "message" => 'hello world',
75
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3',"phone_id"=>nil}
76
+ # another client with the same device pin ...
77
+ @c1 = Client.create(@c_fields,{:source_name => @s_fields[:name]})
78
+ # and yet another one ...
79
+ @c2 = Client.create(@c_fields,{:source_name => @s_fields[:name]})
80
+
81
+ Apple.should_receive(:ping).with({'device_pin' => @c.device_pin, 'device_port' => @c.device_port}.merge!(params))
82
+ PingJob.should_receive(:log).twice.with(/Dropping ping request for client/)
83
+ lambda { PingJob.perform(params) }.should_not raise_error
84
+ end
85
+
86
+ it "should drop ping if it's already in user's phone id list and device pin is different" do
87
+ params = {"user_id" => @u.id, "api_token" => @api_token,
88
+ "sources" => [@s.name], "message" => 'hello world',
89
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3'}
90
+ @c.phone_id = '3'
91
+ @c_fields.merge!(:phone_id => '3')
92
+ # another client with the same phone id..
93
+ @c1 = Client.create(@c_fields,{:source_name => @s_fields[:name]})
94
+ # yet another...
95
+ @c2 = Client.create(@c_fields,{:source_name => @s_fields[:name]})
96
+
97
+ Apple.should_receive(:ping).with({'device_pin' => @c.device_pin, 'phone_id' => @c.phone_id, 'device_port' => @c.device_port}.merge!(params))
98
+ PingJob.should_receive(:log).twice.with(/Dropping ping request for client/)
99
+ lambda { PingJob.perform(params) }.should_not raise_error
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'support', 'shared_examples')
3
+
4
+ describe "SourceJob" do
5
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
6
+ before(:each) do
7
+ @s = Source.load(@s_fields[:name],@s_params)
8
+ end
9
+
10
+ it "should perform process_query" do
11
+ set_state('test_db_storage' => @data)
12
+ SourceJob.perform('query',@s.id,@s.app_id,@s.user_id,nil,nil)
13
+ verify_result(@s.docname(:md) => @data,
14
+ @s.docname(:md_size) => @data.size.to_s)
15
+ end
16
+
17
+ it "should perform process_cud" do
18
+ expected = {'backend_id'=>@product1}
19
+ @product1['link'] = 'abc'
20
+ set_state(@c.docname(:create) => {'1'=>@product1})
21
+ SourceJob.perform('cud',@s.id,@s.app_id,@s.user_id,@c.id,nil)
22
+ verify_result(@s.docname(:md) => expected,
23
+ @s.docname(:md_size) => expected.size.to_s,
24
+ @c.docname(:cd) => expected,
25
+ @c.docname(:cd_size) => expected.size.to_s,
26
+ @c.docname(:create) => {})
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ require File.join(File.dirname(__FILE__),'spec_helper')
2
+ require File.join(File.dirname(__FILE__), 'support', 'shared_examples')
3
+
4
+ describe "License" do
5
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => false do
6
+ before(:each) do
7
+ Store.put_value(License::CLIENT_DOCKEY,nil)
8
+ end
9
+
10
+ it "should decrypt license" do
11
+ license = License.new
12
+ license.rhoconnect_version.should == 'Version 1'
13
+ license.licensee.should == 'Rhomobile'
14
+ license.seats.should == 10
15
+ license.issued.should == 'Fri Apr 23 17:20:13 -0700 2010'
16
+ end
17
+
18
+ it "should raise exception on license load error" do
19
+ Rhoconnect.stub!(:get_config).and_return({Rhoconnect.environment.to_sym => {}})
20
+ lambda { License.new }.should raise_error(LicenseException, "Error verifying license.")
21
+ end
22
+
23
+ it "should verify # of seats before adding" do
24
+ License.new.check_and_use_seat
25
+ Store.get_value(License::CLIENT_DOCKEY).to_i.should == 1
26
+ end
27
+
28
+ it "should raise exception when seats are exceeded" do
29
+ Store.put_value(License::CLIENT_DOCKEY,10)
30
+ lambda { License.new.check_and_use_seat }.should raise_error(
31
+ LicenseSeatsExceededException, "WARNING: Maximum # of devices exceeded for this license."
32
+ )
33
+ end
34
+
35
+ it "should free license seat" do
36
+ Store.put_value(License::CLIENT_DOCKEY,5)
37
+ License.new.free_seat
38
+ Store.get_value(License::CLIENT_DOCKEY).to_i.should == 4
39
+ end
40
+
41
+ it "should get # of available seats" do
42
+ license = License.new
43
+ license.check_and_use_seat
44
+ license.available.should == 9
45
+ end
46
+
47
+ it "should use RHOCONNECT_LICENSE env var" do
48
+ ENV['RHOCONNECT_LICENSE'] = 'b749cbe6e029400e688360468624388e2cb7f6a1e72c91d4686a1b8c9d37b72c3e1872ec9f369d481220e10759c18e16'
49
+ license = License.new
50
+ license.licensee.should == 'Rhohub'
51
+ license.seats.should == 5
52
+ license.issued.should == 'Tue Aug 10 16:14:24 -0700 2010'
53
+ ENV.delete('RHOCONNECT_LICENSE')
54
+ end
55
+
56
+ it "should use RHOSYNC_LICENSE env var" do
57
+ ENV['RHOSYNC_LICENSE'] = 'b749cbe6e029400e688360468624388e2cb7f6a1e72c91d4686a1b8c9d37b72c3e1872ec9f369d481220e10759c18e16'
58
+ license = License.new
59
+ license.licensee.should == 'Rhohub'
60
+ license.seats.should == 5
61
+ license.issued.should == 'Tue Aug 10 16:14:24 -0700 2010'
62
+ ENV.delete('RHOSYNC_LICENSE')
63
+ end
64
+ end
65
+
66
+ end
@@ -0,0 +1,273 @@
1
+ # Taken from http://github.com/voloko/redis-model
2
+ require File.join(File.dirname(__FILE__),'spec_helper')
3
+
4
+ describe Rhoconnect::Model do
5
+
6
+ context "DSL" do
7
+ class TestDSL < Rhoconnect::Model
8
+ field :foo
9
+ list :bar
10
+ set :sloppy
11
+ end
12
+
13
+ before(:each) do
14
+ @x = TestDSL.with_key(1)
15
+ end
16
+
17
+ it "should define rw accessors for field" do
18
+ @x.should respond_to(:foo)
19
+ @x.should respond_to(:foo=)
20
+ end
21
+
22
+ it "should define r accessor for list" do
23
+ @x.should respond_to(:bar)
24
+ end
25
+
26
+ it "should define r accessor for set" do
27
+ @x.should respond_to(:sloppy)
28
+ end
29
+
30
+ it "should raise error on invalid type" do
31
+ lambda do
32
+ class TestInvalidType < Rhoconnect::Model
33
+ field :invalid, :invalid_type
34
+ end
35
+ end.should raise_error(ArgumentError, 'Unknown type invalid_type for field invalid')
36
+ end
37
+ end
38
+
39
+ context "field type cast" do
40
+ class TestType < Rhoconnect::Model
41
+ field :foo_string, :string
42
+ field :foo_json, :json
43
+ field :foo_date, :datetime
44
+ field :foo_int, :int
45
+ field :foo_float, :float
46
+
47
+ list :list_date, :datetime
48
+ set :set_date, :datetime
49
+ end
50
+
51
+ class TestValidateType < Rhoconnect::Model
52
+ field :v_field, :string
53
+ validates_presence_of :v_field
54
+ end
55
+
56
+ class TestLoadType < Rhoconnect::Model
57
+ field :something, :string
58
+ attr_accessor :foo
59
+ end
60
+
61
+ before(:each) do
62
+ @xRedisMock = RSpec::Mocks::Mock.new
63
+ @yRedisMock = RSpec::Mocks::Mock.new
64
+ @x = TestType.with_key(1)
65
+ @y = TestType.with_key(1)
66
+ @x.stub!(:redis).and_return(@xRedisMock)
67
+ @y.stub!(:redis).and_return(@yRedisMock)
68
+ end
69
+
70
+ it "should create with string id" do
71
+ @x = TestType.create(:id => 'test')
72
+ @x.id.should == 'test'
73
+ end
74
+
75
+ it "should create with auto-increment id" do
76
+ @x = TestType.create
77
+ @x1 = TestType.create
78
+ @x1.id.should == @x.id + 1
79
+ end
80
+
81
+ it "should raise ArgumentError on create with duplicate id" do
82
+ @x = TestType.create(:id => 'test1')
83
+ lambda { TestType.create(:id => 'test1') }.should
84
+ raise_error(ArgumentError, "Record already exists for 'test1'")
85
+ end
86
+
87
+ it "should validate_presence_of v_field" do
88
+ lambda { TestValidateType.create(:id => 'test2') }.should
89
+ raise_error(ArgumentError, "Missing required field 'v_field'")
90
+ end
91
+
92
+ it "should load with attributes set" do
93
+ TestLoadType.create(:id => 'test2')
94
+ @x = TestLoadType.load('test2',{:foo => 'bar'})
95
+ @x.foo.should == 'bar'
96
+ end
97
+
98
+ it "should save string as is" do
99
+ @xRedisMock.should_receive(:[]=).with('test_type:1:foo_string', 'xxx')
100
+ @yRedisMock.should_receive(:[]).with('test_type:1:foo_string').and_return('xxx')
101
+ @x.foo_string = 'xxx'
102
+ @y.foo_string.should be_instance_of(String)
103
+ end
104
+
105
+ it "should marshal integer fields" do
106
+ @xRedisMock.should_receive(:[]=).with('test_type:1:foo_int', '12')
107
+ @yRedisMock.should_receive(:[]).with('test_type:1:foo_int').and_return('12')
108
+ @x.foo_int = 12
109
+ @y.foo_int.should be_kind_of(Integer)
110
+ @y.foo_int.should == 12
111
+ end
112
+
113
+ it "should marshal float fields" do
114
+ @xRedisMock.should_receive(:[]=).with('test_type:1:foo_float', '12.1')
115
+ @yRedisMock.should_receive(:[]).with('test_type:1:foo_float').and_return('12.1')
116
+ @x.foo_float = 12.1
117
+ @y.foo_float.should be_kind_of(Float)
118
+ @y.foo_float.should == 12.1
119
+ end
120
+
121
+ it "should marshal datetime fields" do
122
+ time = DateTime.now
123
+ str = time.strftime('%FT%T%z')
124
+ @xRedisMock.should_receive(:[]=).with('test_type:1:foo_date', str)
125
+ @yRedisMock.should_receive(:[]).with('test_type:1:foo_date').and_return(str)
126
+ @x.foo_date = time
127
+ @y.foo_date.should be_kind_of(DateTime)
128
+ @y.foo_date.should.to_s == time.to_s
129
+ end
130
+
131
+ it "should marshal json structs" do
132
+ data = {'foo' => 'bar', 'x' => 2}
133
+ str = JSON.dump(data)
134
+ @xRedisMock.should_receive(:[]=).with('test_type:1:foo_json', str)
135
+ @yRedisMock.should_receive(:[]).with('test_type:1:foo_json').and_return(str)
136
+ @x.foo_json = data
137
+ @y.foo_json.should be_kind_of(Hash)
138
+ @y.foo_json.should.inspect == data.inspect
139
+ end
140
+
141
+ it "should return nil for empty fields" do
142
+ @xRedisMock.should_receive(:[]).with('test_type:1:foo_date').and_return(nil)
143
+ @x.foo_date.should be_nil
144
+ end
145
+
146
+ it "should marshal list values" do
147
+ data = DateTime.now
148
+ str = data.strftime('%FT%T%z')
149
+
150
+ @xRedisMock.should_receive('rpush').with('test_type:1:list_date', str)
151
+ @xRedisMock.should_receive('lset').with('test_type:1:list_date', 1, str)
152
+ @xRedisMock.should_receive('exists').with('test_type:1:list_date', str)
153
+ @xRedisMock.should_receive('lrem').with('test_type:1:list_date', 0, str)
154
+ @xRedisMock.should_receive('lpush').with('test_type:1:list_date', str)
155
+ @xRedisMock.should_receive('lrange').with('test_type:1:list_date', 0, 1).and_return([str])
156
+ @xRedisMock.should_receive('rpop').with('test_type:1:list_date').and_return(str)
157
+ @xRedisMock.should_receive('lpop').with('test_type:1:list_date').and_return(str)
158
+ @xRedisMock.should_receive('lindex').with('test_type:1:list_date', 0).and_return(str)
159
+ @x.list_date << data
160
+ @x.list_date[1] = data
161
+ @x.list_date.include?(data)
162
+ @x.list_date.remove(0, data)
163
+ @x.list_date.push_head(data)
164
+ @x.list_date[0].should be_kind_of(DateTime)
165
+ @x.list_date[0, 1][0].should be_kind_of(DateTime)
166
+ @x.list_date.pop_tail.should be_kind_of(DateTime)
167
+ @x.list_date.pop_head.should be_kind_of(DateTime)
168
+ end
169
+
170
+ it "should marshal set values" do
171
+ data = DateTime.now
172
+ str = data.strftime('%FT%T%z')
173
+
174
+ @xRedisMock.should_receive('sadd').with('test_type:1:set_date', str)
175
+ @xRedisMock.should_receive('srem').with('test_type:1:set_date', str)
176
+ @xRedisMock.should_receive('sismember').with('test_type:1:set_date', str)
177
+ @xRedisMock.should_receive('smembers').with('test_type:1:set_date').and_return([str])
178
+ @xRedisMock.should_receive('sinter').with('test_type:1:set_date', 'x').and_return([str])
179
+ @xRedisMock.should_receive('sunion').with('test_type:1:set_date', 'x').and_return([str])
180
+ @xRedisMock.should_receive('sdiff').with('test_type:1:set_date', 'x', 'y').and_return([str])
181
+ @x.set_date << data
182
+ @x.set_date.delete(data)
183
+ @x.set_date.include?(data)
184
+ @x.set_date.members[0].should be_kind_of(DateTime)
185
+ @x.set_date.intersect('x')[0].should be_kind_of(DateTime)
186
+ @x.set_date.union('x')[0].should be_kind_of(DateTime)
187
+ @x.set_date.diff('x', 'y')[0].should be_kind_of(DateTime)
188
+ end
189
+
190
+ it "should handle empty members" do
191
+ @xRedisMock.stub!(:smembers).and_return(nil)
192
+ @x.set_date.members.should == []
193
+ end
194
+ end
195
+
196
+ context "increment/decrement" do
197
+ class TestIncrements < Rhoconnect::Model
198
+ field :foo, :integer
199
+ field :bar, :string
200
+ field :baz, :float
201
+ end
202
+
203
+ before do
204
+ @redisMock = RSpec::Mocks::Mock.new
205
+ @x = TestIncrements.with_key(1)
206
+ @x.stub!(:redis).and_return(@redisMock)
207
+ end
208
+
209
+ it "should send INCR when #increment! is called on an integer" do
210
+ @redisMock.should_receive(:incr).with("test_increments:1:foo", 1)
211
+ @x.increment!(:foo)
212
+ end
213
+
214
+ it "should send DECR when #decrement! is called on an integer" do
215
+ @redisMock.should_receive(:decr).with("test_increments:1:foo", 1)
216
+ @x.decrement!(:foo)
217
+ end
218
+
219
+ it "should raise an ArgumentError when called on non-integers" do
220
+ [:bar, :baz].each do |f|
221
+ lambda{@x.increment!(f)}.should raise_error(ArgumentError)
222
+ lambda{@x.decrement!(f)}.should raise_error(ArgumentError)
223
+ end
224
+ end
225
+ end
226
+
227
+ context "redis commands" do
228
+ class TestCommands < Rhoconnect::Model
229
+ field :foo
230
+ list :bar
231
+ set :sloppy
232
+ end
233
+
234
+ before(:each) do
235
+ @redisMock = RSpec::Mocks::Mock.new
236
+ @x = TestCommands.with_key(1)
237
+ @x.stub!(:redis).and_return(@redisMock)
238
+ end
239
+
240
+ it "should send GET on field read" do
241
+ @redisMock.should_receive(:[]).with('test_commands:1:foo')
242
+ @x.foo
243
+ end
244
+
245
+ it "should send SET on field write" do
246
+ @redisMock.should_receive(:[]=).with('test_commands:1:foo', 'bar')
247
+ @x.foo = 'bar'
248
+ end
249
+
250
+ it "should send RPUSH on list <<" do
251
+ @redisMock.should_receive(:rpush).with('test_commands:1:bar', 'bar')
252
+ @x.bar << 'bar'
253
+ end
254
+
255
+ it "should send SADD on set <<" do
256
+ @redisMock.should_receive(:sadd).with('test_commands:1:sloppy', 'bar')
257
+ @x.sloppy << 'bar'
258
+ end
259
+
260
+ it "should delete separate fields" do
261
+ @redisMock.should_receive(:del).with('test_commands:1:foo')
262
+ @x.delete :foo
263
+ end
264
+
265
+ it "should delete all field" do
266
+ @redisMock.should_receive(:del).with('test_commands:1:foo')
267
+ @redisMock.should_receive(:del).with('test_commands:1:rho__id')
268
+ @redisMock.should_receive(:del).with('test_commands:1:bar')
269
+ @redisMock.should_receive(:del).with('test_commands:1:sloppy')
270
+ @x.delete
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__),'perf_spec_helper')
2
+
3
+ describe "BulkData Performance" do
4
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => false do
5
+ before(:each) do
6
+ basedir = File.join(File.dirname(__FILE__),'..','apps','rhotestapp')
7
+ Rhoconnect.bootstrap(basedir) do |rhoconnect|
8
+ rhoconnect.vendor_directory = File.join(basedir,'..','vendor')
9
+ end
10
+ end
11
+
12
+ after(:each) do
13
+ delete_data_directory
14
+ end
15
+
16
+ it "should generate sqlite bulk data for 1000 objects (6000 attributes)" do
17
+ start = start_timer
18
+ @data = get_test_data(1000)
19
+ start = lap_timer('generate data',start)
20
+ set_state('test_db_storage' => @data)
21
+ start = lap_timer('set_state masterdoc',start)
22
+ data = BulkData.create(:name => bulk_data_docname(@a.id,@u.id),
23
+ :state => :inprogress,
24
+ :app_id => @a.id,
25
+ :user_id => @u.id,
26
+ :sources => [@s_fields[:name]])
27
+ BulkDataJob.perform("data_name" => data.name)
28
+ lap_timer('BulkDataJob.perform duration',start)
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'support', 'shared_examples')
3
+ require 'ffaker'
4
+
5
+ def get_test_data(num=1000)
6
+ file = File.join("spec","testdata","#{num}-data.txt")
7
+ data = nil
8
+ if File.exists?(file)
9
+ data = open(file, 'r') {|f| Marshal.load(f)}
10
+ else
11
+ data = generate_fake_data(num)
12
+ f = File.new(file, 'w')
13
+ f.write Marshal.dump(data)
14
+ f.close
15
+ end
16
+ data
17
+ end
18
+
19
+ private
20
+
21
+ PREFIX = ["Account", "Administrative", "Advertising", "Assistant", "Banking", "Business Systems",
22
+ "Computer", "Distribution", "IT", "Electronics", "Environmental", "Financial", "General", "Head",
23
+ "Laboratory", "Maintenance", "Medical", "Production", "Quality Assurance", "Software", "Technical",
24
+ "Chief", "Senior"] unless defined? PREFIX
25
+ SUFFIX = ["Clerk", "Analyst", "Manager", "Supervisor", "Plant Manager", "Mechanic", "Technician", "Engineer",
26
+ "Director", "Superintendent", "Specialist", "Technologist", "Estimator", "Scientist", "Foreman", "Nurse",
27
+ "Worker", "Helper", "Intern", "Sales", "Mechanic", "Planner", "Recruiter", "Officer", "Superintendent",
28
+ "Vice President", "Buyer", "Production Supervisor", "Chef", "Accountant", "Executive"] unless defined? SUFFIX
29
+
30
+ def title
31
+ prefix = PREFIX[rand(PREFIX.length)]
32
+ suffix = SUFFIX[rand(SUFFIX.length)]
33
+
34
+ "#{prefix} #{suffix}"
35
+ end
36
+
37
+ def generate_fake_data(num=1000)
38
+ res = {}
39
+ num.times do |n|
40
+ res[n.to_s] = {
41
+ "FirstName" => Faker::Name.first_name,
42
+ "LastName" => Faker::Name.last_name,
43
+ "Email" => Faker::Internet.free_email,
44
+ "Company" => Faker::Company.name,
45
+ "JobTitle" => title,
46
+ "Phone1" => Faker::PhoneNumber.phone_number
47
+ }
48
+ end
49
+ res
50
+ end