higgs 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/test/test_lock.rb CHANGED
@@ -10,7 +10,7 @@ module Higgs::Test
10
10
  include Higgs
11
11
 
12
12
  # for ident(1)
13
- CVS_ID = '$Id: test_lock.rb 559 2007-09-25 15:20:20Z toki $'
13
+ CVS_ID = '$Id: test_lock.rb 652 2007-10-22 15:23:50Z toki $'
14
14
 
15
15
  WORK_COUNT = 100
16
16
  THREAD_COUNT = 10
@@ -118,6 +118,93 @@ module Higgs::Test
118
118
  end
119
119
  assert_equal(THREAD_COUNT * WORK_COUNT, count)
120
120
  end
121
+
122
+ def test_exclusive_single_thread
123
+ v = "foo"
124
+ WORK_COUNT.times do
125
+ @lock_manager.exclusive{
126
+ assert_equal("foo", v)
127
+ }
128
+ end
129
+ end
130
+
131
+ def test_exclusive_multithread
132
+ count = 0
133
+ th_grp = ThreadGroup.new
134
+ barrier = Barrier.new(THREAD_COUNT + 1)
135
+
136
+ THREAD_COUNT.times do
137
+ th_grp.add Thread.new{
138
+ barrier.wait
139
+ WORK_COUNT.times do
140
+ @lock_manager.exclusive{
141
+ count += 1
142
+ }
143
+ end
144
+ }
145
+ end
146
+
147
+ barrier.wait
148
+ for t in th_grp.list
149
+ t.join
150
+ end
151
+ assert_equal(THREAD_COUNT * WORK_COUNT, count)
152
+ end
153
+
154
+ def test_read_write_exclusive_multithread
155
+ v = 'foo'
156
+ count = 0
157
+ th_grp = ThreadGroup.new
158
+ barrier = Barrier.new(THREAD_COUNT * 3 + 1)
159
+
160
+ THREAD_COUNT.times{|i|
161
+ th_grp.add Thread.new{
162
+ barrier.wait
163
+ WORK_COUNT.times do |j|
164
+ @lock_manager.transaction(true) {|lock_handler|
165
+ lock_handler.lock(:foo)
166
+ assert_equal('foo', v, "read transaction: #{i}.#{j}")
167
+ }
168
+ end
169
+ }
170
+ }
171
+
172
+ THREAD_COUNT.times{|i|
173
+ th_grp.add Thread.new{
174
+ barrier.wait
175
+ WORK_COUNT.times do |j|
176
+ @lock_manager.transaction{|lock_handler|
177
+ lock_handler.lock(:foo)
178
+ assert_equal('foo', v, "write transaction: #{i}.#{j}")
179
+ v = 'bar'
180
+ v = 'foo'
181
+ count += 1
182
+ }
183
+ end
184
+ }
185
+ }
186
+
187
+ THREAD_COUNT.times{|i|
188
+ th_grp.add Thread.new{
189
+ barrier.wait
190
+ WORK_COUNT.times do |j|
191
+ @lock_manager.exclusive{
192
+ assert_equal('foo', v, "exclusive: #{i}.#{j}")
193
+ v = 'baz'
194
+ v = 'foo'
195
+ count += 1
196
+ }
197
+ end
198
+ }
199
+ }
200
+
201
+ barrier.wait
202
+ for t in th_grp.list
203
+ t.join
204
+ end
205
+ assert_equal('foo', v)
206
+ assert_equal(THREAD_COUNT * WORK_COUNT * 2, count)
207
+ end
121
208
  end
122
209
 
123
210
  class GiantLockManagerTest < Test::Unit::TestCase
@@ -125,7 +212,7 @@ module Higgs::Test
125
212
  include LockManagerTest
126
213
 
127
214
  # for ident(1)
128
- CVS_ID = '$Id: test_lock.rb 559 2007-09-25 15:20:20Z toki $'
215
+ CVS_ID = '$Id: test_lock.rb 652 2007-10-22 15:23:50Z toki $'
129
216
 
130
217
  def setup
131
218
  @lock_manager = GiantLockManager.new
@@ -170,7 +257,7 @@ module Higgs::Test
170
257
  include LockManagerTest
171
258
 
172
259
  # for ident(1)
173
- CVS_ID = '$Id: test_lock.rb 559 2007-09-25 15:20:20Z toki $'
260
+ CVS_ID = '$Id: test_lock.rb 652 2007-10-22 15:23:50Z toki $'
174
261
 
175
262
  def setup
176
263
  @lock_manager = FineGrainLockManager.new
@@ -214,7 +301,7 @@ module Higgs::Test
214
301
  include Higgs
215
302
 
216
303
  # for ident(1)
217
- CVS_ID = '$Id: test_lock.rb 559 2007-09-25 15:20:20Z toki $'
304
+ CVS_ID = '$Id: test_lock.rb 652 2007-10-22 15:23:50Z toki $'
218
305
 
219
306
  WORK_COUNT = 1000
220
307
 
@@ -255,7 +342,7 @@ module Higgs::Test
255
342
  include Higgs
256
343
 
257
344
  # for ident(1)
258
- CVS_ID = '$Id: test_lock.rb 559 2007-09-25 15:20:20Z toki $'
345
+ CVS_ID = '$Id: test_lock.rb 652 2007-10-22 15:23:50Z toki $'
259
346
 
260
347
  def setup
261
348
  @lock_manager = FineGrainLockManager.new(:spin_lock_count => 10,
@@ -3,6 +3,7 @@
3
3
  require 'drb'
4
4
  require 'fileutils'
5
5
  require 'higgs/index'
6
+ require 'higgs/services'
6
7
  require 'higgs/storage'
7
8
  require 'logger'
8
9
  require 'test/unit'
@@ -30,7 +31,7 @@ module Higgs::Test
30
31
  include OnlineBackupParams
31
32
 
32
33
  # for ident(1)
33
- CVS_ID = '$Id: test_online_backup.rb 627 2007-10-12 07:10:13Z toki $'
34
+ CVS_ID = '$Id: test_online_backup.rb 655 2007-10-23 16:32:59Z toki $'
34
35
 
35
36
  def setup
36
37
  srand(0)
@@ -45,7 +46,7 @@ module Higgs::Test
45
46
  FileUtils.rm_rf(@restore_dir) # for debug
46
47
  FileUtils.mkdir_p(@restore_dir)
47
48
 
48
- @jlog_rotate_service_uri = 'druby://localhost:14142'
49
+ @remote_services_uri = 'druby://localhost:14142'
49
50
 
50
51
  @start_latch = File.join(@backup_dir, '.start')
51
52
  @stop_latch = File.join(@backup_dir, '.stop')
@@ -59,18 +60,19 @@ module Higgs::Test
59
60
  end
60
61
 
61
62
  def run_backup_storage
62
- # step 0: storage starts with jlog_rotate_service_uri option
63
- # (jlog_rotate_service_uri option is disabled by default)
64
63
  st = Storage.new(@backup_name,
65
64
  :jlog_rotate_max => 0,
66
65
  :jlog_rotate_size => COMMIT_ITEMS * MAX_ITEM_BYTES * LEAST_COMMITS_PER_ROTATION,
67
- :jlog_rotate_service_uri => @jlog_rotate_service_uri,
68
66
  :logger => proc{|path|
69
67
  logger = Logger.new(path, 1)
70
68
  logger.level = Logger::DEBUG
71
69
  logger
72
70
  })
73
71
 
72
+ # step 0: storage starts with remote services.
73
+ sv = RemoteServices.new(:remote_services_uri => @remote_services_uri,
74
+ :storage => st)
75
+
74
76
  begin
75
77
  FileUtils.touch(@start_latch)
76
78
  until (File.exist? @stop_latch)
@@ -103,17 +105,24 @@ module Higgs::Test
103
105
  st.verify
104
106
  ensure
105
107
  st.shutdown
108
+ sv.shutdown
106
109
  end
107
110
  end
108
111
  private :run_backup_storage
109
112
 
110
113
  def test_online_backup
111
114
  pid = fork{ run_backup_storage }
115
+ DRb.start_service
112
116
  begin
113
117
  until (File.exist? @start_latch)
114
118
  # spin lock
115
119
  end
116
- jlog_rotate_service = DRbObject.new_with_uri(@jlog_rotate_service_uri)
120
+ sv = DRbObject.new_with_uri(@remote_services_uri)
121
+ localhost_check_service = sv[:localhost_check_service_v1] or flunk
122
+ localhost_check_service.call{|check|
123
+ check.call
124
+ }
125
+ jlog_rotate_service = sv[:jlog_rotate_service_v1] or flunk
117
126
  sleep(UPTIME_SECONDS)
118
127
 
119
128
  # step 1: backup index
@@ -134,7 +143,7 @@ module Higgs::Test
134
143
  jlog_rotate_service.call(true)
135
144
 
136
145
  # step 4: backup old journal logs
137
- for path in Storage.rotate_entries("#{@backup_name}.jlog")
146
+ for path in Storage.rotated_entries("#{@backup_name}.jlog")
138
147
  FileUtils.cp(path, File.join(@restore_dir, File.basename(path)))
139
148
  FileUtils.rm(path)
140
149
  end
@@ -143,9 +152,9 @@ module Higgs::Test
143
152
  Storage.recover(@restore_name)
144
153
 
145
154
  # recovered files are same as original files.
146
- assert(FileUtils.cmp("#{@backup_name}.tar", "#{@restore_name}.tar"), 'data')
147
- assert_equal(Index.new.load("#{@backup_name}.idx").to_h,
148
- Index.new.load("#{@restore_name}.idx").to_h, 'index')
155
+ assert(FileUtils.cmp("#{@backup_name}.tar", "#{@restore_name}.tar"), 'DATA should be same.')
156
+ assert(Index.new.load("#{@backup_name}.idx").to_h ==
157
+ Index.new.load("#{@restore_name}.idx").to_h, 'INDEX should be same.')
149
158
  ensure
150
159
  FileUtils.touch(@stop_latch)
151
160
  FileUtils.touch(@end_latch)
@@ -0,0 +1,468 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'fileutils'
4
+ require 'higgs/dbm'
5
+ require 'higgs/storage'
6
+ require 'higgs/store'
7
+ require 'higgs/thread'
8
+ require 'higgs/tman'
9
+ require 'logger'
10
+ require 'test/unit'
11
+
12
+ module Higgs::Test
13
+ module ReplicationTest
14
+ include Higgs
15
+
16
+ # for ident(1)
17
+ CVS_ID = '$Id: test_tman.rb 662 2007-11-03 16:13:33Z toki $'
18
+
19
+ STORAGE_ITEMS = (ENV['STORAGE_ITEMS'] || '100').to_i
20
+ WARM_START_ITEMS = (ENV['WARM_START_ITEMS'] || '1000').to_i
21
+ MAX_ITEM_BYTES = (ENV['MAX_ITEM_BYTES'] || '16384').to_i
22
+ ITEM_CHARS = ('A'..'Z').to_a + ('a'..'z').to_a
23
+
24
+ def setup
25
+ srand(0)
26
+
27
+ @name = 'foo'
28
+
29
+ @src_dir = 'rep_src'
30
+ @src_name = File.join(@src_dir, @name)
31
+ FileUtils.rm_rf(@src_dir)
32
+ FileUtils.mkdir_p(@src_dir)
33
+
34
+ @dst_dir = 'rep_dst'
35
+ @dst_name = File.join(@dst_dir, @name)
36
+ FileUtils.rm_rf(@dst_dir)
37
+ FileUtils.mkdir_p(@dst_dir)
38
+
39
+ @jlog_apply_dir = 'rep_jlog'
40
+ FileUtils.rm_rf(@jlog_apply_dir)
41
+ FileUtils.mkdir_p(@jlog_apply_dir)
42
+
43
+ @logger = proc{|path|
44
+ logger = Logger.new(path, 1)
45
+ logger.level = Logger::DEBUG
46
+ logger
47
+ }
48
+
49
+ setup_storage
50
+ end
51
+
52
+ def teardown
53
+ shutdown_storage
54
+ FileUtils.rm_rf(@src_dir) unless $DEBUG
55
+ FileUtils.rm_rf(@dst_dir) unless $DEBUG
56
+ FileUtils.rm_rf(@jlog_apply_dir) unless $DEBUG
57
+ end
58
+
59
+ def move_jlog
60
+ for jlog in Storage.rotated_entries("#{@src_name}.jlog")
61
+ name = File.basename(jlog)
62
+ target = File.join(@jlog_apply_dir, name)
63
+ FileUtils.mv(jlog, target)
64
+ end
65
+ nil
66
+ end
67
+ private :move_jlog
68
+
69
+ def test_replication_basic
70
+ #### create ####
71
+
72
+ @src.transaction{|tx|
73
+ tx[:foo] = "Hello world.\n"
74
+ }
75
+ @dst.transaction{|tx|
76
+ assert(tx.empty?)
77
+ }
78
+
79
+ src_rotate_journal_log
80
+ move_jlog
81
+ @dst.apply_journal_log
82
+
83
+ @dst.transaction{|tx|
84
+ assert(! tx.empty?)
85
+ assert_equal([ :foo ], tx.keys)
86
+ assert_equal("Hello world.\n", tx[:foo])
87
+ }
88
+
89
+ #### set property ####
90
+
91
+ @src.transaction{|tx|
92
+ tx.set_property(:foo, 'bar', 'Banana')
93
+ }
94
+ @dst.transaction{|tx|
95
+ assert(! (tx.property? :foo, 'bar'))
96
+ }
97
+
98
+ src_rotate_journal_log
99
+ move_jlog
100
+ @dst.apply_journal_log
101
+
102
+ @dst.transaction{|tx|
103
+ assert((tx.property? :foo, 'bar'))
104
+ assert_equal('Banana', tx.property(:foo, 'bar'))
105
+ }
106
+
107
+ #### update property ####
108
+
109
+ @src.transaction{|tx|
110
+ tx.set_property(:foo, 'bar', 'Orange')
111
+ }
112
+ @dst.transaction{|tx|
113
+ assert((tx.property? :foo, 'bar'))
114
+ assert_equal('Banana', tx.property(:foo, 'bar'))
115
+ }
116
+
117
+ src_rotate_journal_log
118
+ move_jlog
119
+ @dst.apply_journal_log
120
+
121
+ @dst.transaction{|tx|
122
+ assert((tx.property? :foo, 'bar'))
123
+ assert_equal('Orange', tx.property(:foo, 'bar'))
124
+ }
125
+
126
+ #### delete property ####
127
+
128
+ @src.transaction{|tx|
129
+ tx.delete_property(:foo, 'bar')
130
+ }
131
+ @dst.transaction{|tx|
132
+ assert((tx.property? :foo, 'bar'))
133
+ assert_equal('Orange', tx.property(:foo, 'bar'))
134
+ }
135
+
136
+ src_rotate_journal_log
137
+ move_jlog
138
+ @dst.apply_journal_log
139
+
140
+ @dst.transaction{|tx|
141
+ assert(! (tx.property? :foo, 'bar'))
142
+ }
143
+
144
+ #### update ####
145
+
146
+ @src.transaction{|tx|
147
+ tx[:foo] = 'Apple'
148
+ }
149
+ @dst.transaction{|tx|
150
+ assert(! tx.empty?)
151
+ assert_equal([ :foo ], tx.keys)
152
+ assert_equal("Hello world.\n", tx[:foo])
153
+ }
154
+
155
+ src_rotate_journal_log
156
+ move_jlog
157
+ @dst.apply_journal_log
158
+
159
+ @dst.transaction{|tx|
160
+ assert(! tx.empty?)
161
+ assert_equal([ :foo ], tx.keys)
162
+ assert_equal('Apple', tx[:foo])
163
+ }
164
+
165
+ #### delete ####
166
+
167
+ @src.transaction{|tx|
168
+ tx.delete(:foo)
169
+ }
170
+ @dst.transaction{|tx|
171
+ assert(! tx.empty?)
172
+ assert_equal([ :foo ], tx.keys)
173
+ assert_equal('Apple', tx[:foo])
174
+ }
175
+
176
+ src_rotate_journal_log
177
+ move_jlog
178
+ @dst.apply_journal_log
179
+
180
+ @dst.transaction{|tx|
181
+ assert(tx.empty?)
182
+ }
183
+
184
+ ####
185
+
186
+ shutdown_storage
187
+
188
+ assert(FileUtils.cmp("#{@src_name}.tar", "#{@dst_name}.tar"), 'DATA should be same.')
189
+ assert(Index.new.load("#{@src_name}.idx").to_h ==
190
+ Index.new.load("#{@dst_name}.idx").to_h, 'INDEX should be same.')
191
+ end
192
+
193
+ def update_source_storage(options)
194
+ count = 0
195
+ operations = [
196
+ :write_data,
197
+ :delete_data,
198
+ :write_system_properties,
199
+ :write_custom_properties,
200
+ :delete_custom_properties
201
+ ]
202
+ while (options[:spin_lock])
203
+ count += 1
204
+ options[:end_of_warm_up].start if (count == WARM_START_ITEMS)
205
+
206
+ ope = operations[rand(operations.length)]
207
+ key = rand(STORAGE_ITEMS)
208
+ case (ope)
209
+ when :write_data
210
+ value = rand(256).chr * rand(MAX_ITEM_BYTES)
211
+ @src.transaction{|tx|
212
+ tx[key] = value
213
+ }
214
+ when :delete_data
215
+ @src.transaction{|tx|
216
+ tx.delete(key)
217
+ }
218
+ when :write_system_properties
219
+ @src.transaction{|tx|
220
+ if (tx.key? key) then
221
+ tx.set_property(key, 'string_only', rand(2) > 0)
222
+ end
223
+ }
224
+ when :write_custom_properties
225
+ @src.transaction{|tx|
226
+ if (tx.key? key) then
227
+ value = ITEM_CHARS[rand(ITEM_CHARS.length)] * rand(MAX_ITEM_BYTES)
228
+ tx.set_property(key, 'foo', value)
229
+ end
230
+ }
231
+ when :delete_custom_properties
232
+ @src.transaction{|tx|
233
+ if (tx.key? key) then
234
+ tx.delete_property(key, 'foo')
235
+ end
236
+ }
237
+ else
238
+ raise "unknown operation: #{ope}"
239
+ end
240
+ end
241
+ end
242
+ private :update_source_storage
243
+
244
+ def test_update_source_storage
245
+ options = {
246
+ :end_of_warm_up => Latch.new,
247
+ :spin_lock => true
248
+ }
249
+ t = Thread.new{ update_source_storage(options) }
250
+ options[:end_of_warm_up].wait
251
+ options[:spin_lock] = false
252
+ t.join
253
+ end
254
+
255
+ def test_replication_with_multithread
256
+ options = {
257
+ :end_of_warm_up => Latch.new,
258
+ :spin_lock => true
259
+ }
260
+ t = Thread.new{ update_source_storage(options) }
261
+ options[:end_of_warm_up].wait
262
+
263
+ 10.times do
264
+ sleep(0.01)
265
+ move_jlog
266
+ @dst.apply_journal_log
267
+ end
268
+
269
+ options[:spin_lock] = false
270
+ t.join
271
+
272
+ src_rotate_journal_log
273
+ move_jlog
274
+ @dst.apply_journal_log
275
+
276
+ shutdown_storage
277
+
278
+ assert(FileUtils.cmp("#{@src_name}.tar", "#{@dst_name}.tar"), 'DATA should be same.')
279
+ assert(Index.new.load("#{@src_name}.idx").to_h ==
280
+ Index.new.load("#{@dst_name}.idx").to_h, 'INDEX should be same.')
281
+ end
282
+
283
+ def test_switch_to_write
284
+ # check standby mode
285
+ assert_equal(:standby, @dst.read_only)
286
+ @dst.transaction{|tx|
287
+ assert_raise(NoMethodError) { tx[:foo] = "Hello world.\n" }
288
+ assert_raise(NoMethodError) { tx.set_property(:foo, 'baz', 'orange') }
289
+ assert_raise(NoMethodError) { tx.delete_property(:foo, 'bar') }
290
+ assert_raise(NoMethodError) { tx.delete(:foo) }
291
+ assert_raise(NoMethodError) { tx.delete_if{|key, value| value == 'apple' } }
292
+ assert_raise(NoMethodError) { tx.clear }
293
+ assert_raise(NoMethodError) { tx.commit }
294
+ assert_raise(NoMethodError) { tx.rollback }
295
+ }
296
+ assert_raise(Higgs::Storage::NotWritableError) {
297
+ dst_rotate_journal_log
298
+ }
299
+
300
+ # replication enabled
301
+ test_update_source_storage
302
+ src_rotate_journal_log
303
+ move_jlog
304
+ @dst.apply_journal_log
305
+
306
+ # standby -> read-write
307
+ @dst.switch_to_write
308
+ assert_equal(false, @dst.read_only)
309
+
310
+ # replication disabled
311
+ test_update_source_storage
312
+ src_rotate_journal_log
313
+ move_jlog
314
+ assert_raise(RuntimeError) {
315
+ @dst.apply_journal_log
316
+ }
317
+
318
+ # check read-write
319
+ @dst.transaction{|tx|
320
+ tx[:foo] = "Hello world.\n"
321
+ tx.set_property(:foo, 'baz', 'orange')
322
+ tx.delete_property(:foo, 'bar')
323
+ tx.delete(:foo)
324
+ tx.delete_if{|key, value| value == 'apple' }
325
+ tx.clear
326
+ tx.commit
327
+ tx.rollback
328
+ }
329
+ dst_rotate_journal_log
330
+ end
331
+
332
+ def test_switch_to_write_RuntimeError_not_standby_mode
333
+ assert_equal(false, @src.read_only)
334
+ assert_raise(RuntimeError) {
335
+ @src.switch_to_write
336
+ }
337
+ end
338
+ end
339
+
340
+ class TransactionManagerReplicationTest < Test::Unit::TestCase
341
+ include Higgs
342
+ include ReplicationTest
343
+
344
+ # for ident(1)
345
+ CVS_ID = '$Id: test_tman.rb 662 2007-11-03 16:13:33Z toki $'
346
+
347
+ def setup_storage
348
+ @src_st = Storage.new(@src_name,
349
+ :logger => @logger,
350
+ :jlog_rotate_max => 0)
351
+
352
+ @src_st.rotate_journal_log(true)
353
+ FileUtils.cp("#{@src_name}.tar", "#{@dst_name}.tar", :preserve => true)
354
+ FileUtils.cp("#{@src_name}.idx", "#{@dst_name}.idx", :preserve => true)
355
+
356
+ @dst_st = Storage.new(@dst_name,
357
+ :logger => @logger,
358
+ :read_only => :standby)
359
+
360
+ for jlog_path in Storage.rotated_entries("#{@src_name}.jlog")
361
+ @dst_st.apply_journal_log(jlog_path)
362
+ end
363
+
364
+ @src = TransactionManager.new(@src_st)
365
+ @dst = TransactionManager.new(@dst_st,
366
+ :read_only => :standby,
367
+ :jlog_apply_dir => @jlog_apply_dir)
368
+ end
369
+
370
+ def shutdown_storage
371
+ @src_st.shutdown if (@src_st && ! @src_st.shutdown?)
372
+ @dst_st.shutdown if (@dst_st && ! @dst_st.shutdown?)
373
+ end
374
+
375
+ def src_rotate_journal_log
376
+ @src_st.rotate_journal_log
377
+ end
378
+
379
+ def dst_rotate_journal_log
380
+ @dst_st.rotate_journal_log
381
+ end
382
+ end
383
+
384
+ class StoreReplicationTest < Test::Unit::TestCase
385
+ include Higgs
386
+ include ReplicationTest
387
+
388
+ # for ident(1)
389
+ CVS_ID = '$Id$'
390
+
391
+ def setup_storage
392
+ @src = Store.new(@src_name,
393
+ :logger => @logger,
394
+ :jlog_rotate_max => 0)
395
+
396
+ @src.rotate_journal_log(true)
397
+ FileUtils.cp("#{@src_name}.tar", "#{@dst_name}.tar", :preserve => true)
398
+ FileUtils.cp("#{@src_name}.idx", "#{@dst_name}.idx", :preserve => true)
399
+
400
+ @dst = Store.new(@dst_name,
401
+ :logger => @logger,
402
+ :read_only => :standby,
403
+ :jlog_apply_dir => @jlog_apply_dir)
404
+
405
+ for jlog_path in Storage.rotated_entries("#{@src_name}.jlog")
406
+ @dst.apply_journal_log(jlog_path)
407
+ end
408
+ end
409
+
410
+ def shutdown_storage
411
+ @src.shutdown if (@src && ! @src.shutdown?)
412
+ @dst.shutdown if (@dst && ! @dst.shutdown?)
413
+ end
414
+
415
+ def src_rotate_journal_log
416
+ @src.rotate_journal_log
417
+ end
418
+
419
+ def dst_rotate_journal_log
420
+ @dst.rotate_journal_log
421
+ end
422
+ end
423
+
424
+ class DBMReplicationTest < Test::Unit::TestCase
425
+ include Higgs
426
+ include ReplicationTest
427
+
428
+ # for ident(1)
429
+ CVS_ID = '$Id$'
430
+
431
+ def setup_storage
432
+ @src = DBM.new(@src_name,
433
+ :logger => @logger,
434
+ :jlog_rotate_max => 0)
435
+
436
+ @src.rotate_journal_log(true)
437
+ FileUtils.cp("#{@src_name}.tar", "#{@dst_name}.tar", :preserve => true)
438
+ FileUtils.cp("#{@src_name}.idx", "#{@dst_name}.idx", :preserve => true)
439
+
440
+ @dst = DBM.new(@dst_name,
441
+ :logger => @logger,
442
+ :read_only => :standby,
443
+ :jlog_apply_dir => @jlog_apply_dir)
444
+
445
+ for jlog_path in Storage.rotated_entries("#{@src_name}.jlog")
446
+ @dst.apply_journal_log(jlog_path)
447
+ end
448
+ end
449
+
450
+ def shutdown_storage
451
+ @src.shutdown if (@src && ! @src.shutdown?)
452
+ @dst.shutdown if (@dst && ! @dst.shutdown?)
453
+ end
454
+
455
+ def src_rotate_journal_log
456
+ @src.rotate_journal_log
457
+ end
458
+
459
+ def dst_rotate_journal_log
460
+ @dst.rotate_journal_log
461
+ end
462
+ end
463
+ end
464
+
465
+ # Local Variables:
466
+ # mode: Ruby
467
+ # indent-tabs-mode: nil
468
+ # End: