rhoconnect 3.3.6 → 3.4.2

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 (152) hide show
  1. data/CHANGELOG.md +40 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +27 -25
  4. data/bench/benchapp/Gemfile +7 -27
  5. data/bench/benchapp/config.ru +9 -31
  6. data/bench/blobapp/Gemfile +7 -27
  7. data/bench/blobapp/config.ru +9 -29
  8. data/bench/lib/bench.rb +8 -1
  9. data/bench/lib/bench/test_data.rb +4 -1
  10. data/bench/scripts/blob_cud_script.rb +4 -0
  11. data/bench/scripts/cud_script.rb +7 -1
  12. data/bench/scripts/helpers.rb +1 -1
  13. data/bench/scripts/test_query_script.rb +20 -7
  14. data/bench/spec/bench_spec_helper.rb +3 -1
  15. data/bin/rhoconnect +22 -12
  16. data/commands/{commands/dtach_commands → dtach}/dtach_about.rb +0 -0
  17. data/commands/{commands/dtach_commands → dtach}/dtach_install.rb +0 -0
  18. data/commands/{commands/redis_commands → dtach}/redis_attach.rb +0 -0
  19. data/commands/execute.rb +14 -15
  20. data/commands/generators/update.rb +26 -0
  21. data/commands/{commands/redis_commands → redis}/redis_about.rb +0 -0
  22. data/commands/redis/redis_download.rb +13 -0
  23. data/commands/redis/redis_install.rb +26 -0
  24. data/commands/{commands/redis_commands → redis}/redis_make.rb +0 -0
  25. data/commands/{commands/redis_commands → redis}/redis_restart.rb +3 -2
  26. data/commands/{commands/redis_commands → redis}/redis_start.rb +0 -0
  27. data/commands/{commands/redis_commands → redis}/redis_startbg.rb +0 -0
  28. data/commands/{commands/redis_commands → redis}/redis_stop.rb +3 -2
  29. data/commands/{commands/rhoconnect → rhoconnect}/clean_start.rb +0 -0
  30. data/commands/{commands/rhoconnect → rhoconnect}/config.rb +7 -2
  31. data/commands/{commands/rhoconnect → rhoconnect}/create_user.rb +0 -0
  32. data/commands/{commands/rhoconnect → rhoconnect}/delete_device.rb +0 -0
  33. data/commands/{commands/rhoconnect → rhoconnect}/delete_user.rb +0 -0
  34. data/commands/{commands/rhoconnect → rhoconnect}/flushdb.rb +4 -4
  35. data/commands/{commands/rhoconnect → rhoconnect}/get_token.rb +0 -0
  36. data/commands/{commands/rhoconnect → rhoconnect}/reset.rb +0 -0
  37. data/commands/{commands/rhoconnect → rhoconnect}/reset_refresh.rb +0 -0
  38. data/commands/{commands/rhoconnect → rhoconnect}/restart.rb +0 -0
  39. data/commands/{commands/rhoconnect → rhoconnect}/secret.rb +0 -0
  40. data/commands/{commands/rhoconnect → rhoconnect}/set_admin_password.rb +0 -0
  41. data/commands/{commands/rhoconnect → rhoconnect}/spec.rb +0 -0
  42. data/commands/rhoconnect/start.rb +27 -0
  43. data/commands/{commands/rhoconnect → rhoconnect}/startbg.rb +0 -0
  44. data/commands/{commands/rhoconnect → rhoconnect}/startdebug.rb +2 -2
  45. data/commands/{commands/rhoconnect → rhoconnect}/stop.rb +3 -4
  46. data/commands/{commands/rhoconnect → rhoconnect}/version.rb +0 -0
  47. data/commands/{commands/rhoconnect → rhoconnect}/web.rb +0 -0
  48. data/commands/rhoconnect_attach/attach.rb +10 -0
  49. data/commands/rhoconnect_console/console.rb +16 -0
  50. data/commands/{commands/rhoconnect → rhoconnect_console}/console_helper.rb +0 -0
  51. data/commands/{commands/rhoconnect → rhoconnect_war}/war.rb +0 -0
  52. data/commands/{commands/redis_commands → utilities}/redis_runner.rb +22 -19
  53. data/commands/utilities/utilities.rb +6 -0
  54. data/doc/benchmarks.txt +2 -2
  55. data/doc/bulk-sync.txt +12 -1
  56. data/doc/client-java.txt +3 -3
  57. data/doc/client-objc.txt +1 -1
  58. data/doc/client.txt +5 -5
  59. data/doc/command-line.txt +80 -135
  60. data/doc/deploying.txt +119 -12
  61. data/doc/extending-rhoconnect-server.txt +1 -1
  62. data/doc/heroku-addon.txt +119 -23
  63. data/doc/install.txt +101 -39
  64. data/doc/java-plugin.txt +2 -2
  65. data/doc/licensing.txt +1 -1
  66. data/doc/plugin-intro.txt +3 -1
  67. data/doc/preparing-production.txt +4 -4
  68. data/doc/public/cli.txt +2 -2
  69. data/doc/push-backend-setup.txt +11 -1
  70. data/doc/push-client-setup.txt +72 -2
  71. data/doc/push-server-setup.txt +129 -8
  72. data/doc/rails-plugin.txt +245 -40
  73. data/doc/rest-api.txt +10 -6
  74. data/doc/rhoconnect-calculator.txt +237 -0
  75. data/doc/rhoconnect-redis-stack.txt +35 -0
  76. data/doc/session-and-configuration.txt +24 -0
  77. data/doc/settings.txt +51 -41
  78. data/doc/source-adapters.txt +45 -45
  79. data/doc/stats-middleware.txt +2 -2
  80. data/doc/supported-platforms.txt +6 -6
  81. data/doc/testing.txt +2 -2
  82. data/doc/tutorial.txt +63 -63
  83. data/examples/simple/Gemfile +7 -35
  84. data/examples/simple/config.ru +8 -26
  85. data/examples/simple/sources/product.rb +6 -6
  86. data/generators/rhoconnect.rb +5 -0
  87. data/generators/templates/application/Gemfile +7 -37
  88. data/generators/templates/application/Rakefile +8 -0
  89. data/generators/templates/application/config.ru +12 -31
  90. data/generators/templates/application/rcgemfile +44 -0
  91. data/generators/templates/application/settings/settings.yml +7 -5
  92. data/install.sh +4 -4
  93. data/installer/unix-like/create_texts.rb +7 -2
  94. data/installer/unix-like/rho_connect_install_constants.rb +2 -2
  95. data/installer/unix-like/rho_connect_install_installers.rb +1 -16
  96. data/lib/rhoconnect.rb +51 -38
  97. data/lib/rhoconnect/api/app/query.rb +4 -1
  98. data/lib/rhoconnect/api/app/search.rb +4 -1
  99. data/lib/rhoconnect/api/client/list_client_docs.rb +3 -1
  100. data/lib/rhoconnect/api/user/ping.rb +1 -5
  101. data/lib/rhoconnect/application/init.rb +43 -0
  102. data/lib/rhoconnect/async.rb +11 -6
  103. data/lib/rhoconnect/client_sync.rb +30 -37
  104. data/lib/rhoconnect/document.rb +4 -0
  105. data/lib/rhoconnect/graph_helper.rb +74 -56
  106. data/lib/rhoconnect/middleware/helpers.rb +4 -0
  107. data/lib/rhoconnect/ping.rb +1 -0
  108. data/lib/rhoconnect/ping/gcm.rb +58 -0
  109. data/lib/rhoconnect/predefined_adapters/bench_adapter.rb +7 -1
  110. data/lib/rhoconnect/source.rb +70 -56
  111. data/lib/rhoconnect/source_sync.rb +33 -5
  112. data/lib/rhoconnect/store.rb +358 -110
  113. data/lib/rhoconnect/user.rb +8 -0
  114. data/lib/rhoconnect/utilities.rb +16 -14
  115. data/lib/rhoconnect/version.rb +1 -1
  116. data/lib/rhoconnect/web-console/models/client.js +1 -1
  117. data/lib/rhoconnect/web-console/public/UNVR67bold.ttf +0 -0
  118. data/lib/rhoconnect/web-console/public/bootstrap.css +6 -0
  119. data/lib/rhoconnect/web-console/public/logo.png +0 -0
  120. data/lib/rhoconnect/web-console/server.rb +13 -11
  121. data/lib/rhoconnect/web-console/templates/index.erb +5 -5
  122. data/lib/rhoconnect/web-console/templates/jqplot.erb +1 -0
  123. data/lib/rhoconnect/web-console/views/doc.js +0 -4
  124. data/lib/rhoconnect/web-console/views/home.js +2 -1
  125. data/lib/rhoconnect/web-console/views/new_ping.js +11 -6
  126. data/lib/rhoconnect/web-console/views/stats.js +9 -5
  127. data/rhoconnect.gemspec +6 -4
  128. data/spec/api/app/fast_update_spec.rb +2 -2
  129. data/spec/api/source/get_source_params_spec.rb +1 -0
  130. data/spec/apps/rhotestapp/settings/settings.yml +5 -5
  131. data/spec/client_sync_spec.rb +3 -14
  132. data/spec/perf/perf_spec_helper.rb +11 -7
  133. data/spec/perf/store_perf_spec.rb +88 -11
  134. data/spec/ping/gcm_spec.rb +99 -0
  135. data/spec/server/server_spec.rb +7 -0
  136. data/spec/server/stats_spec.rb +9 -2
  137. data/spec/source_sync_spec.rb +29 -0
  138. data/spec/spec_helper.rb +40 -38
  139. data/spec/stats/record_spec.rb +18 -9
  140. data/spec/store_spec.rb +128 -19
  141. data/spec/testdata/10000-data.txt +0 -0
  142. data/spec/testdata/5-data.txt +0 -0
  143. data/spec/testdata/5000-data.txt +0 -0
  144. data/tasks/jasmine.rake +1 -0
  145. data/tasks/redis.rake +16 -13
  146. metadata +71 -39
  147. data/commands/commands/redis_commands/redis_download.rb +0 -33
  148. data/commands/commands/redis_commands/redis_install.rb +0 -26
  149. data/commands/commands/rhoconnect/attach.rb +0 -8
  150. data/commands/commands/rhoconnect/console.rb +0 -15
  151. data/commands/commands/rhoconnect/start.rb +0 -18
  152. data/commands/utilities/dtach_installed.rb +0 -10
@@ -33,16 +33,20 @@ def title
33
33
  "#{prefix} #{suffix}"
34
34
  end
35
35
 
36
- def generate_fake_data(num=1000)
36
+ def generate_fake_data(num=1000,unique=false)
37
37
  res = {}
38
38
  num.times do |n|
39
+ unique_prefix = ""
40
+ if unique
41
+ unique_prefix = "#{n}-#{Time.now.to_s}"
42
+ end
39
43
  res[n.to_s] = {
40
- "FirstName" => Faker::Name.first_name,
41
- "LastName" => Faker::Name.last_name,
42
- "Email" => Faker::Internet.free_email,
43
- "Company" => Faker::Company.name,
44
- "JobTitle" => title,
45
- "Phone1" => Faker::PhoneNumber.phone_number
44
+ "FirstName" => Faker::Name.first_name + unique_prefix,
45
+ "LastName" => Faker::Name.last_name + unique_prefix,
46
+ "Email" => Faker::Internet.free_email + unique_prefix,
47
+ "Company" => Faker::Company.name + unique_prefix,
48
+ "JobTitle" => title + unique_prefix,
49
+ "Phone1" => Faker::PhoneNumber.phone_number + unique_prefix
46
50
  }
47
51
  end
48
52
  res
@@ -2,25 +2,102 @@ require File.join(File.dirname(__FILE__),'perf_spec_helper')
2
2
 
3
3
  describe "Rhoconnect Performance" do
4
4
  it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => false do
5
- it "should process get/put for 1000 records (6000 elements)" do
6
- @data = get_test_data(1000)
5
+ it "should process get/put/delete for 10000 records (60000 elements)" do
6
+ @data = get_test_data(10000)
7
7
  start = start_timer
8
8
  Store.put_data('mdoc',@data).should == true
9
9
  start = lap_timer('put_data duration',start)
10
10
  Store.get_data('mdoc').should == @data
11
- lap_timer('get_data duration',start)
11
+ start = lap_timer('get_data duration',start)
12
+ Store.rename('mdoc','mdoc_copy')
13
+ start = lap_timer("rename doc duration", start)
14
+ Store.clone('mdoc_copy','mdoc_copy1')
15
+ start = lap_timer("clone doc duration", start)
16
+ Store.delete_objects('mdoc_copy',@data.keys[0,2])
17
+ start = lap_timer("delete_objects duration", start)
18
+ Store.delete_data('mdoc_copy1',@data)
19
+ start = lap_timer("delete_data duration", start)
12
20
  end
13
-
14
- it "should process single attribute update 1000-record doc" do
15
- @data = get_test_data(1000)
16
- @data1 = get_test_data(1000)
21
+
22
+ it "should process update_objects in a set of 10000 records (60000 elements)" do
23
+ @data = get_test_data(10000)
24
+ updated_key = @data.keys[21]
25
+ @update_data = {}
26
+ @update_data[updated_key] = @data[updated_key].clone
27
+ @update_data[updated_key]['Phone'] = 'updated phone SADD'
28
+ @update_data[updated_key]['Phone1'] = 'updated phone SREM and SADD'
29
+ expected = @data.clone
30
+ expected.merge!(@update_data)
31
+
32
+ Store.put_data('mdoc',@data).should == true
33
+ start = start_timer
34
+ Store.update_objects('mdoc', @update_data)
35
+ lap_timer("update_objects duration", start)
36
+ Store.get_data('mdoc').should == expected
37
+ end
38
+
39
+ it "should process 1000 update_objects in a set of 10000 records (60000 elements)" do
40
+ @data = get_test_data(10000)
41
+ updated_keys = @data.keys[2001..3000]
42
+ @update_data = {}
43
+ updated_keys.each do |updated_key|
44
+ @update_data[updated_key] = @data[updated_key].clone
45
+ @update_data[updated_key]['Phone'] = 'updated phone SADD'
46
+ @update_data[updated_key]['Phone1'] = 'updated phone SREM and SADD'
47
+ end
48
+ expected = @data.dup
49
+ expected.merge!(@update_data)
50
+
51
+ Store.put_data('mdoc',@data).should == true
52
+ start = start_timer
53
+ Store.update_objects('mdoc', @update_data)
54
+ lap_timer("update_objects duration", start)
55
+
56
+ Store.get_data('mdoc').should == expected
57
+ end
58
+
59
+ it "should process single attribute diff for 10000-record doc" do
60
+ @data = get_test_data(10000)
61
+ @data1 = get_test_data(10000)
17
62
  @data1['950']['Phone1'] = 'This is changed'
18
63
  expected = {'950' => {'Phone1' => 'This is changed'}}
19
- Store.put_data('mdoc',@data).should == true
20
- Store.put_data('cdoc',@data1).should == true
64
+ Store.put_data(@s.docname(:md),@data1).should == true
65
+ Store.put_data(@c.docname(:cd),@data).should == true
66
+ start = start_timer
67
+ cs = ClientSync.new(@s,@c)
68
+ token,progress_count,total_count,res = cs.send_new_page
69
+ lap_timer('compute_page duration', start)
70
+ Store.get_data(@c.docname(:page)).should == expected
71
+ res['insert'].should == expected
72
+ res['delete'].should == {'950' => {'Phone1' => @data['950']['Phone1']}}
73
+ end
74
+
75
+ it "should process full-sync for 5000-record doc" do
76
+ @data = get_test_data(5000)
77
+ Store.put_data(@s.docname(:md),@data).should == true
78
+ start = start_timer
79
+ cs = ClientSync.new(@s,@c,5000)
80
+ token,progress_count,total_count,res = cs.send_new_page
81
+ lap_timer('compute_page duration', start)
82
+ Store.get_data(@c.docname(:page)).should == @data
83
+ res['insert'].should == @data
84
+ res['delete'].should == nil
85
+ end
86
+
87
+ it "should process worst-case sync scenario there every attrib of every object is changed for 5000-record doc" do
88
+ @data = generate_fake_data(5000,true)
89
+ sleep(1.5)
90
+ @data1 = generate_fake_data(5000,true)
91
+ Store.put_data(@s.docname(:md),@data).should == true
92
+ Store.put_data(@c.docname(:cd),@data1).should == true
21
93
  start = start_timer
22
- Store.get_diff_data('mdoc','cdoc').should == expected
23
- lap_timer('get_diff_data duration', start)
94
+ cs = ClientSync.new(@s,@c,5000)
95
+ token,progress_count,total_count,res = cs.send_new_page
96
+ lap_timer('compute_page duration', start)
97
+ Store.get_data(@c.docname(:page)).should == @data
98
+ Store.get_data(@c.docname(:cd)).should == Store.get_data(@s.docname(:md))
99
+ res['insert'].should == @data
100
+ res['delete'].should == @data1
24
101
  end
25
102
  end
26
103
 
@@ -0,0 +1,99 @@
1
+ require File.join(File.dirname(__FILE__),'..','spec_helper')
2
+
3
+ describe "Ping Android GCM" do
4
+ it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => false do
5
+
6
+ before(:each) do
7
+ @params = {"device_pin" => @c.device_pin,
8
+ "sources" => [@s.name], "message" => 'hello world',
9
+ "vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3'}
10
+ @response = mock('response')
11
+ Rhoconnect.settings[:gcm_api_key] = 'validkey'
12
+ end
13
+
14
+ it "should ping gcm successfully" do
15
+ result = 'id=0:34234234134254%abc123\n'
16
+ @response.stub!(:code).and_return(200)
17
+ @response.stub!(:body).and_return(result)
18
+ @response.stub!(:headers).and_return({})
19
+ @response.stub!(:return!).and_return(@response)
20
+ setup_post_yield(@response)
21
+ Gcm.ping(@params).body.should == result
22
+ end
23
+
24
+ it "should raise error on missing gcm_api_key setting" do
25
+ key = Rhoconnect.settings[:gcm_api_key].dup
26
+ Rhoconnect.settings[:gcm_api_key] = nil
27
+ lambda { Gcm.ping(@params) }.should raise_error(
28
+ Gcm::InvalidApiKey, 'Missing `:gcm_api_key:` option in settings/settings.yml'
29
+ )
30
+ Rhoconnect.settings[:gcm_api_key] = key
31
+ end
32
+
33
+ it "should ping gcm with 503 connection error" do
34
+ error = 'Connection refused'
35
+ @response.stub!(:body).and_return(error)
36
+ RestClient.stub!(:post).and_return { raise RestClient::Exception.new(@response,503) }
37
+ Gcm.should_receive(:log).twice
38
+ lambda { Gcm.ping(@params) }.should raise_error(RestClient::Exception)
39
+ end
40
+
41
+ it "should ping gcm with 200 error message" do
42
+ error = 'Error=QuotaExceeded'
43
+ @response.stub!(:code).and_return(200)
44
+ @response.stub!(:body).and_return(error)
45
+ @response.stub!(:headers).and_return(nil)
46
+ setup_post_yield(@response)
47
+ Gcm.should_receive(:log).twice
48
+ lambda { Gcm.ping(@params) }.should raise_error(Gcm::GCMPingError, "GCM ping error: QuotaExceeded")
49
+ end
50
+
51
+ it "should fail to ping with bad authentication" do
52
+ error = 'Error=BadAuthentication'
53
+ @response.stub!(:code).and_return(403)
54
+ @response.stub!(:body).and_return(error)
55
+ @response.stub!(:headers).and_return({})
56
+ setup_post_yield(@response)
57
+ Gcm.should_receive(:log).twice
58
+ lambda { Gcm.ping(@params) }.should raise_error(
59
+ Gcm::InvalidApiKey, "Invalid GCM api key. Obtain new api key from GCM service."
60
+ )
61
+ end
62
+
63
+ it "should ping gcm with 401 error message" do
64
+ @response.stub!(:code).and_return(401)
65
+ @response.stub!(:body).and_return('')
66
+ setup_post_yield(@response)
67
+ Gcm.should_receive(:log).twice
68
+ lambda { Gcm.ping(@params) }.should raise_error(
69
+ Gcm::InvalidApiKey, "Invalid GCM api key. Obtain new api key from GCM service."
70
+ )
71
+ end
72
+
73
+ it "should compute gcm_message" do
74
+ expected = {
75
+ 'registration_ids' => [@c.device_pin],
76
+ 'collapse_key' => "RAND_KEY",
77
+ 'data' => {
78
+ 'do_sync' => @s.name,
79
+ 'alert' => "hello world",
80
+ 'vibrate' => '5',
81
+ 'sound' => "hello.mp3"
82
+ }
83
+ }
84
+ actual = Gcm.gcm_message(@params)
85
+ actual['collapse_key'] = "RAND_KEY" unless actual['collapse_key'].nil?
86
+ actual.should == expected
87
+ end
88
+
89
+ it "should trim empty or nil params from gcm_message" do
90
+ expected = {'registration_ids' => [@c.device_pin], 'collapse_key' => "RAND_KEY",
91
+ 'data' => {'vibrate' => '5', 'do_sync' => '', 'sound' => "hello.mp3"} }
92
+ params = {"device_pin" => @c.device_pin,
93
+ "sources" => [], "message" => '', "vibrate" => '5', "sound" => 'hello.mp3'}
94
+ actual = Gcm.gcm_message(params)
95
+ actual['collapse_key'] = "RAND_KEY" unless actual['collapse_key'].nil?
96
+ actual.should == expected
97
+ end
98
+ end
99
+ end
@@ -382,6 +382,8 @@ describe "Server" do
382
382
  get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}", {}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
383
383
  last_response.should be_ok
384
384
  token = @c.get_value(:page_token)
385
+ last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
386
+ last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 2.to_s
385
387
  JSON.parse(last_response.body).should == [{'version'=>ClientSync::SYNC_VERSION},{"token"=>token},
386
388
  {"count"=>2}, {"progress_count"=>0}, {"total_count"=>2},{'insert'=>data}]
387
389
 
@@ -391,6 +393,8 @@ describe "Server" do
391
393
  get "/app/#{Rhoconnect::API_VERSION}/#{@s.name}",{:token => token}, {Rhoconnect::CLIENT_ID_HEADER => @c.id}
392
394
  last_response.should be_ok
393
395
  token = @c.get_value(:page_token)
396
+ last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
397
+ last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 2.to_s
394
398
  JSON.parse(last_response.body).should == [{'version'=>ClientSync::SYNC_VERSION},{"token"=>token},
395
399
  {"count"=>2}, {"progress_count"=>0}, {"total_count"=>0},{'delete'=>data}]
396
400
  end
@@ -402,8 +406,11 @@ describe "Server" do
402
406
  params = {:client_id => @c.id,:sources => sources,:search => {'name' => 'iPhone'},
403
407
  :version => ClientSync::VERSION}
404
408
  get "/api/application/search",params
409
+ last_response.headers['Warning'].index('deprecated').should_not == nil
405
410
  last_response.content_type.should =~ /application\/json/
406
411
  token = @c.get_value(:search_token)
412
+ last_response.headers[Rhoconnect::PAGE_TOKEN_HEADER].should == token
413
+ last_response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER].should == 1.to_s
407
414
  JSON.parse(last_response.body).should == [[{'version'=>ClientSync::SYNC_VERSION},{'token'=>token},
408
415
  {'source'=>sources[0][:name]},{'count'=>1},{'insert'=>{'1'=>@product1}}]]
409
416
  end
@@ -26,7 +26,14 @@ describe "Middleware" do
26
26
  end
27
27
 
28
28
  it "should compute http average" do
29
- Time.stub!(:now).and_return { @now += 0.3; @now }
29
+ @incr = 0
30
+ Time.stub!(:now).and_return do
31
+ if @incr > 0
32
+ @now += 0.3
33
+ @incr -= 1
34
+ end
35
+ @now
36
+ end
30
37
  env = {
31
38
  'rack.request.query_hash' => {
32
39
  'source_name' => 'SampleAdapter'
@@ -34,7 +41,7 @@ describe "Middleware" do
34
41
  'REQUEST_METHOD' => 'GET',
35
42
  'PATH_INFO' => '/api/application/query'
36
43
  }
37
- 10.times { @middleware_new_routes.call(env) }
44
+ 10.times { @incr = 3; @middleware_new_routes.call(env) }
38
45
  metric = 'http:GET:/api/application/query:SampleAdapter'
39
46
  Rhoconnect::Stats::Record.key(metric).should == "stat:#{metric}"
40
47
 
@@ -130,6 +130,35 @@ describe "SourceSync" do
130
130
  @ss.process_query
131
131
  end
132
132
  end
133
+
134
+ describe "push_notify" do
135
+ it "should do push_notify for source after push_objects if enabled" do
136
+ @s.push_notify = 'true'
137
+ data = {'1' => @product1, '2' => @product2, '3' => @product3}
138
+ params = {'user_id'=>["testuser"], 'sources'=>["SampleAdapter"]}
139
+ PingJob.should_receive(:perform).once.with(params)
140
+ @ss.push_objects(data)
141
+ end
142
+
143
+ it "should do push_notify for source after push_deletes if enabled" do
144
+ @s.push_notify = 'true'
145
+ u2 = User.create(:login => 'user2')
146
+ @a.users << u2.id
147
+ data = {'1' => @product1, '2' => @product2, '3' => @product3}
148
+ params = {'user_id'=>["testuser"], 'sources'=>["SampleAdapter"]}
149
+ PingJob.should_receive(:perform).once.with(params)
150
+ @ss.push_deletes(data)
151
+ end
152
+
153
+ it "should not do push_notify for source by default" do
154
+ @s.partition = :app
155
+ u2 = User.create(:login => 'user2')
156
+ @a.users << u2.id
157
+ data = {'1' => @product1}
158
+ PingJob.should_receive(:perform).never
159
+ @ss.fast_delete(data)
160
+ end
161
+ end
133
162
 
134
163
  describe "create" do
135
164
  it "should do create where adapter.create returns nil" do
data/spec/spec_helper.rb CHANGED
@@ -4,23 +4,25 @@ require 'webmock/rspec'
4
4
  require 'rspec/autorun' # Required for Rcov to run with rspec '~> 2.8.0'
5
5
  if RUBY_VERSION =~ /1.9/ || defined?(JRUBY_VERSION)
6
6
  require 'simplecov'
7
- SimpleCov.start
7
+ SimpleCov.start do
8
+ add_filter '/spec/'
9
+ end
8
10
  end
9
11
 
10
12
  # all specs are Async'd in new ruby
11
13
  if RUBY_VERSION =~ /1.9/ and not defined?(JRUBY_VERSION)
12
14
  require 'eventmachine'
13
15
  require 'fiber'
14
-
16
+
15
17
  Thread.abort_on_exception = true
16
-
18
+
17
19
  module RSpec
18
20
  module Core
19
21
  class ExampleGroup
20
-
22
+
21
23
  class << self
22
24
  alias_method :run_alias, :run
23
-
25
+
24
26
  def run(reporter)
25
27
  if EM.reactor_running?
26
28
  run_alias reporter
@@ -50,16 +52,16 @@ Dir["#{SPEC_PATH}/support/**/*.rb"].each { |f| require f }
50
52
 
51
53
  ENV['RACK_ENV'] = 'test'
52
54
  ERROR = '0_broken_object_id' unless defined? ERROR
53
-
55
+
54
56
  module TestHelpers
55
57
  def get_testapp_path
56
58
  File.expand_path(File.join(File.dirname(__FILE__),'apps','rhotestapp'))
57
59
  end
58
-
60
+
59
61
  def get_emptyapp_path
60
62
  File.expand_path(File.join(File.dirname(__FILE__),'apps','emptyapp'))
61
63
  end
62
-
64
+
63
65
  def do_post(url,params,headers = {})
64
66
  headers.merge!('CONTENT_TYPE'=>'application/json')
65
67
  post url, params.to_json, headers
@@ -69,7 +71,7 @@ module TestHelpers
69
71
  headers.merge!('CONTENT_TYPE'=>'application/json')
70
72
  put url, params.to_json, headers
71
73
  end
72
-
74
+
73
75
  def bulk_data_docname(app_id,user_id)
74
76
  if user_id == "*"
75
77
  File.join(app_id,app_id)
@@ -77,13 +79,13 @@ module TestHelpers
77
79
  File.join(app_id,user_id,user_id)
78
80
  end
79
81
  end
80
-
82
+
81
83
  def dump_db_data(store)
82
- puts "*"*50
84
+ puts "*"*50
83
85
  puts "DATA DUMP"
84
86
  puts "*"*50
85
87
  store.db.keys('*').sort.each do |key|
86
- next if not key =~ /md|cd/
88
+ next if not key =~ /md|cd/
87
89
  line = ""
88
90
  line << "#{key}: "
89
91
  type = store.db.type key
@@ -92,7 +94,7 @@ module TestHelpers
92
94
  line << "#{store.get_data(key).inspect}"
93
95
  else
94
96
  line << "#{store.db.smembers(key).inspect}"
95
- end
97
+ end
96
98
  else
97
99
  line << "#{store.db.get key}"
98
100
  end
@@ -100,22 +102,22 @@ module TestHelpers
100
102
  end
101
103
  puts "*"*50
102
104
  end
103
-
105
+
104
106
  def add_client_id(data)
105
107
  res = Marshal.load(Marshal.dump(data))
106
108
  res.each { |key,value| value['rhomobile.rhoclient'] = @c.id.to_s }
107
109
  end
108
110
 
109
111
  def add_error_object(data,error_message,error_name='wrongname')
110
- error = {'an_attribute'=>error_message,'name'=>error_name}
112
+ error = {'an_attribute'=>error_message,'name'=>error_name}
111
113
  data.merge!({ERROR=>error})
112
114
  data
113
115
  end
114
-
116
+
115
117
  def delete_data_directory
116
118
  FileUtils.rm_rf(Rhoconnect.data_directory)
117
119
  end
118
-
120
+
119
121
  def json_clone(data)
120
122
  JSON.parse(data.to_json)
121
123
  end
@@ -127,7 +129,7 @@ module TestHelpers
127
129
  RestClient.stub!(:post).and_yield(response)
128
130
  end
129
131
  end
130
-
132
+
131
133
  def set_state(state,append=false)
132
134
  state.each do |dockey,data|
133
135
  if data.is_a?(Hash) or data.is_a?(Array)
@@ -137,22 +139,22 @@ module TestHelpers
137
139
  end
138
140
  end
139
141
  end
140
-
142
+
141
143
  def set_zstate(state,assoc_key,append=false)
142
144
  state.each do |dockey,data|
143
145
  Store.put_zdata(dockey,assoc_key,data,append)
144
146
  end
145
147
  end
146
-
148
+
147
149
  def set_test_data(dockey,data,error_message=nil,error_name='wrongname')
148
150
  if error_message
149
- error = {'an_attribute'=>error_message,'name'=>error_name}
151
+ error = {'an_attribute'=>error_message,'name'=>error_name}
150
152
  data.merge!({ERROR=>error})
151
- end
153
+ end
152
154
  Store.put_data(dockey,data)
153
155
  data
154
156
  end
155
-
157
+
156
158
  def verify_result(result)
157
159
  result.keys.sort.each do |dockey|
158
160
  expected = result[dockey]
@@ -170,7 +172,7 @@ module TestHelpers
170
172
  end
171
173
  end
172
174
  end
173
-
175
+
174
176
  def verify_zresult(result)
175
177
  result.keys.sort.each do |dockey|
176
178
  expected = result[dockey]
@@ -183,25 +185,25 @@ module TestHelpers
183
185
  end
184
186
  end
185
187
  end
186
-
188
+
187
189
  def validate_db(bulk_data,data)
188
- validate_db_file(bulk_data.dbfile,bulk_data.sources[0, -1],data)
190
+ validate_db_file(bulk_data.dbfile,bulk_data.sources[0, -1],data)
189
191
  end
190
-
191
- def validate_db_file(dbfile,sources,data)
192
- db = DBAdapter.instance.get_connection(dbfile)
192
+
193
+ def validate_db_file(dbfile,sources,data)
194
+ db = DBAdapter.instance.get_connection(dbfile)
193
195
  sources.each do |source_name|
194
196
  s = Source.load(source_name,{:app_id => APP_NAME,:user_id => @u.login})
195
197
  return false unless validate_db_by_name(db,s,data[s.name])
196
- end
197
- true
198
+ end
199
+ true
198
200
  end
199
-
201
+
200
202
  def validate_db_by_name(db,s,data)
201
203
  db.execute("select source_id,name,sync_priority,partition,sync_type,source_attribs,
202
204
  metadata,schema,blob_attribs,associations,last_inserted_size, backend_refresh_time
203
205
  from sources where name='#{s.name}'").each do |row|
204
-
206
+
205
207
  return false if row[0].to_s != s.source_id.to_s
206
208
  return false if row[1] != s.name
207
209
  return false if row[2].to_s != s.priority.to_s
@@ -241,7 +243,7 @@ module TestHelpers
241
243
  end
242
244
  data.empty?
243
245
  end
244
-
246
+
245
247
  def get_attrib_counter(data)
246
248
  counter = {}
247
249
  data.each do |object_name,object|
@@ -251,7 +253,7 @@ module TestHelpers
251
253
  end
252
254
  BulkDataJob.refs_to_s(counter)
253
255
  end
254
-
256
+
255
257
  def mock_metadata_method(adapters, &block)
256
258
  adapters.each do |klass|
257
259
  klass.class_eval "def metadata; {'foo'=>'bar'}.to_json; end"
@@ -261,7 +263,7 @@ module TestHelpers
261
263
  klass.class_eval "def metadata; end"
262
264
  end
263
265
  end
264
-
266
+
265
267
  def mock_schema_method(adapters, &block)
266
268
  adapters.each do |klass|
267
269
  klass.class_eval 'def schema
@@ -296,7 +298,7 @@ module TestHelpers
296
298
  klass.class_eval "def schema; end"
297
299
  end
298
300
  end
299
-
301
+
300
302
  def unzip_file(file,file_dir)
301
303
  Zip::ZipFile.open(file) do |zip_file|
302
304
  zip_file.each do |f|
@@ -315,5 +317,5 @@ module TestHelpers
315
317
  BulkDataJob.perform(params)
316
318
  BulkDataJob.after_perform_x(params) if BulkData.is_exist?(params["data_name"])
317
319
  end
318
-
320
+
319
321
  end #TestHelpers