rhoconnect 4.0.4 → 5.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/CHANGELOG.md +54 -5
- data/CREDITS +219 -219
- data/Gemfile +2 -2
- data/Gemfile.lock +68 -79
- data/Rakefile +1 -2
- data/bench/benchapp/spec/models/ruby/mock_adapter_spec.rb +17 -17
- data/bench/benchapp/spec/models/ruby/queue_mock_adapter_spec.rb +17 -17
- data/bench/benchapp/spec/spec_helper.rb +3 -3
- data/bench/blobapp/spec/models/ruby/blob_adapter_spec.rb +17 -17
- data/bench/blobapp/spec/spec_helper.rb +3 -3
- data/bench/lib/bench/runner.rb +1 -69
- data/bench/lib/bench.rb +18 -18
- data/bench/spec/mock_adapter_spec.rb +54 -55
- data/bench/spec/mock_client_spec.rb +47 -48
- data/bench/spec/result_spec.rb +41 -44
- data/bench/spec/utils_spec.rb +24 -25
- data/commands/generators/app.rb +7 -5
- data/commands/generators/controller.rb +7 -5
- data/commands/generators/model.rb +7 -5
- data/commands/generators/source.rb +7 -5
- data/commands/parser.rb +1 -1
- data/commands/redis/redis_download.rb +1 -1
- data/doc/async-jobs.txt +9 -9
- data/doc/supported-platforms.txt +0 -2
- data/generators/rhoconnect.rb +92 -212
- data/generators/templates/application/rcgemfile +3 -3
- data/generators/templates/application/spec/application_controller_spec.rb +14 -16
- data/generators/templates/application/spec/js_spec.rb +20 -20
- data/generators/templates/application/spec/spec_helper.rb +1 -1
- data/generators/templates/source/controllers/ruby/controller_spec.rb +18 -19
- data/generators/templates/source/models/ruby/model_spec.rb +17 -17
- data/install.sh +10 -21
- data/installer/unix-like/rho_connect_install_constants.rb +5 -5
- data/installer/unix-like/rho_connect_install_installers.rb +4 -4
- data/installer/utils/constants.rb +6 -6
- data/installer/utils/nix_install_test.rb +29 -29
- data/installer/utils/package_upload/repos.rake +16 -26
- data/js-adapters/node.rb +4 -4
- data/js-adapters/node_channel.rb +4 -8
- data/lib/rhoconnect/db_adapter.rb +13 -13
- data/lib/rhoconnect/handler/changes/engine.rb +1 -1
- data/lib/rhoconnect/jobs/bulk_data_job.rb +29 -29
- data/lib/rhoconnect/license.rb +7 -7
- data/lib/rhoconnect/model/helpers/find_duplicates_on_update.rb +13 -13
- data/lib/rhoconnect/ping/apple.rb +4 -4
- data/lib/rhoconnect/server.rb +2 -2
- data/lib/rhoconnect/source.rb +2 -2
- data/lib/rhoconnect/store.rb +12 -6
- data/lib/rhoconnect/utilities.rb +2 -2
- data/lib/rhoconnect/version.rb +1 -1
- data/lib/rhoconnect.rb +6 -4
- data/rhoconnect.gemspec +5 -6
- data/spec/api/api_helper.rb +1 -1
- data/spec/api/app/fast_delete_spec.rb +22 -22
- data/spec/api/app/fast_insert_spec.rb +23 -23
- data/spec/api/app/fast_update_spec.rb +63 -63
- data/spec/api/app/push_deletes_spec.rb +11 -13
- data/spec/api/app/push_objects_spec.rb +39 -39
- data/spec/api/client/client_get_db_doc_spec.rb +29 -29
- data/spec/api/client/client_set_db_doc_spec.rb +11 -11
- data/spec/api/client/get_client_params_spec.rb +29 -29
- data/spec/api/client/list_client_docs_spec.rb +32 -34
- data/spec/api/client/reset_spec.rb +30 -30
- data/spec/api/readstate/set_refresh_time_spec.rb +43 -43
- data/spec/api/source/get_source_params_spec.rb +32 -34
- data/spec/api/source/list_sources_spec.rb +13 -13
- data/spec/api/source/update_source_params_spec.rb +19 -19
- data/spec/api/store/get_db_doc_spec.rb +27 -27
- data/spec/api/store/set_db_doc_spec.rb +38 -38
- data/spec/api/system/adapter_spec.rb +27 -29
- data/spec/api/system/get_license_info_spec.rb +11 -11
- data/spec/api/system/login_spec.rb +37 -37
- data/spec/api/system/reset_spec.rb +15 -15
- data/spec/api/system/stats_spec.rb +70 -71
- data/spec/api/user/create_user_spec.rb +37 -37
- data/spec/api/user/delete_client_spec.rb +7 -7
- data/spec/api/user/delete_user_spec.rb +62 -62
- data/spec/api/user/list_clients_spec.rb +24 -24
- data/spec/api/user/list_source_docs_spec.rb +29 -29
- data/spec/api/user/list_users_spec.rb +22 -22
- data/spec/api/user/ping_spec.rb +18 -18
- data/spec/api/user/show_user_spec.rb +10 -10
- data/spec/api/user/update_user_spec.rb +43 -43
- data/spec/api/user/user_get_db_doc_spec.rb +12 -12
- data/spec/api/user/user_set_db_doc_spec.rb +37 -37
- data/spec/api_token_spec.rb +8 -8
- data/spec/app_spec.rb +18 -17
- data/spec/apps/jstestapp/settings/settings.yml +2 -0
- data/spec/async_spec.rb +9 -11
- data/spec/bulk_data/bulk_data_spec.rb +120 -120
- data/spec/cli/cli_spec.rb +50 -53
- data/spec/client_spec.rb +105 -105
- data/spec/client_sync_spec.rb +529 -528
- data/spec/controllers/js_base_spec.rb +147 -141
- data/spec/doc/doc_spec.rb +51 -52
- data/spec/document_spec.rb +58 -58
- data/spec/dynamic_adapter_spec.rb +33 -36
- data/spec/generator/generator_spec.rb +76 -42
- data/spec/jobs/bulk_data_job_spec.rb +101 -102
- data/spec/jobs/ping_job_spec.rb +176 -177
- data/spec/jobs/source_job_spec.rb +24 -25
- data/spec/license_spec.rb +54 -55
- data/spec/models/js_base_spec.rb +121 -120
- data/spec/perf/bulk_data_perf_spec.rb +23 -24
- data/spec/perf/perf_spec_helper.rb +7 -7
- data/spec/perf/store_perf_spec.rb +139 -140
- data/spec/ping/apple_spec.rb +65 -65
- data/spec/ping/gcm_spec.rb +83 -84
- data/spec/ping/rhoconnect_push_spec.rb +52 -53
- data/spec/predefined_adapters/rho_internal_bench_adapter_controller_js_spec.rb +100 -101
- data/spec/predefined_adapters/rho_internal_js_bench_adapter_js_spec.rb +29 -31
- data/spec/read_state_spec.rb +24 -25
- data/spec/rhoconnect_spec.rb +7 -7
- data/spec/server/server_spec.rb +664 -662
- data/spec/server/stats_spec.rb +12 -12
- data/spec/source_adapter_spec.rb +124 -125
- data/spec/source_spec.rb +148 -149
- data/spec/source_sync_spec.rb +736 -736
- data/spec/spec_helper.rb +4 -5
- data/spec/stats/record_spec.rb +22 -21
- data/spec/store_orm_spec.rb +48 -48
- data/spec/store_spec.rb +428 -426
- data/spec/support/shared_examples.rb +5 -7
- data/spec/sync_states_spec.rb +67 -67
- data/spec/test_methods_spec.rb +121 -123
- data/spec/testdata/10000-data.txt +0 -0
- data/spec/testdata/5000-data.txt +0 -0
- data/spec/user_spec.rb +102 -102
- data/tasks/redis.rake +3 -3
- metadata +154 -195
- data/bench/benchapp/tmp/pids/passenger.9292.pid.lock +0 -0
- data/bench/benchapp/tmp/restart.txt +0 -0
- data/bench/blobapp/settings/license.key.bak +0 -2
- data/bench/blobapp/tmp/restart.txt +0 -0
- data/bench/lib/testdata/1-data.txt +0 -0
- data/bench/lib/testdata/10-data.txt +0 -0
- data/bench/lib/testdata/2-data.txt +0 -0
- data/bench/lib/testdata/250-data.txt +0 -0
- data/bench/lib/testdata/5-blob_data.txt +0 -0
- data/bench/lib/testdata/5-data.txt +0 -0
- data/bench/lib/testdata/50-data.txt +0 -0
- data/bench/lib/testdata/500-data.txt +0 -0
- data/doc/protocol.html +0 -1993
- data/spec/coverage/rcov/assets/0.2.3/jquery-1.3.2.min.js +0 -19
- data/spec/coverage/rcov/assets/0.2.3/jquery.tablesorter.min.js +0 -15
- data/spec/coverage/rcov/assets/0.2.3/print.css +0 -12
- data/spec/coverage/rcov/assets/0.2.3/rcov.js +0 -42
- data/spec/coverage/rcov/assets/0.2.3/screen.css +0 -270
- data/spec/coverage/rcov/index.html +0 -88
- 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
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
-
|
183
|
-
|
184
|
-
|
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
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
-
|
203
|
-
|
204
|
-
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
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
|
-
|
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
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
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
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
-
|
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
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
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
|
-
|
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
|
-
|
326
|
-
|
327
|
-
|
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
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
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
|
-
|
344
|
-
|
345
|
-
Store.
|
346
|
-
Store.
|
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
|
350
|
-
|
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
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
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
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
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 = {'
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
Store.
|
397
|
-
|
398
|
-
|
399
|
-
Store.get_store(
|
400
|
-
|
401
|
-
Store.get_store(
|
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
|