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,231 @@
1
+ require 'rubygems'
2
+ require 'webmock/rspec'
3
+ require 'rspec'
4
+ require 'rhoconnect'
5
+ include Rhoconnect
6
+ ENV['RACK_ENV'] = 'test'
7
+
8
+ ERROR = '0_broken_object_id' unless defined? ERROR
9
+
10
+ # Monkey patch to fix the following issue:
11
+ # /Library/Ruby/Gems/1.8/gems/rspec-core-2.5.1/lib/rspec/core/shared_example_group.rb:45:
12
+ # in `ensure_shared_example_group_name_not_taken': Shared example group '...' already exists (ArgumentError)
13
+ module RSpec
14
+ module Core
15
+ module SharedExampleGroup
16
+ private
17
+ def ensure_shared_example_group_name_not_taken(name)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ module TestHelpers
24
+ def get_testapp_path
25
+ File.expand_path(File.join(File.dirname(__FILE__),'apps','rhotestapp'))
26
+ end
27
+
28
+ def get_emptyapp_path
29
+ File.expand_path(File.join(File.dirname(__FILE__),'apps','emptyapp'))
30
+ end
31
+
32
+ def do_post(url,params)
33
+ post url, params.to_json, {'CONTENT_TYPE'=>'application/json'}
34
+ end
35
+
36
+ def bulk_data_docname(app_id,user_id)
37
+ if user_id == "*"
38
+ File.join(app_id,app_id)
39
+ else
40
+ File.join(app_id,user_id,user_id)
41
+ end
42
+ end
43
+
44
+ def dump_db_data(store)
45
+ puts "*"*50
46
+ puts "DATA DUMP"
47
+ puts "*"*50
48
+ store.db.keys('*').sort.each do |key|
49
+ next if not key =~ /md|cd/
50
+ line = ""
51
+ line << "#{key}: "
52
+ type = store.db.type key
53
+ if type == 'set'
54
+ if not key =~ /sources|clients|users/
55
+ line << "#{store.get_data(key).inspect}"
56
+ else
57
+ line << "#{store.db.smembers(key).inspect}"
58
+ end
59
+ else
60
+ line << "#{store.db.get key}"
61
+ end
62
+ puts line
63
+ end
64
+ puts "*"*50
65
+ end
66
+
67
+ def add_client_id(data)
68
+ res = Marshal.load(Marshal.dump(data))
69
+ res.each { |key,value| value['rhomobile.rhoclient'] = @c.id.to_s }
70
+ end
71
+
72
+ def add_error_object(data,error_message,error_name='wrongname')
73
+ error = {'an_attribute'=>error_message,'name'=>error_name}
74
+ data.merge!({ERROR=>error})
75
+ data
76
+ end
77
+
78
+ def delete_data_directory
79
+ FileUtils.rm_rf(Rhoconnect.data_directory)
80
+ end
81
+
82
+ def json_clone(data)
83
+ JSON.parse(data.to_json)
84
+ end
85
+
86
+ def set_state(state)
87
+ state.each do |dockey,data|
88
+ if data.is_a?(Hash) or data.is_a?(Array)
89
+ Store.put_data(dockey,data)
90
+ else
91
+ Store.put_value(dockey,data)
92
+ end
93
+ end
94
+ end
95
+
96
+ def set_test_data(dockey,data,error_message=nil,error_name='wrongname')
97
+ if error_message
98
+ error = {'an_attribute'=>error_message,'name'=>error_name}
99
+ data.merge!({ERROR=>error})
100
+ end
101
+ Store.put_data(dockey,data)
102
+ data
103
+ end
104
+
105
+ def verify_result(result)
106
+ result.keys.sort.each do |dockey|
107
+ expected = result[dockey]
108
+ begin
109
+ if expected.is_a?(Hash)
110
+ Store.get_data(dockey).should == expected
111
+ elsif expected.is_a?(Array)
112
+ Store.get_data(dockey,Array).should == expected
113
+ else
114
+ Store.get_value(dockey).should == expected
115
+ end
116
+ rescue RSpec::Expectations::ExpectationNotMetError => e
117
+ message = "\nVerifying `#{dockey}`\n\n" + e.to_s
118
+ Kernel::raise(RSpec::Expectations::ExpectationNotMetError.new(message))
119
+ end
120
+ end
121
+ end
122
+
123
+ def validate_db(bulk_data,data)
124
+ validate_db_file(bulk_data.dbfile,bulk_data.sources.members,data)
125
+ end
126
+
127
+ def validate_db_file(dbfile,sources,data)
128
+ db = DBAdapter.instance.get_connection(dbfile)
129
+ sources.each do |source_name|
130
+ s = Source.load(source_name,{:app_id => APP_NAME,:user_id => @u.login})
131
+ return false unless validate_db_by_name(db,s,data[s.name])
132
+ end
133
+ true
134
+ end
135
+
136
+ def validate_db_by_name(db,s,data)
137
+ db.execute("select source_id,name,sync_priority,partition,
138
+ sync_type,source_attribs,metadata,schema,blob_attribs,associations
139
+ from sources where name='#{s.name}'").each do |row|
140
+
141
+ return false if row[0].to_s != s.source_id.to_s
142
+ return false if row[1] != s.name
143
+ return false if row[2].to_s != s.priority.to_s
144
+ return false if row[3] != s.partition_type.to_s
145
+ return false if row[4] != s.sync_type.to_s
146
+ return false if row[5] != (s.schema ? "" : get_attrib_counter(data))
147
+ return false if row[6] != s.get_value(:metadata)
148
+ return false if row[7] != s.schema
149
+ return false if row[8] != s.blob_attribs
150
+ return false if row[9] != s.has_many
151
+ end
152
+
153
+ data = json_clone(data)
154
+ if s.schema
155
+ schema = JSON.parse(s.schema)
156
+ columns = ['object']
157
+ schema['property'].each do |key,value|
158
+ columns << key
159
+ end
160
+ db.execute("select #{columns.join(',')} from #{s.name}").each do |row|
161
+ obj = data[row[0]]
162
+ columns.each_index do |i|
163
+ next if i == 0
164
+ return false if row[i] != obj[columns[i]]
165
+ end
166
+ data.delete(row[0])
167
+ end
168
+ else
169
+ db.execute("select * from object_values where source_id=#{s.source_id}").each do |row|
170
+ object = data[row[2]]
171
+ return false if object.nil? or object[row[1]] != row[3] or row[0].to_s != s.source_id.to_s
172
+ object.delete(row[1])
173
+ data.delete(row[2]) if object.empty?
174
+ end
175
+ end
176
+ data.empty?
177
+ end
178
+
179
+ def get_attrib_counter(data)
180
+ counter = {}
181
+ data.each do |object_name,object|
182
+ object.each do |attrib,value|
183
+ counter[attrib] = counter[attrib] ? counter[attrib] + 1 : 1
184
+ end
185
+ end
186
+ BulkDataJob.refs_to_s(counter)
187
+ end
188
+
189
+ def mock_metadata_method(adapters, &block)
190
+ adapters.each do |klass|
191
+ klass.class_eval "def metadata; {'foo'=>'bar'}.to_json; end"
192
+ end
193
+ yield
194
+ adapters.each do |klass|
195
+ klass.class_eval "def metadata; end"
196
+ end
197
+ end
198
+
199
+ def mock_schema_method(adapters, &block)
200
+ adapters.each do |klass|
201
+ klass.class_eval 'def schema
202
+ {
203
+ "property" => {
204
+ "name" => "string",
205
+ "brand" => "string"
206
+ },
207
+ "version" => "1.0"
208
+ }.to_json
209
+ end'
210
+ end
211
+ yield
212
+ adapters.each do |klass|
213
+ klass.class_eval "def schema; end"
214
+ end
215
+ end
216
+
217
+ def unzip_file(file,file_dir)
218
+ Zip::ZipFile.open(file) do |zip_file|
219
+ zip_file.each do |f|
220
+ f_path = File.join(file_dir,f.name)
221
+ FileUtils.mkdir_p(File.dirname(f_path))
222
+ zip_file.extract(f, f_path) { true }
223
+ end
224
+ end
225
+ end
226
+
227
+ def get_sha1(str)
228
+ Digest::SHA1.hexdigest(str)
229
+ end
230
+
231
+ end #TestHelpers
@@ -0,0 +1,53 @@
1
+ require 'rhoconnect'
2
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
3
+ STATS_RECORD_RESOLUTION = 2 unless defined? STATS_RECORD_RESOLUTION
4
+ STATS_RECORD_SIZE = 8 unless defined? STATS_RECORD_SIZE
5
+
6
+ include Rhoconnect
7
+ include Rhoconnect::Stats
8
+
9
+ describe "Middleware" do
10
+
11
+ before(:each) do
12
+ @now = 10.0
13
+ Store.db.flushdb
14
+ app = mock('app')
15
+ app.stub!(:call)
16
+ @middleware_new_routes = Middleware.new(app)
17
+ Store.stub!(:lock).and_yield
18
+ end
19
+
20
+ it "should compute http average" do
21
+ Time.stub!(:now).and_return { @now += 0.3; @now }
22
+ env = {
23
+ 'rack.request.query_hash' => {
24
+ 'source_name' => 'SampleAdapter'
25
+ },
26
+ 'REQUEST_METHOD' => 'GET',
27
+ 'PATH_INFO' => '/api/application/query'
28
+ }
29
+ 10.times { @middleware_new_routes.call(env) }
30
+ metric = 'http:GET:/api/application/query:SampleAdapter'
31
+ Record.key(metric).should == "stat:#{metric}"
32
+
33
+ # FIXME:
34
+ # The conversion algorithm (float to string) currently checks two precisions.
35
+ # In Ruby 1.9, it tries 16 digits and if that's not enough it then uses 17.
36
+ # In 1.8, it's the same but with 15 and 16.
37
+ if RUBY_VERSION =~ /1.9/
38
+ Record.range(metric, 0, -1).should == [
39
+ "2.0,0.6000000000000014:12",
40
+ "2.0,0.6000000000000014:14",
41
+ "2.0,0.6000000000000014:16",
42
+ "2.0,0.6000000000000014:18"
43
+ ]
44
+ else
45
+ Record.range(metric, 0, -1).should == [
46
+ "2.0,0.600000000000002:12",
47
+ "2.0,0.600000000000002:14",
48
+ "2.0,0.600000000000002:16",
49
+ "2.0,0.600000000000002:18"
50
+ ]
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,92 @@
1
+ require 'rhoconnect'
2
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
3
+ STATS_RECORD_RESOLUTION = 2 unless defined? STATS_RECORD_RESOLUTION
4
+ STATS_RECORD_SIZE = 8 unless defined? STATS_RECORD_SIZE
5
+
6
+ include Rhoconnect
7
+ include Rhoconnect::Stats
8
+
9
+ describe "Record" do
10
+
11
+ before(:each) do
12
+ @now = 9
13
+ Store.db.flushdb
14
+ Store.stub!(:lock).and_yield
15
+ end
16
+
17
+ it "should add metric to the record and trim record size" do
18
+ Time.stub!(:now).and_return { @now += 1; @now }
19
+ 10.times { Record.add('foo') }
20
+ Store.db.zrange('stat:foo', 0, -1).should == ["2:12", "2:14", "2:16", "2:18"]
21
+ end
22
+
23
+ it "should add single record" do
24
+ Time.stub!(:now).and_return { @now += 1; @now }
25
+ Record.add('foo')
26
+ Store.db.zrange('stat:foo', 0, -1).should == ["1:10"]
27
+ end
28
+
29
+ it "should return type of metric" do
30
+ Record.add('foo')
31
+ Record.rtype('foo').should == 'zset'
32
+ end
33
+
34
+ it "should set string metric" do
35
+ Record.set_value('foo', 'bar')
36
+ Store.db.get('stat:foo').should == 'bar'
37
+ end
38
+
39
+ it "should get string metric" do
40
+ Store.db.set('stat:foo', 'bar')
41
+ Record.get_value('foo').should == 'bar'
42
+ end
43
+
44
+ it "should get keys" do
45
+ Record.add('foo')
46
+ Record.add('bar')
47
+ Record.keys.sort.should == ['bar','foo']
48
+ end
49
+
50
+ it "should add absolute metric value" do
51
+ Time.stub!(:now).and_return { @now += 1; @now }
52
+ time = 0
53
+ 4.times do
54
+ Record.save_average('foo',time)
55
+ time += 1
56
+ end
57
+ Store.db.zrange('stat:foo', 0, -1).should == ["2.0,1.0:10", "2.0,5.0:12"]
58
+ end
59
+
60
+ it "should update metric" do
61
+ Rhoconnect.stats = true
62
+ Time.stub!(:now).and_return { @now += 1; @now }
63
+ 4.times do
64
+ Record.update('foo') do
65
+ # something interesting
66
+ end
67
+ end
68
+ Store.db.zrange('stat:foo', 0, -1).should == ["1,1.0:14", "1,1.0:18", "1,1.0:20"]
69
+ Rhoconnect.stats = false
70
+ end
71
+
72
+ it "should get range of metric values" do
73
+ Time.stub!(:now).and_return { @now += 1; @now }
74
+ 10.times { Record.add('foo') }
75
+ Record.range('foo', 0, 1).should == ["2:12", "2:14"]
76
+ end
77
+
78
+ it "should reset metric" do
79
+ Time.stub!(:now).and_return { @now += 1; @now }
80
+ 10.times { Record.add('foo') }
81
+ Store.db.zrange('stat:foo', 0, -1).should == ["2:12", "2:14", "2:16", "2:18"]
82
+ Record.reset('foo')
83
+ Store.db.zrange('stat:foo', 0, -1).should == []
84
+ end
85
+
86
+ it "should reset all metrics" do
87
+ Record.add('foo')
88
+ Record.add('bar')
89
+ Record.reset_all
90
+ Store.db.keys('stat:*').should == []
91
+ end
92
+ end
@@ -0,0 +1,251 @@
1
+ require File.join(File.dirname(__FILE__),'spec_helper')
2
+ require File.join(File.dirname(__FILE__), 'support', 'shared_examples')
3
+
4
+ describe "Store" do
5
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
6
+ describe "store methods" do
7
+ it "should create db class method" do
8
+ Store.db.class.name.should match(/Redis/)
9
+ end
10
+
11
+ it "should set redis connection" do
12
+ Store.db = nil
13
+ Store.db = 'localhost:6379'
14
+ Store.db.client.host.should == 'localhost'
15
+ Store.db.client.port.should == 6379
16
+ end
17
+
18
+ it "should create default redis connection" do
19
+ Store.db = nil
20
+ Store.db.class.name.should match(/Redis/)
21
+ end
22
+
23
+ it "should assign redis to existing redis" do
24
+ Store.db = Redis.new(:timeout => 60)
25
+ Store.db.client.timeout.should == 60
26
+ end
27
+
28
+ it "should create redis connection based on ENV" do
29
+ ENV[REDIS_URL] = 'redis://localhost:6379'
30
+ Redis.should_receive(:connect).with(:url => 'redis://localhost:6379').and_return { Redis.new }
31
+ Store.db = nil
32
+ Store.db.should_not == nil
33
+ ENV.delete(REDIS_URL)
34
+ end
35
+
36
+ it "should add simple data to new set" do
37
+ Store.put_data(@s.docname(:md),@data).should == true
38
+ Store.get_data(@s.docname(:md)).should == @data
39
+ end
40
+
41
+ it "should set_data and get_data" do
42
+ Store.set_data('foo', @data)
43
+ Store.get_data('foo').should == @data
44
+ end
45
+
46
+ it "should put_data with simple data" do
47
+ data = { '1' => { 'hello' => 'world' } }
48
+ Store.put_data('mydata', data)
49
+ Store.get_data('mydata').should == data
50
+ end
51
+
52
+ it "should add simple array data to new set" do
53
+ @data = ['1','2','3']
54
+ Store.put_data(@s.docname(:md),@data).should == true
55
+ Store.get_data(@s.docname(:md),Array).sort.should == @data
56
+ end
57
+
58
+ it "should replace simple data to existing set" do
59
+ new_data,new_data['3'] = {},{'name' => 'Droid','brand' => 'Google'}
60
+ Store.put_data(@s.docname(:md),@data).should == true
61
+ Store.put_data(@s.docname(:md),new_data)
62
+ Store.get_data(@s.docname(:md)).should == new_data
63
+ end
64
+
65
+ it "should put_value and get_value" do
66
+ Store.put_value('foo','bar')
67
+ Store.get_value('foo').should == 'bar'
68
+ end
69
+
70
+ it "should incr a key" do
71
+ Store.incr('foo').should == 1
72
+ end
73
+
74
+ it "should decr a key" do
75
+ Store.set_value('foo', 10)
76
+ Store.decr('foo').should == 9
77
+ end
78
+
79
+ it "should return true/false if element ismember of a set" do
80
+ Store.put_data('foo',['a'])
81
+ Store.ismember?('foo','a').should == true
82
+
83
+ Store.ismember?('foo','b').should == false
84
+ end
85
+
86
+ it "should return attributes modified in doc2" do
87
+ Store.put_data(@s.docname(:md),@data).should == true
88
+ Store.get_data(@s.docname(:md)).should == @data
89
+
90
+ @product3['price'] = '59.99'
91
+ expected = { '3' => { 'price' => '59.99' } }
92
+ @data1,@data1['1'],@data1['2'],@data1['3'] = {},@product1,@product2,@product3
93
+
94
+ Store.put_data(@c.docname(:cd),@data1)
95
+ Store.get_data(@c.docname(:cd)).should == @data1
96
+ Store.get_diff_data(@s.docname(:md),@c.docname(:cd)).should == [expected,1]
97
+ end
98
+
99
+ it "should return attributes modified and missed in doc2" do
100
+ Store.put_data(@s.docname(:md),@data).should == true
101
+ Store.get_data(@s.docname(:md)).should == @data
102
+
103
+ @product2['price'] = '59.99'
104
+ expected = { '2' => { 'price' => '99.99' },'3' => @product3 }
105
+ @data1,@data1['1'],@data1['2'] = {},@product1,@product2
106
+
107
+ Store.put_data(@c.docname(:cd),@data1)
108
+ Store.get_data(@c.docname(:cd)).should == @data1
109
+ Store.get_diff_data(@c.docname(:cd),@s.docname(:md)).should == [expected,2]
110
+ end
111
+
112
+ it "should ignore reserved attributes" do
113
+ @newproduct = {
114
+ 'name' => 'iPhone',
115
+ 'brand' => 'Apple',
116
+ 'price' => '199.99',
117
+ 'id' => 1234,
118
+ 'attrib_type' => 'someblob'
119
+ }
120
+
121
+ @data1 = {'1'=>@newproduct,'2'=>@product2,'3'=>@product3}
122
+
123
+ Store.put_data(@s.docname(:md),@data1).should == true
124
+ Store.get_data(@s.docname(:md)).should == @data
125
+ end
126
+
127
+ it "should flash_data" do
128
+ Store.put_data(@s.docname(:md),@data)
129
+ Store.flash_data(@s.docname(:md))
130
+ Store.get_data(@s.docname(:md)).should == {}
131
+ end
132
+
133
+ it "should get_keys" do
134
+ expected = ["doc1:1:1:1:source1", "doc1:1:1:1:source2"]
135
+ Store.put_data(expected[0],@data)
136
+ Store.put_data(expected[1],@data)
137
+ Store.get_keys('doc1:1:1:1:*').sort.should == expected
138
+ end
139
+
140
+ if defined?(JRUBY_VERSION)
141
+ # FIXME:
142
+ it "should lock document" do
143
+ doc = "locked_data"
144
+ m_lock = Store.get_lock(doc)
145
+ t = Thread.new do
146
+ Store.db = Redis.new
147
+ t_lock = Store.get_lock(doc)
148
+ Store.put_data(doc,{'1'=>@product1},true)
149
+ Store.release_lock(doc,t_lock)
150
+ end
151
+ Store.put_data(doc,{'2'=>@product2},true)
152
+ Store.get_data(doc).should == {'2'=>@product2}
153
+ Store.release_lock(doc,m_lock)
154
+ t.join
155
+ m_lock = Store.get_lock(doc)
156
+ Store.get_data(doc).should == {'1'=>@product1,'2'=>@product2}
157
+ end
158
+ else
159
+ it "should lock document" do
160
+ doc = "locked_data"
161
+ m_lock = Store.get_lock(doc)
162
+ pid = Process.fork do
163
+ Store.db = Redis.new
164
+ t_lock = Store.get_lock(doc)
165
+ Store.put_data(doc,{'1'=>@product1},true)
166
+ Store.release_lock(doc,t_lock)
167
+ Process.exit(0)
168
+ end
169
+ Store.put_data(doc,{'2'=>@product2},true)
170
+ Store.get_data(doc).should == {'2'=>@product2}
171
+ Store.release_lock(doc,m_lock)
172
+ Process.waitpid(pid)
173
+ m_lock = Store.get_lock(doc)
174
+ Store.get_data(doc).should == {'1'=>@product1,'2'=>@product2}
175
+ end
176
+ end
177
+
178
+ it "should lock key for timeout" do
179
+ doc = "locked_data"
180
+ lock = Time.now.to_i+3
181
+ Store.db.set "lock:#{doc}", lock
182
+ Store.should_receive(:sleep).at_least(:once).with(1).and_return { sleep 1; Store.release_lock(doc,lock); }
183
+ Store.get_lock(doc,4)
184
+ end
185
+
186
+ it "should raise exception if lock expires" do
187
+ doc = "locked_data"
188
+ Store.get_lock(doc)
189
+ lambda { sleep 2; Store.get_lock(doc,4,true) }.should raise_error(StoreLockException,"Lock \"lock:locked_data\" expired before it was released")
190
+ end
191
+
192
+ it "should raise lock expires exception on global setting" do
193
+ doc = "locked_data"
194
+ Store.get_lock(doc)
195
+ Rhoconnect.raise_on_expired_lock = true
196
+ lambda { sleep 2; Store.get_lock(doc,4) }.should raise_error(StoreLockException,"Lock \"lock:locked_data\" expired before it was released")
197
+ Rhoconnect.raise_on_expired_lock = false
198
+ end
199
+
200
+ it "should acquire lock if it expires" do
201
+ doc = "locked_data"
202
+ Store.get_lock(doc)
203
+ sleep 2
204
+ Store.get_lock(doc,1).should > Time.now.to_i
205
+ end
206
+
207
+ it "should use global lock duration" do
208
+ doc = "locked_data"
209
+ Rhoconnect.lock_duration = 2
210
+ Store.get_lock(doc)
211
+ Store.should_receive(:sleep).exactly(3).times.with(1).and_return { sleep 1 }
212
+ Store.get_lock(doc)
213
+ Rhoconnect.lock_duration = nil
214
+ end
215
+
216
+ it "should lock document in block" do
217
+ doc = "locked_data"
218
+ Store.lock(doc,0) do
219
+ Store.put_data(doc,{'2'=>@product2})
220
+ Store.get_data(doc).should == {'2'=>@product2}
221
+ end
222
+ end
223
+
224
+ it "should create clone of set" do
225
+ set_state('abc' => @data)
226
+ Store.clone('abc','def')
227
+ verify_result('abc' => @data,'def' => @data)
228
+ end
229
+
230
+ it "should rename a key" do
231
+ set_state('key1' => @data)
232
+ Store.rename('key1','key2')
233
+ verify_result('key1' => {}, 'key2' => @data)
234
+ end
235
+
236
+ it "should not fail to rename if key doesn't exist" do
237
+ Store.rename('key1','key2')
238
+ Store.db.exists('key1').should be_false
239
+ Store.db.exists('key2').should be_false
240
+ end
241
+
242
+ it "should raise ArgumentError on put_data with invalid data" do
243
+ foobar = {'foo'=>'bar'}
244
+ expect {
245
+ Store.put_data('somedoc',{'foo'=>'bar'})
246
+ }.to raise_exception(ArgumentError, "Invalid value object: #{foobar['foo'].inspect}. Hash is expected.")
247
+ end
248
+
249
+ end
250
+ end
251
+ end