rhoconnect 4.0.4 → 5.1.1

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 (151) hide show
  1. checksums.yaml +5 -13
  2. data/CHANGELOG.md +54 -5
  3. data/CREDITS +219 -219
  4. data/Gemfile +2 -2
  5. data/Gemfile.lock +68 -79
  6. data/Rakefile +1 -2
  7. data/bench/benchapp/spec/models/ruby/mock_adapter_spec.rb +17 -17
  8. data/bench/benchapp/spec/models/ruby/queue_mock_adapter_spec.rb +17 -17
  9. data/bench/benchapp/spec/spec_helper.rb +3 -3
  10. data/bench/blobapp/spec/models/ruby/blob_adapter_spec.rb +17 -17
  11. data/bench/blobapp/spec/spec_helper.rb +3 -3
  12. data/bench/lib/bench/runner.rb +1 -69
  13. data/bench/lib/bench.rb +18 -18
  14. data/bench/spec/mock_adapter_spec.rb +54 -55
  15. data/bench/spec/mock_client_spec.rb +47 -48
  16. data/bench/spec/result_spec.rb +41 -44
  17. data/bench/spec/utils_spec.rb +24 -25
  18. data/commands/generators/app.rb +7 -5
  19. data/commands/generators/controller.rb +7 -5
  20. data/commands/generators/model.rb +7 -5
  21. data/commands/generators/source.rb +7 -5
  22. data/commands/parser.rb +1 -1
  23. data/commands/redis/redis_download.rb +1 -1
  24. data/doc/async-jobs.txt +9 -9
  25. data/doc/supported-platforms.txt +0 -2
  26. data/generators/rhoconnect.rb +92 -212
  27. data/generators/templates/application/rcgemfile +3 -3
  28. data/generators/templates/application/spec/application_controller_spec.rb +14 -16
  29. data/generators/templates/application/spec/js_spec.rb +20 -20
  30. data/generators/templates/application/spec/spec_helper.rb +1 -1
  31. data/generators/templates/source/controllers/ruby/controller_spec.rb +18 -19
  32. data/generators/templates/source/models/ruby/model_spec.rb +17 -17
  33. data/install.sh +10 -21
  34. data/installer/unix-like/rho_connect_install_constants.rb +5 -5
  35. data/installer/unix-like/rho_connect_install_installers.rb +4 -4
  36. data/installer/utils/constants.rb +6 -6
  37. data/installer/utils/nix_install_test.rb +29 -29
  38. data/installer/utils/package_upload/repos.rake +16 -26
  39. data/js-adapters/node.rb +4 -4
  40. data/js-adapters/node_channel.rb +4 -8
  41. data/lib/rhoconnect/db_adapter.rb +13 -13
  42. data/lib/rhoconnect/handler/changes/engine.rb +1 -1
  43. data/lib/rhoconnect/jobs/bulk_data_job.rb +29 -29
  44. data/lib/rhoconnect/license.rb +7 -7
  45. data/lib/rhoconnect/model/helpers/find_duplicates_on_update.rb +13 -13
  46. data/lib/rhoconnect/ping/apple.rb +4 -4
  47. data/lib/rhoconnect/server.rb +2 -2
  48. data/lib/rhoconnect/source.rb +2 -2
  49. data/lib/rhoconnect/store.rb +12 -6
  50. data/lib/rhoconnect/utilities.rb +2 -2
  51. data/lib/rhoconnect/version.rb +1 -1
  52. data/lib/rhoconnect.rb +6 -4
  53. data/rhoconnect.gemspec +5 -6
  54. data/spec/api/api_helper.rb +1 -1
  55. data/spec/api/app/fast_delete_spec.rb +22 -22
  56. data/spec/api/app/fast_insert_spec.rb +23 -23
  57. data/spec/api/app/fast_update_spec.rb +63 -63
  58. data/spec/api/app/push_deletes_spec.rb +11 -13
  59. data/spec/api/app/push_objects_spec.rb +39 -39
  60. data/spec/api/client/client_get_db_doc_spec.rb +29 -29
  61. data/spec/api/client/client_set_db_doc_spec.rb +11 -11
  62. data/spec/api/client/get_client_params_spec.rb +29 -29
  63. data/spec/api/client/list_client_docs_spec.rb +32 -34
  64. data/spec/api/client/reset_spec.rb +30 -30
  65. data/spec/api/readstate/set_refresh_time_spec.rb +43 -43
  66. data/spec/api/source/get_source_params_spec.rb +32 -34
  67. data/spec/api/source/list_sources_spec.rb +13 -13
  68. data/spec/api/source/update_source_params_spec.rb +19 -19
  69. data/spec/api/store/get_db_doc_spec.rb +27 -27
  70. data/spec/api/store/set_db_doc_spec.rb +38 -38
  71. data/spec/api/system/adapter_spec.rb +27 -29
  72. data/spec/api/system/get_license_info_spec.rb +11 -11
  73. data/spec/api/system/login_spec.rb +37 -37
  74. data/spec/api/system/reset_spec.rb +15 -15
  75. data/spec/api/system/stats_spec.rb +70 -71
  76. data/spec/api/user/create_user_spec.rb +37 -37
  77. data/spec/api/user/delete_client_spec.rb +7 -7
  78. data/spec/api/user/delete_user_spec.rb +62 -62
  79. data/spec/api/user/list_clients_spec.rb +24 -24
  80. data/spec/api/user/list_source_docs_spec.rb +29 -29
  81. data/spec/api/user/list_users_spec.rb +22 -22
  82. data/spec/api/user/ping_spec.rb +18 -18
  83. data/spec/api/user/show_user_spec.rb +10 -10
  84. data/spec/api/user/update_user_spec.rb +43 -43
  85. data/spec/api/user/user_get_db_doc_spec.rb +12 -12
  86. data/spec/api/user/user_set_db_doc_spec.rb +37 -37
  87. data/spec/api_token_spec.rb +8 -8
  88. data/spec/app_spec.rb +18 -17
  89. data/spec/apps/jstestapp/settings/settings.yml +2 -0
  90. data/spec/async_spec.rb +9 -11
  91. data/spec/bulk_data/bulk_data_spec.rb +120 -120
  92. data/spec/cli/cli_spec.rb +50 -53
  93. data/spec/client_spec.rb +105 -105
  94. data/spec/client_sync_spec.rb +529 -528
  95. data/spec/controllers/js_base_spec.rb +147 -141
  96. data/spec/doc/doc_spec.rb +51 -52
  97. data/spec/document_spec.rb +58 -58
  98. data/spec/dynamic_adapter_spec.rb +33 -36
  99. data/spec/generator/generator_spec.rb +76 -42
  100. data/spec/jobs/bulk_data_job_spec.rb +101 -102
  101. data/spec/jobs/ping_job_spec.rb +176 -177
  102. data/spec/jobs/source_job_spec.rb +24 -25
  103. data/spec/license_spec.rb +54 -55
  104. data/spec/models/js_base_spec.rb +121 -120
  105. data/spec/perf/bulk_data_perf_spec.rb +23 -24
  106. data/spec/perf/perf_spec_helper.rb +7 -7
  107. data/spec/perf/store_perf_spec.rb +139 -140
  108. data/spec/ping/apple_spec.rb +65 -65
  109. data/spec/ping/gcm_spec.rb +83 -84
  110. data/spec/ping/rhoconnect_push_spec.rb +52 -53
  111. data/spec/predefined_adapters/rho_internal_bench_adapter_controller_js_spec.rb +100 -101
  112. data/spec/predefined_adapters/rho_internal_js_bench_adapter_js_spec.rb +29 -31
  113. data/spec/read_state_spec.rb +24 -25
  114. data/spec/rhoconnect_spec.rb +7 -7
  115. data/spec/server/server_spec.rb +664 -662
  116. data/spec/server/stats_spec.rb +12 -12
  117. data/spec/source_adapter_spec.rb +124 -125
  118. data/spec/source_spec.rb +148 -149
  119. data/spec/source_sync_spec.rb +736 -736
  120. data/spec/spec_helper.rb +4 -5
  121. data/spec/stats/record_spec.rb +22 -21
  122. data/spec/store_orm_spec.rb +48 -48
  123. data/spec/store_spec.rb +428 -426
  124. data/spec/support/shared_examples.rb +5 -7
  125. data/spec/sync_states_spec.rb +67 -67
  126. data/spec/test_methods_spec.rb +121 -123
  127. data/spec/testdata/10000-data.txt +0 -0
  128. data/spec/testdata/5000-data.txt +0 -0
  129. data/spec/user_spec.rb +102 -102
  130. data/tasks/redis.rake +3 -3
  131. metadata +154 -195
  132. data/bench/benchapp/tmp/pids/passenger.9292.pid.lock +0 -0
  133. data/bench/benchapp/tmp/restart.txt +0 -0
  134. data/bench/blobapp/settings/license.key.bak +0 -2
  135. data/bench/blobapp/tmp/restart.txt +0 -0
  136. data/bench/lib/testdata/1-data.txt +0 -0
  137. data/bench/lib/testdata/10-data.txt +0 -0
  138. data/bench/lib/testdata/2-data.txt +0 -0
  139. data/bench/lib/testdata/250-data.txt +0 -0
  140. data/bench/lib/testdata/5-blob_data.txt +0 -0
  141. data/bench/lib/testdata/5-data.txt +0 -0
  142. data/bench/lib/testdata/50-data.txt +0 -0
  143. data/bench/lib/testdata/500-data.txt +0 -0
  144. data/doc/protocol.html +0 -1993
  145. data/spec/coverage/rcov/assets/0.2.3/jquery-1.3.2.min.js +0 -19
  146. data/spec/coverage/rcov/assets/0.2.3/jquery.tablesorter.min.js +0 -15
  147. data/spec/coverage/rcov/assets/0.2.3/print.css +0 -12
  148. data/spec/coverage/rcov/assets/0.2.3/rcov.js +0 -42
  149. data/spec/coverage/rcov/assets/0.2.3/screen.css +0 -270
  150. data/spec/coverage/rcov/index.html +0 -88
  151. data/spec/generator/generator_spec_helper.rb +0 -9
data/spec/store_spec.rb CHANGED
@@ -1,474 +1,476 @@
1
1
  require File.join(File.dirname(__FILE__),'spec_helper')
2
2
 
3
3
  describe "Store" do
4
- it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
5
- describe "store methods" do
6
- it "should create proper connection class" do
7
- Store.get_store(0).db.class.name.should match(/Redis/)
8
- end
4
+ include_examples "SharedRhoconnectHelper", :rhoconnect_data => true
9
5
 
10
- it "should create redis connection based on ENV" do
11
- ENV[REDIS_URL] = 'redis://localhost:6379'
12
- Redis.should_receive(:connect).with(:url => 'redis://localhost:6379', :thread_safe => true, :timeout => Rhoconnect.redis_timeout).exactly(5).times.and_return { Redis.new }
13
- Store.nullify
14
- Store.num_stores.should == 0
15
- Store.create
16
- Store.get_store(0).db.should_not == nil
17
- ENV.delete(REDIS_URL)
18
- end
6
+ describe "store methods" do
7
+ it "should create proper connection class" do
8
+ Store.get_store(0).db.class.name.should match(/Redis/)
9
+ end
19
10
 
20
- it "should create redis connection based on REDISTOGO_URL ENV" do
21
- ENV[REDISTOGO_URL] = 'redis://localhost:6379'
22
- Redis.should_receive(:connect).with(:url => 'redis://localhost:6379', :thread_safe => true, :timeout => Rhoconnect.redis_timeout).exactly(5).times.and_return { Redis.new }
23
- Store.nullify
24
- Store.create
25
- Store.get_store(0).db.should_not == nil
26
- ENV.delete(REDISTOGO_URL)
27
- end
11
+ it "should create redis connection based on ENV" do
12
+ ENV[REDIS_URL] = 'redis://localhost:6379'
13
+ Redis.should_receive(:connect).with(:url => 'redis://localhost:6379', :thread_safe => true, :timeout => Rhoconnect.redis_timeout).exactly(5).times.and_return { Redis.new }
14
+ Store.nullify
15
+ Store.num_stores.should == 0
16
+ Store.create
17
+ Store.get_store(0).db.should_not == nil
18
+ ENV.delete(REDIS_URL)
19
+ end
28
20
 
29
- it "should add simple data to new set" do
30
- Store.put_data(@s.docname(:md),@data).should == true
31
- Store.get_data(@s.docname(:md)).should == @data
32
- end
21
+ it "should create redis connection based on REDISTOGO_URL ENV" do
22
+ ENV[REDISTOGO_URL] = 'redis://localhost:6379'
23
+ Redis.should_receive(:connect).with(:url => 'redis://localhost:6379', :thread_safe => true, :timeout => Rhoconnect.redis_timeout).exactly(5).times.and_return { Redis.new }
24
+ Store.nullify
25
+ Store.create
26
+ Store.get_store(0).db.should_not == nil
27
+ ENV.delete(REDISTOGO_URL)
28
+ end
33
29
 
34
- it "should set_data and get_data" do
35
- Store.set_data('foo', @data)
36
- Store.get_data('foo').should == @data
37
- end
30
+ it "should add simple data to new set" do
31
+ Store.put_data(@s.docname(:md),@data).should == true
32
+ Store.get_data(@s.docname(:md)).should == @data
33
+ end
38
34
 
39
- it "should put_data with simple data" do
40
- data = { '1' => { 'hello' => 'world' } }
41
- Store.put_data('mydata', data)
42
- Store.get_data('mydata').should == data
43
- end
44
-
45
- it "should update_objects with simple data and one changed attribute" do
46
- data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
47
- update_data = { '1' => {'attr1' => 'value2'}}
48
- Store.put_data(:md, data)
49
- Store.get_data(:md).should == data
50
- Store.update_objects(:md, update_data)
51
- data['1'].merge!(update_data['1'])
52
- Store.get_data(:md).should == data
53
- end
54
-
55
- it "should update_objects with simple data and verify that srem and sadd is called only on affected fields" do
56
- data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
57
- update_data = { '1' => {'attr1' => 'value2', 'new_attr' => 'new_val', 'hello' => 'world'},
58
- '2' => {'whole_new_object' => 'new_value' } }
59
- Store.put_data('mydata', data)
60
- Store.get_store(0).db.should_receive(:srem).exactly(1).times
61
- Store.get_store(0).db.should_receive(:sadd).exactly(2).times
62
- Store.update_objects('mydata', update_data)
63
- end
64
-
65
- it "should delete_objects with simple data" do
66
- data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
67
- Store.put_data('mydata', data)
68
- Store.delete_objects('mydata', ['1'])
69
- Store.get_data('mydata').should == {}
70
- end
35
+ it "should set_data and get_data" do
36
+ Store.set_data('foo', @data)
37
+ Store.get_data('foo').should == @data
38
+ end
71
39
 
72
- it "should update_count and delete_value with simple integer data" do
73
- Store.put_value('mydata', 21)
74
- Store.update_count('mydata', -5)
75
- Store.get_value('mydata').to_i.should == 16
76
- Store.delete_value('mydata')
77
- Store.exists?('mydata').should be_false
78
- end
79
-
80
- it "should delete_objects with simple data and verify that srem is called only on affected fields" do
81
- data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
82
- Store.put_data('mydata', data)
83
- Store.get_store(0).db.should_receive(:srem).exactly(1).times
84
- Store.get_store(0).db.should_receive(:sadd).exactly(0).times
85
- Store.delete_objects('mydata', ['1'])
86
- end
87
-
88
- it "should add simple array data to new list" do
89
- @data = ['1','2','3']
90
- Store.put_list(@s.docname(:md),@data).should == true
91
- Store.get_list(@s.docname(:md)).should == @data
92
- end
93
-
94
- it "should add simple array data to new list using *_data methods" do
95
- @data = ['1','2','3']
96
- Store.put_data(@s.docname(:md),@data).should == true
97
- Store.get_data(@s.docname(:md),Array).should == @data
98
- end
40
+ it "should put_data with simple data" do
41
+ data = { '1' => { 'hello' => 'world' } }
42
+ Store.put_data('mydata', data)
43
+ Store.get_data('mydata').should == data
44
+ end
99
45
 
100
- it "should replace simple data to existing set" do
101
- new_data,new_data['3'] = {},{'name' => 'Droid','brand' => 'Google'}
102
- Store.put_data(@s.docname(:md),@data).should == true
103
- Store.put_data(@s.docname(:md),new_data)
104
- Store.get_data(@s.docname(:md)).should == new_data
105
- end
46
+ it "should update_objects with simple data and one changed attribute" do
47
+ data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
48
+ update_data = { '1' => {'attr1' => 'value2'}}
49
+ Store.put_data(:md, data)
50
+ Store.get_data(:md).should == data
51
+ Store.update_objects(:md, update_data)
52
+ data['1'].merge!(update_data['1'])
53
+ Store.get_data(:md).should == data
54
+ end
106
55
 
107
- it "should put_value and get_value" do
108
- Store.put_value('foo','bar')
109
- Store.get_value('foo').should == 'bar'
110
- end
56
+ it "should update_objects with simple data and verify that srem and sadd is called only on affected fields" do
57
+ data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
58
+ update_data = { '1' => {'attr1' => 'value2', 'new_attr' => 'new_val', 'hello' => 'world'},
59
+ '2' => {'whole_new_object' => 'new_value' } }
60
+ Store.put_data('mydata', data)
61
+ Store.get_store(0).db.should_receive(:srem).exactly(1).times
62
+ Store.get_store(0).db.should_receive(:sadd).exactly(2).times
63
+ Store.update_objects('mydata', update_data)
64
+ end
111
65
 
112
- it "should incr a key" do
113
- Store.incr('foo').should == 1
114
- end
66
+ it "should delete_objects with simple data" do
67
+ data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
68
+ Store.put_data('mydata', data)
69
+ Store.delete_objects('mydata', ['1'])
70
+ Store.get_data('mydata').should == {}
71
+ end
115
72
 
116
- it "should decr a key" do
117
- Store.set_value('foo', 10)
118
- Store.decr('foo').should == 9
119
- end
73
+ it "should update_count and delete_value with simple integer data" do
74
+ Store.put_value('mydata', 21)
75
+ Store.update_count('mydata', -5)
76
+ Store.get_value('mydata').to_i.should == 16
77
+ Store.delete_value('mydata')
78
+ Store.exists?('mydata').should be_false
79
+ end
120
80
 
121
- it "should return modified objs in doc2" do
122
- Store.put_data(@s.docname(:md),@data).should == true
123
- Store.get_data(@s.docname(:md)).should == @data
81
+ it "should delete_objects with simple data and verify that srem is called only on affected fields" do
82
+ data = { '1' => { 'hello' => 'world', "attr1" => 'value1' } }
83
+ Store.put_data('mydata', data)
84
+ Store.get_store(0).db.should_receive(:srem).exactly(1).times
85
+ Store.get_store(0).db.should_receive(:sadd).exactly(0).times
86
+ Store.delete_objects('mydata', ['1'])
87
+ end
124
88
 
125
- @product3['price'] = '59.99'
126
- elem_3 = Store.get_store(0).send(:set_obj_element, '3', @product3)
127
- keypairs_3 = Store.get_store(0).send(:get_obj_key_and_pairs, elem_3)
128
- expected = {elem_3 => keypairs_3}
129
- @data1,@data1['1'],@data1['2'],@data1['3'] = {},@product1,@product2,@product3
89
+ it "should add simple array data to new list" do
90
+ @data = ['1','2','3']
91
+ Store.put_list(@s.docname(:md),@data).should == true
92
+ Store.get_list(@s.docname(:md)).should == @data
93
+ end
130
94
 
131
- Store.put_data(@c.docname(:cd),@data1)
132
- Store.get_data(@c.docname(:cd)).should == @data1
133
- Store.get_diff_data(@s.docname(:md),@c.docname(:cd)).should == expected
134
- end
95
+ it "should add simple array data to new list using *_data methods" do
96
+ @data = ['1','2','3']
97
+ Store.put_data(@s.docname(:md),@data).should == true
98
+ Store.get_data(@s.docname(:md),Array).should == @data
99
+ end
135
100
 
136
- it "should return objects with attributes modified and missed in doc2" do
137
- Store.put_data(@s.docname(:md),@data).should == true
138
- Store.get_data(@s.docname(:md)).should == @data
139
-
140
- mod_product2 = @product2.dup
141
- mod_product2['price'] = '59.99'
142
- elem_2 = Store.get_store(0).send(:set_obj_element, '2', @data['2'])
143
- elem_3 = Store.get_store(0).send(:set_obj_element, '3', @product3)
144
- keypairs_2 = Store.get_store(0).send(:get_obj_key_and_pairs, elem_2)
145
- keypairs_3 = Store.get_store(0).send(:get_obj_key_and_pairs, elem_3)
146
- expected = {elem_2 => keypairs_2, elem_3 => keypairs_3}
147
- @data1,@data1['1'],@data1['2'] = {},@product1,mod_product2
148
-
149
- Store.put_data(@c.docname(:cd),@data1)
150
- Store.get_data(@c.docname(:cd)).should == @data1
151
- Store.get_diff_data(@c.docname(:cd),@s.docname(:md)).should == expected
152
- end
153
-
154
- it "should ignore reserved attributes" do
155
- @newproduct = {
156
- 'name' => 'iPhone',
157
- 'brand' => 'Apple',
158
- 'price' => '199.99',
159
- 'id' => 1234,
160
- 'attrib_type' => 'someblob'
161
- }
162
-
163
- @data1 = {'1'=>@newproduct,'2'=>@product2,'3'=>@product3}
164
-
165
- Store.put_data(@s.docname(:md),@data1).should == true
166
- Store.get_data(@s.docname(:md)).should == @data
167
- end
101
+ it "should replace simple data to existing set" do
102
+ new_data,new_data['3'] = {},{'name' => 'Droid','brand' => 'Google'}
103
+ Store.put_data(@s.docname(:md),@data).should == true
104
+ Store.put_data(@s.docname(:md),new_data)
105
+ Store.get_data(@s.docname(:md)).should == new_data
106
+ end
168
107
 
169
- it "should flush_data" do
170
- Store.put_data(@s.docname(:md),@data)
171
- Store.flush_data(@s.docname(:md))
172
- Store.get_data(@s.docname(:md)).should == {}
173
- end
174
-
175
- it "should flush_data for all keys matching pattern" do
176
- keys = ['test_flush_data1','test_flush_data2']
177
- keys.each {|key| Store.put_data(key,@data)}
178
- Store.flush_data('test_flush_data*')
179
- keys.each {|key| Store.get_data(key).should == {} }
180
- end
108
+ it "should put_value and get_value" do
109
+ Store.put_value('foo','bar')
110
+ Store.get_value('foo').should == 'bar'
111
+ end
181
112
 
182
- it "should flush_data without calling KEYS when there aren't pattern matching characters in the provided keymask" do
183
- key = 'test_flush_data'
184
- Store.put_data(key,@data)
185
- Store.get_store(0).db.should_not_receive(:keys)
186
- Store.get_store(0).db.should_receive(:del).once.with("#{key}:#{get_sha1('1')[0..1]}").and_return(true)
187
- Store.get_store(0).db.should_receive(:del).once.with("#{key}:#{get_sha1('2')[0..1]}").and_return(true)
188
- Store.get_store(0).db.should_receive(:del).once.with("#{key}:#{get_sha1('3')[0..1]}").and_return(true)
189
- Store.get_store(0).db.should_receive(:del).once.with("#{key}:indices").and_return(true)
190
- Store.flush_data(key)
191
- end
113
+ it "should incr a key" do
114
+ Store.incr('foo').should == 1
115
+ end
192
116
 
193
- it "should flush_data and call KEYS when there are pattern matching characters in the provided keymask" do
194
- keys = ['test_flush_data1','test_flush_data2']
195
- keys.each {|key| Store.put_data(key,@data)}
196
- docs = Store.keys("test_flush_data*")
197
- Store.get_store(0).db.should_receive(:keys).exactly(1).times.with("test_flush_data*").and_return(docs)
198
- Store.get_store(0).db.should_receive(:del).exactly(8).times.and_return(true)
199
- Store.flush_data("test_flush_data*")
200
- end
117
+ it "should decr a key" do
118
+ Store.set_value('foo', 10)
119
+ Store.decr('foo').should == 9
120
+ end
201
121
 
202
- it "should put_zdata and get_zdata" do
203
- create_doc = [[@s.name, [['1', {'foo' => 'bar'}]]]]
204
- assoc_key = 'my_assoc_key'
205
- Store.put_zdata('doc1',assoc_key,create_doc)
206
- zdata,keys = Store.get_zdata('doc1')
207
- zdata.should == [create_doc]
208
- keys.should == [assoc_key]
209
- end
210
-
211
- it "should return empty list on non-existing get_zdata" do
212
- zdata,keys = Store.get_zdata('wrong_doc2')
213
- zdata.should == []
214
- keys.should == []
215
- end
216
-
217
- it "should append duplicate data in put_zdata" do
218
- create_doc = [[@s.name, [['1', {'foo' => 'bar'}]]]]
219
- assoc_key = 'my_assoc_key'
220
- Store.put_zdata('doc1',assoc_key,create_doc)
221
- Store.put_zdata('doc1',assoc_key,create_doc, true)
222
- zdata,keys = Store.get_zdata('doc1')
223
- zdata.should == [create_doc,create_doc]
224
- keys.should == [assoc_key,assoc_key]
225
- end
226
-
227
- it "should flush_zdata" do
228
- create_doc = [[@s.name, [['1', {'foo' => 'bar'}]]]]
229
- assoc_key = 'my_assoc_key'
230
- Store.put_zdata('doc1',assoc_key,create_doc)
231
- zdocs = Store.get_data("doc1:1:my_assoc_key:#{@s.name}:0")
232
- zdocs.should == {'0_1' => {'foo' => 'bar'}}
233
- Store.flush_zdata('doc1')
234
- zdata,keys = Store.get_zdata('doc1')
235
- zdata.should == []
236
- keys.should == []
237
- zdocs = Store.get_data("doc1:1:my_assoc_key:#{@s.name}:0")
238
- zdocs.should == {}
239
- end
240
-
241
- if defined?(JRUBY_VERSION)
242
- it "should lock document" do
243
- doc = "locked_data"
244
- threads = []
245
- m_lock = Store.get_lock(doc)
246
- threads << Thread.new do
247
- t_lock = Store.get_lock(doc)
248
- Store.put_data(doc,{'1'=>@product1},true)
249
- Store.release_lock(doc,t_lock)
250
- end
251
- threads << Thread.new do
252
- t_lock = Store.get_lock(doc)
253
- Store.put_data(doc,{'3'=>@product3},true)
254
- Store.release_lock(doc,t_lock)
255
- end
256
- Store.put_data(doc,{'2'=>@product2},true)
257
- Store.get_data(doc).should == {'2'=>@product2}
258
- Store.release_lock(doc,m_lock)
259
- threads.each { |t| t.join }
260
- m_lock = Store.get_lock(doc)
261
- Store.get_data(doc).should == {'1'=>@product1,'2'=>@product2,'3'=>@product3}
262
- end
263
- else
264
- it "should lock document" do
265
- doc = "locked_data"
266
- m_lock = Store.get_lock(doc)
267
- pid = Process.fork do
268
- Store.nullify
269
- Store.create
270
- t_lock = Store.get_lock(doc)
271
- Store.put_data(doc,{'1'=>@product1},true)
272
- Store.release_lock(doc,t_lock)
273
- Process.exit(0)
274
- end
275
- Store.put_data(doc,{'2'=>@product2},true)
276
- Store.get_data(doc).should == {'2'=>@product2}
277
- Store.release_lock(doc,m_lock)
278
- Process.waitpid(pid)
279
- m_lock = Store.get_lock(doc)
280
- Store.get_data(doc).should == {'1'=>@product1,'2'=>@product2}
281
- end
282
- end
122
+ it "should return modified objs in doc2" do
123
+ Store.put_data(@s.docname(:md),@data).should == true
124
+ Store.get_data(@s.docname(:md)).should == @data
283
125
 
284
- it "should lock key for timeout" do
285
- doc = "locked_data"
286
- lock = Time.now.to_i+3
287
- Store.get_store(0).db.set "lock:#{doc}", lock
288
- Store.get_store(0).should_receive(:sleep).at_least(:once).with(1).and_return { sleep 1; Store.release_lock(doc,lock); }
289
- Store.get_lock(doc,4)
290
- end
126
+ @product3['price'] = '59.99'
127
+ elem_3 = Store.get_store(0).send(:set_obj_element, '3', @product3)
128
+ keypairs_3 = Store.get_store(0).send(:get_obj_key_and_pairs, elem_3)
129
+ expected = {elem_3 => keypairs_3}
130
+ @data1,@data1['1'],@data1['2'],@data1['3'] = {},@product1,@product2,@product3
291
131
 
292
- it "should raise exception if lock expires" do
132
+ Store.put_data(@c.docname(:cd),@data1)
133
+ Store.get_data(@c.docname(:cd)).should == @data1
134
+ Store.get_diff_data(@s.docname(:md),@c.docname(:cd)).should == expected
135
+ end
293
136
 
294
- doc = "locked_data"
295
- Store.get_lock(doc)
296
- lambda { sleep 2; Store.get_lock(doc,4,true) }.should raise_error(StoreLockException,"Lock \"lock:locked_data\" expired before it was released")
297
- end
137
+ it "should return objects with attributes modified and missed in doc2" do
138
+ Store.put_data(@s.docname(:md),@data).should == true
139
+ Store.get_data(@s.docname(:md)).should == @data
140
+
141
+ mod_product2 = @product2.dup
142
+ mod_product2['price'] = '59.99'
143
+ elem_2 = Store.get_store(0).send(:set_obj_element, '2', @data['2'])
144
+ elem_3 = Store.get_store(0).send(:set_obj_element, '3', @product3)
145
+ keypairs_2 = Store.get_store(0).send(:get_obj_key_and_pairs, elem_2)
146
+ keypairs_3 = Store.get_store(0).send(:get_obj_key_and_pairs, elem_3)
147
+ expected = {elem_2 => keypairs_2, elem_3 => keypairs_3}
148
+ @data1,@data1['1'],@data1['2'] = {},@product1,mod_product2
149
+
150
+ Store.put_data(@c.docname(:cd),@data1)
151
+ Store.get_data(@c.docname(:cd)).should == @data1
152
+ Store.get_diff_data(@c.docname(:cd),@s.docname(:md)).should == expected
153
+ end
298
154
 
299
- it "should raise lock expires exception on global setting" do
300
- doc = "locked_data"
301
- Store.get_lock(doc)
302
- Rhoconnect.raise_on_expired_lock = true
303
- lambda { sleep 2; Store.get_lock(doc,4) }.should raise_error(StoreLockException,"Lock \"lock:locked_data\" expired before it was released")
304
- Rhoconnect.raise_on_expired_lock = false
305
- end
155
+ it "should ignore reserved attributes" do
156
+ @newproduct = {
157
+ 'name' => 'iPhone',
158
+ 'brand' => 'Apple',
159
+ 'price' => '199.99',
160
+ 'id' => 1234,
161
+ 'attrib_type' => 'someblob'
162
+ }
306
163
 
307
- it "should acquire lock if it expires" do
308
- doc = "locked_data"
309
- Store.get_lock(doc)
310
- sleep 2
311
- Store.get_lock(doc,1).should > Time.now.to_i
312
- end
164
+ @data1 = {'1'=>@newproduct,'2'=>@product2,'3'=>@product3}
313
165
 
314
- it "should use global lock duration" do
315
- doc = "locked_data"
316
- Rhoconnect.lock_duration = 2
317
- Store.get_lock(doc)
318
- Store.get_store(0).should_receive(:sleep).at_least(1).times.with(1).and_return { sleep 1 }
319
- Store.get_lock(doc)
320
- Rhoconnect.lock_duration = nil
321
- end
166
+ Store.put_data(@s.docname(:md),@data1).should == true
167
+ Store.get_data(@s.docname(:md)).should == @data
168
+ end
169
+
170
+ it "should flush_data" do
171
+ Store.put_data(@s.docname(:md),@data)
172
+ Store.flush_data(@s.docname(:md))
173
+ Store.get_data(@s.docname(:md)).should == {}
174
+ end
175
+
176
+ it "should flush_data for all keys matching pattern" do
177
+ keys = ['test_flush_data1','test_flush_data2']
178
+ keys.each {|key| Store.put_data(key,@data)}
179
+ Store.flush_data('test_flush_data*')
180
+ keys.each {|key| Store.get_data(key).should == {} }
181
+ end
182
+
183
+ it "should flush_data without calling KEYS when there aren't pattern matching characters in the provided keymask" do
184
+ key = 'test_flush_data'
185
+ Store.put_data(key,@data)
186
+ redis_client = Store.get_store(0).db
187
+ expect(redis_client).to receive(:del).once.with("#{key}:#{get_sha1('1')[0..1]}").and_return(true)
188
+ expect(redis_client).to receive(:del).once.with("#{key}:#{get_sha1('2')[0..1]}").and_return(true)
189
+ expect(redis_client).to receive(:del).once.with("#{key}:#{get_sha1('3')[0..1]}").and_return(true)
190
+ expect(redis_client).to receive(:del).once.with("#{key}:indices").and_return(true)
191
+ expect(redis_client).to receive(:del).once.with("#{key}").and_return(true)
192
+
193
+ Store.flush_data(key)
194
+ end
322
195
 
323
- it "should lock document in block" do
196
+ it "should flush_data and call KEYS when there are pattern matching characters in the provided keymask" do
197
+ keys = ['test_flush_data1','test_flush_data2']
198
+ keys.each {|key| Store.put_data(key,@data)}
199
+ docs = Store.keys("test_flush_data*")
200
+ Store.get_store(0).db.should_receive(:keys).exactly(1).times.with("test_flush_data*").and_return(docs)
201
+ Store.get_store(0).db.should_receive(:del).exactly(8).times.and_return(true)
202
+ Store.flush_data("test_flush_data*")
203
+ end
204
+
205
+ it "should put_zdata and get_zdata" do
206
+ create_doc = [[@s.name, [['1', {'foo' => 'bar'}]]]]
207
+ assoc_key = 'my_assoc_key'
208
+ Store.put_zdata('doc1',assoc_key,create_doc)
209
+ zdata,keys = Store.get_zdata('doc1')
210
+ zdata.should == [create_doc]
211
+ keys.should == [assoc_key]
212
+ end
213
+
214
+ it "should return empty list on non-existing get_zdata" do
215
+ zdata,keys = Store.get_zdata('wrong_doc2')
216
+ zdata.should == []
217
+ keys.should == []
218
+ end
219
+
220
+ it "should append duplicate data in put_zdata" do
221
+ create_doc = [[@s.name, [['1', {'foo' => 'bar'}]]]]
222
+ assoc_key = 'my_assoc_key'
223
+ Store.put_zdata('doc1',assoc_key,create_doc)
224
+ Store.put_zdata('doc1',assoc_key,create_doc, true)
225
+ zdata,keys = Store.get_zdata('doc1')
226
+ zdata.should == [create_doc,create_doc]
227
+ keys.should == [assoc_key,assoc_key]
228
+ end
229
+
230
+ it "should flush_zdata" do
231
+ create_doc = [[@s.name, [['1', {'foo' => 'bar'}]]]]
232
+ assoc_key = 'my_assoc_key'
233
+ Store.put_zdata('doc1',assoc_key,create_doc)
234
+ zdocs = Store.get_data("doc1:1:my_assoc_key:#{@s.name}:0")
235
+ zdocs.should == {'0_1' => {'foo' => 'bar'}}
236
+ Store.flush_zdata('doc1')
237
+ zdata,keys = Store.get_zdata('doc1')
238
+ zdata.should == []
239
+ keys.should == []
240
+ zdocs = Store.get_data("doc1:1:my_assoc_key:#{@s.name}:0")
241
+ zdocs.should == {}
242
+ end
243
+
244
+ if defined?(JRUBY_VERSION)
245
+ it "should lock document" do
324
246
  doc = "locked_data"
325
- Store.lock(doc,0) do
326
- Store.put_data(doc,{'2'=>@product2})
327
- Store.get_data(doc).should == {'2'=>@product2}
247
+ threads = []
248
+ m_lock = Store.get_lock(doc)
249
+ threads << Thread.new do
250
+ t_lock = Store.get_lock(doc)
251
+ Store.put_data(doc,{'1'=>@product1},true)
252
+ Store.release_lock(doc,t_lock)
328
253
  end
254
+ threads << Thread.new do
255
+ t_lock = Store.get_lock(doc)
256
+ Store.put_data(doc,{'3'=>@product3},true)
257
+ Store.release_lock(doc,t_lock)
258
+ end
259
+ Store.put_data(doc,{'2'=>@product2},true)
260
+ Store.get_data(doc).should == {'2'=>@product2}
261
+ Store.release_lock(doc,m_lock)
262
+ threads.each { |t| t.join }
263
+ m_lock = Store.get_lock(doc)
264
+ Store.get_data(doc).should == {'1'=>@product1,'2'=>@product2,'3'=>@product3}
265
+ end
266
+ else
267
+ it "should lock document" do
268
+ doc = "locked_data"
269
+ m_lock = Store.get_lock(doc)
270
+ pid = Process.fork do
271
+ Store.nullify
272
+ Store.create
273
+ t_lock = Store.get_lock(doc)
274
+ Store.put_data(doc,{'1'=>@product1},true)
275
+ Store.release_lock(doc,t_lock)
276
+ Process.exit(0)
277
+ end
278
+ Store.put_data(doc,{'2'=>@product2},true)
279
+ Store.get_data(doc).should == {'2'=>@product2}
280
+ Store.release_lock(doc,m_lock)
281
+ Process.waitpid(pid)
282
+ m_lock = Store.get_lock(doc)
283
+ Store.get_data(doc).should == {'1'=>@product1,'2'=>@product2}
329
284
  end
285
+ end
286
+
287
+ it "should lock key for timeout" do
288
+ doc = "locked_data"
289
+ lock = Time.now.to_i+3
290
+ Store.get_store(0).db.set "lock:#{doc}", lock
291
+ Store.get_store(0).should_receive(:sleep).at_least(:once).with(1).and_return { sleep 1; Store.release_lock(doc,lock); }
292
+ Store.get_lock(doc,4)
293
+ end
294
+
295
+ it "should raise exception if lock expires" do
330
296
 
331
- it "should create clone of set" do
332
- set_state('abc' => @data)
333
- Store.clone('abc','def')
334
- verify_result('abc' => @data,'def' => @data)
297
+ doc = "locked_data"
298
+ Store.get_lock(doc)
299
+ lambda { sleep 2; Store.get_lock(doc,4,true) }.should raise_error(StoreLockException,"Lock \"lock:locked_data\" expired before it was released")
300
+ end
301
+
302
+ it "should raise lock expires exception on global setting" do
303
+ doc = "locked_data"
304
+ Store.get_lock(doc)
305
+ Rhoconnect.raise_on_expired_lock = true
306
+ lambda { sleep 2; Store.get_lock(doc,4) }.should raise_error(StoreLockException,"Lock \"lock:locked_data\" expired before it was released")
307
+ Rhoconnect.raise_on_expired_lock = false
308
+ end
309
+
310
+ it "should acquire lock if it expires" do
311
+ doc = "locked_data"
312
+ Store.get_lock(doc)
313
+ sleep 2
314
+ Store.get_lock(doc,1).should > Time.now.to_i
315
+ end
316
+
317
+ it "should use global lock duration" do
318
+ doc = "locked_data"
319
+ Rhoconnect.lock_duration = 2
320
+ Store.get_lock(doc)
321
+ Store.get_store(0).should_receive(:sleep).at_least(1).times.with(1).and_return { sleep 1 }
322
+ Store.get_lock(doc)
323
+ Rhoconnect.lock_duration = nil
324
+ end
325
+
326
+ it "should lock document in block" do
327
+ doc = "locked_data"
328
+ Store.lock(doc,0) do
329
+ Store.put_data(doc,{'2'=>@product2})
330
+ Store.get_data(doc).should == {'2'=>@product2}
335
331
  end
332
+ end
333
+
334
+ it "should create clone of set" do
335
+ set_state('abc' => @data)
336
+ Store.clone('abc','def')
337
+ verify_result('abc' => @data,'def' => @data)
338
+ end
339
+
340
+ it "should rename a key" do
341
+ set_state('key1' => @data)
342
+ Store.rename('key1','key2')
343
+ verify_result('key1' => {}, 'key2' => @data)
344
+ end
345
+
346
+ it "should not fail to rename if key doesn't exist" do
347
+ Store.rename('key1','key2')
348
+ Store.exists?('key1').should be_false
349
+ Store.exists?('key2').should be_false
350
+ end
351
+
352
+ it "should raise ArgumentError on put_data with invalid data" do
353
+ foobar = {'foo'=>'bar'}
354
+ expect {
355
+ Store.put_data('somedoc',{'foo'=>'bar'})
356
+ }.to raise_exception(ArgumentError, "Invalid value object: #{foobar['foo'].inspect}. Hash is expected.")
357
+ end
358
+
359
+ it "should put_object into the bucketed md" do
360
+ key1 = '1'
361
+ data1 = {'foo' => 'bar'}
362
+ key2 = '2'
363
+ data2 = {'one' => 'two', 'three' => 'four'}
364
+ docindex1 = get_sha1(key1)[0..1]
365
+ docindex2 = get_sha1(key2)[0..1]
366
+ Store.put_object(:md, key1, data1)
367
+ Store.put_object(:md, key2, data2)
368
+ Store.keys(:md).should == []
369
+ Store.exists?("#{:md}:#{docindex1}").should be_true
370
+ Store.exists?("#{:md}:#{docindex2}").should be_true
371
+ Store.exists?("#{:md}:indices").should be_true
372
+ Store.get_store(0).db.hkeys("#{:md}:indices").should == ["#{docindex1}", "#{docindex2}"]
373
+ Store.get_store(0).db.hvals("#{:md}:indices").should == ["#{:md}:#{docindex1}", "#{:md}:#{docindex2}"]
374
+ end
375
+
376
+ it "should get_object from the bucketed md" do
377
+ key1 = '1'
378
+ data1 = {'foo' => 'bar'}
379
+ key2 = '2'
380
+ data2 = {'one' => 'two', 'three' => 'four'}
381
+ docindex1 = get_sha1(key1)[0..1]
382
+ docindex2 = get_sha1(key2)[0..1]
383
+ Store.put_object(:md, key1, data1)
384
+ Store.put_object(:md, key2, data2)
385
+ obj2 = Store.get_object(:md, key2)
386
+ obj2.should == data2
387
+ end
388
+
389
+ it "should make temporary document and restore it to permanent with rename" do
390
+ key1 = '1'
391
+ data1 = {'foo' => 'bar'}
392
+ key2 = '2'
393
+ data2 = {'one' => 'two', 'three' => 'four'}
394
+ docindex1 = get_sha1(key1)[0..1]
395
+ docindex2 = get_sha1(key2)[0..1]
396
+ Store.put_tmp_data(:md, {key1 => data1})
397
+ Store.put_tmp_data(:md, {key2 => data2}, true)
398
+
399
+ Store.exists?("#{:md}:#{docindex1}").should be_true
400
+ Store.exists?("#{:md}:#{docindex2}").should be_true
401
+ Store.exists?("#{:md}:indices").should be_true
402
+ Store.get_store(0).db.ttl("#{:md}:#{docindex1}").should == Rhoconnect.store_key_ttl
403
+ Store.get_store(0).db.ttl("#{:md}:#{docindex2}").should == Rhoconnect.store_key_ttl
404
+ Store.get_store(0).db.ttl("#{:md}:indices").should == Rhoconnect.store_key_ttl
405
+
406
+ Store.rename_tmp_data(:md, :md_perm)
407
+ Store.exists?("#{:md}:#{docindex1}").should be_false
408
+ Store.exists?("#{:md}:#{docindex2}").should be_false
409
+ Store.exists?("#{:md}:indices").should be_false
410
+ Store.exists?("#{:md_perm}:#{docindex1}").should be_true
411
+ Store.exists?("#{:md_perm}:#{docindex2}").should be_true
412
+ Store.exists?("#{:md_perm}:indices").should be_true
413
+ Store.get_store(0).db.ttl("#{:md_perm}:#{docindex1}").should == -1
414
+ Store.get_store(0).db.ttl("#{:md_perm}:#{docindex2}").should == -1
415
+ Store.get_store(0).db.ttl("#{:md_perm}:indices").should == -1
416
+ end
417
+
418
+ describe "multiple redis clustering" do
419
+ before(:all) do
420
+ # start 2 redis instances in addition to default 6379
421
+ system("redis-server --port 6380 &")
422
+ system("redis-server --port 6381 &")
423
+ sleep(1)
424
+ Store.nullify
425
+ Store.create(['localhost:6379', 'localhost:6380', 'localhost:6381'])
336
426
 
337
- it "should rename a key" do
338
- set_state('key1' => @data)
339
- Store.rename('key1','key2')
340
- verify_result('key1' => {}, 'key2' => @data)
341
427
  end
342
428
 
343
- it "should not fail to rename if key doesn't exist" do
344
- Store.rename('key1','key2')
345
- Store.exists?('key1').should be_false
346
- Store.exists?('key2').should be_false
429
+ after(:all) do
430
+ # shutdown 2 additional redis instances (leave default one as is)
431
+ Store.get_store(1).send(:db).shutdown
432
+ Store.get_store(2).send(:db).shutdown
433
+ Store.nullify
347
434
  end
348
435
 
349
- it "should raise ArgumentError on put_data with invalid data" do
350
- foobar = {'foo'=>'bar'}
351
- expect {
352
- Store.put_data('somedoc',{'foo'=>'bar'})
353
- }.to raise_exception(ArgumentError, "Invalid value object: #{foobar['foo'].inspect}. Hash is expected.")
436
+ it "should list number of stores" do
437
+ Store.num_stores.should == 3
354
438
  end
355
-
356
- it "should put_object into the bucketed md" do
357
- key1 = '1'
358
- data1 = {'foo' => 'bar'}
359
- key2 = '2'
360
- data2 = {'one' => 'two', 'three' => 'four'}
361
- docindex1 = get_sha1(key1)[0..1]
362
- docindex2 = get_sha1(key2)[0..1]
363
- Store.put_object(:md, key1, data1)
364
- Store.put_object(:md, key2, data2)
365
- Store.keys(:md).should == []
366
- Store.exists?("#{:md}:#{docindex1}").should be_true
367
- Store.exists?("#{:md}:#{docindex2}").should be_true
368
- Store.exists?("#{:md}:indices").should be_true
369
- Store.get_store(0).db.hkeys("#{:md}:indices").should == ["#{docindex1}", "#{docindex2}"]
370
- Store.get_store(0).db.hvals("#{:md}:indices").should == ["#{:md}:#{docindex1}", "#{:md}:#{docindex2}"]
439
+
440
+ it "data for Source and Client docs should be on the same instance" do
441
+ source_index = @s.store_index(:md)
442
+ client_index = @c.store_index(:cd)
443
+ # for this source and user , index should be computed to 2
444
+ source_index.should == 2
445
+ source_index.should == client_index
371
446
  end
372
-
373
- it "should get_object from the bucketed md" do
374
- key1 = '1'
375
- data1 = {'foo' => 'bar'}
376
- key2 = '2'
377
- data2 = {'one' => 'two', 'three' => 'four'}
378
- docindex1 = get_sha1(key1)[0..1]
379
- docindex2 = get_sha1(key2)[0..1]
380
- Store.put_object(:md, key1, data1)
381
- Store.put_object(:md, key2, data2)
382
- obj2 = Store.get_object(:md, key2)
383
- obj2.should == data2
447
+
448
+ it "data for app-parttion should go to system Redis (with index 0)" do
449
+ @c.source_name = @s3.name
450
+ source_index = @s3.store_index(:md)
451
+ client_index = @c.store_index(:cd)
452
+ # for this source and user , index should be compured to 0
453
+ source_index.should == 0
454
+ source_index.should == client_index
384
455
  end
385
456
 
386
- it "should make temporary document and restore it to permanent with rename" do
457
+ it "should set and flush the data only in appropriate instance" do
387
458
  key1 = '1'
388
459
  data1 = {'foo' => 'bar'}
389
460
  key2 = '2'
390
- data2 = {'one' => 'two', 'three' => 'four'}
391
- docindex1 = get_sha1(key1)[0..1]
392
- docindex2 = get_sha1(key2)[0..1]
393
- Store.put_tmp_data(:md, {key1 => data1})
394
- Store.put_tmp_data(:md, {key2 => data2}, true)
395
-
396
- Store.exists?("#{:md}:#{docindex1}").should be_true
397
- Store.exists?("#{:md}:#{docindex2}").should be_true
398
- Store.exists?("#{:md}:indices").should be_true
399
- Store.get_store(0).db.ttl("#{:md}:#{docindex1}").should == Rhoconnect.store_key_ttl
400
- Store.get_store(0).db.ttl("#{:md}:#{docindex2}").should == Rhoconnect.store_key_ttl
401
- Store.get_store(0).db.ttl("#{:md}:indices").should == Rhoconnect.store_key_ttl
402
-
403
- Store.rename_tmp_data(:md, :md_perm)
404
- Store.exists?("#{:md}:#{docindex1}").should be_false
405
- Store.exists?("#{:md}:#{docindex2}").should be_false
406
- Store.exists?("#{:md}:indices").should be_false
407
- Store.exists?("#{:md_perm}:#{docindex1}").should be_true
408
- Store.exists?("#{:md_perm}:#{docindex2}").should be_true
409
- Store.exists?("#{:md_perm}:indices").should be_true
410
- Store.get_store(0).db.ttl("#{:md_perm}:#{docindex1}").should == -1
411
- Store.get_store(0).db.ttl("#{:md_perm}:#{docindex2}").should == -1
412
- Store.get_store(0).db.ttl("#{:md_perm}:indices").should == -1
413
- end
414
-
415
- describe "multiple redis clustering" do
416
- before(:all) do
417
- # start 2 redis instances in addition to default 6379
418
- system("redis-server --port 6380 &")
419
- system("redis-server --port 6381 &")
420
- sleep(1)
421
- Store.nullify
422
- Store.create(['localhost:6379', 'localhost:6380', 'localhost:6381'])
423
-
424
- end
425
-
426
- after(:all) do
427
- # shutdown 2 additional redis instances (leave default one as is)
428
- Store.get_store(1).send(:db).shutdown
429
- Store.get_store(2).send(:db).shutdown
430
- Store.nullify
431
- end
432
-
433
- it "should list number of stores" do
434
- Store.num_stores.should == 3
435
- end
436
-
437
- it "data for Source and Client docs should be on the same instance" do
438
- source_index = @s.store_index(:md)
439
- client_index = @c.store_index(:cd)
440
- # for this source and user , index should be computed to 2
441
- source_index.should == 2
442
- source_index.should == client_index
443
- end
444
-
445
- it "data for app-parttion should go to system Redis (with index 0)" do
446
- @c.source_name = @s3.name
447
- source_index = @s3.store_index(:md)
448
- client_index = @c.store_index(:cd)
449
- # for this source and user , index should be compured to 0
450
- source_index.should == 0
451
- source_index.should == client_index
452
- end
453
-
454
- it "should set and flush the data only in appropriate instance" do
455
- key1 = '1'
456
- data1 = {'foo' => 'bar'}
457
- key2 = '2'
458
- data2 = {'foo1' => 'bar1'}
459
- @s.put_data(:md, {key1 => data1})
460
- Store.get_store(2).get_data(@s.docname(:md)).should == {key1 => data1}
461
- # data in store 1 should not be accessible through Source documents
462
- # because this combination of user and source should index to instance #2
463
- Store.get_store(1).put_data(@s.docname(:md), {key2 => data2})
464
- Store.get_store(1).get_data(@s.docname(:md)).should == {key2 => data2}
465
-
466
- @s.get_data(:md).should == {key1 => data1}
467
- Store.get_store(2).flush_data(@s.docname(:md))
468
- @s.get_data(:md).should == {}
469
- Store.get_store(1).get_data(@s.docname(:md)).should == {key2 => data2}
470
- end
461
+ data2 = {'foo1' => 'bar1'}
462
+ @s.put_data(:md, {key1 => data1})
463
+ Store.get_store(2).get_data(@s.docname(:md)).should == {key1 => data1}
464
+ # data in store 1 should not be accessible through Source documents
465
+ # because this combination of user and source should index to instance #2
466
+ Store.get_store(1).put_data(@s.docname(:md), {key2 => data2})
467
+ Store.get_store(1).get_data(@s.docname(:md)).should == {key2 => data2}
468
+
469
+ @s.get_data(:md).should == {key1 => data1}
470
+ Store.get_store(2).flush_data(@s.docname(:md))
471
+ @s.get_data(:md).should == {}
472
+ Store.get_store(1).get_data(@s.docname(:md)).should == {key2 => data2}
471
473
  end
472
474
  end
473
- end
475
+ end
474
476
  end