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.
- 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
|