higgs 0.1.0 → 0.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.
@@ -1,8 +1,8 @@
1
1
  # = backup manager
2
2
  #
3
3
  # Author:: $Author: toki $
4
- # Date:: $Date: 2007-09-26 00:20:20 +0900 (Wed, 26 Sep 2007) $
5
- # Revision:: $Revision: 559 $
4
+ # Date:: $Date: 2007-10-08 22:10:08 +0900 (Mon, 08 Oct 2007) $
5
+ # Revision:: $Revision: 621 $
6
6
  #
7
7
  # == license
8
8
  # :include:LICENSE
@@ -10,6 +10,7 @@
10
10
 
11
11
  require 'drb'
12
12
  require 'fileutils'
13
+ require 'higgs/flock'
13
14
  require 'higgs/storage'
14
15
 
15
16
  module Higgs
@@ -31,22 +32,24 @@ module Higgs
31
32
  # simple online-backup is like this...
32
33
  #
33
34
  # % higgs_backup -v -f foo -t backup_dir -u druby://localhost:17320
34
- # 2007-09-23 03:00:08.925 [23706]: **** START BACKUP SCENARIO ****
35
- # 2007-09-23 03:00:08.936 [23706]: start index backup.
36
- # 2007-09-23 03:00:09.331 [23706]: completed index backup.
37
- # 2007-09-23 03:00:09.333 [23706]: start data backup.
38
- # 2007-09-23 03:09:16.663 [23706]: completed data backup.
39
- # 2007-09-23 03:09:16.692 [23706]: start journal log rotation.
40
- # 2007-09-23 03:09:17.153 [23706]: completed journal log rotation.
41
- # 2007-09-23 03:09:17.154 [23706]: start journal logs backup.
42
- # 2007-09-23 03:09:17.205 [23706]: completed journal logs backup.
43
- # 2007-09-23 03:09:17.206 [23706]: start backup storage recovery.
44
- # 2007-09-23 03:09:17.798 [23706]: completed backup storage recovery.
45
- # 2007-09-23 03:09:17.799 [23706]: start backup storage verify.
46
- # 2007-09-23 03:25:44.122 [23706]: completed backup storage verify.
47
- # 2007-09-23 03:25:44.140 [23706]: start journal logs clean.
48
- # 2007-09-23 03:25:44.541 [23706]: completed journal logs clean.
49
- # 2007-09-23 03:25:44.542 [23706]: **** COMPLETED BACKUP SCENARIO ****
35
+ # 2007-10-03 00:32:58.117 [7558]: **** START BACKUP SCENARIO ****
36
+ # 2007-10-03 00:32:58.118 [7558]: start index backup.
37
+ # 2007-10-03 00:32:58.550 [7558]: completed index backup.
38
+ # 2007-10-03 00:32:58.551 [7558]: start data backup.
39
+ # 2007-10-03 00:42:00.637 [7558]: completed data backup.
40
+ # 2007-10-03 00:42:00.665 [7558]: start journal log rotation.
41
+ # 2007-10-03 00:42:00.907 [7558]: completed journal log rotation.
42
+ # 2007-10-03 00:42:00.909 [7558]: start journal logs backup.
43
+ # 2007-10-03 00:42:00.958 [7558]: completed journal logs backup.
44
+ # 2007-10-03 00:42:00.959 [7558]: start backup storage recovery.
45
+ # 2007-10-03 00:42:01.550 [7558]: completed backup storage recovery.
46
+ # 2007-10-03 00:42:01.552 [7558]: start backup storage verify.
47
+ # 2007-10-03 00:58:56.885 [7558]: completed backup storage verify.
48
+ # 2007-10-03 00:58:56.904 [7558]: start journal logs clean of from-storage.
49
+ # 2007-10-03 00:58:56.954 [7558]: completed jounal logs clean of from-storage.
50
+ # 2007-10-03 00:58:56.955 [7558]: start journal logs clean of to-storage.
51
+ # 2007-10-03 00:58:56.977 [7558]: completed jounal logs clean of to-storage.
52
+ # 2007-10-03 00:58:56.978 [7558]: **** COMPLETED BACKUP SCENARIO ****
50
53
  #
51
54
  # online-backup scenario includes these processes.
52
55
  #
@@ -56,32 +59,48 @@ module Higgs
56
59
  # 4. journal logs backup. see Higgs::Utils::BackupManager#backup_jlog.
57
60
  # 5. backup storage recovery. see Higgs::Utils::BackupManager#recover.
58
61
  # 6. backup storage verify. see Higgs::Utils::BackupManager#verify.
59
- # 7. journal logs clean. see Higgs::Utils::BackupManager#clean_jlog.
62
+ # 7. journal logs clean of from-storage. see Higgs::Utils::BackupManager#clean_jlog_from.
63
+ # 8. journal logs clean of to-storage. see Higgs::Utils::BackupManager#clean_jlog_to.
60
64
  #
61
65
  # == restore from online-backup
62
- # === 0. situation
63
- # storage name is `foo' and backup directory is `backup_dir'.
64
66
  #
65
- # === 1. recovery from last online-backup
66
- # run these commands.
67
- # % cp -p backup_dir/foo.idx foo.idx
68
- # % cp -p backup_dir/foo.tar foo.tar
69
- # % higgs_backup -t . -n foo --command recover
67
+ # simple restore is like this...
70
68
  #
71
- # === 2. apply last journal log
72
- # if system is aborted then last journal log is broken.
73
- # Higgs::Storage applies last jounal log to a readable point at
74
- # the read-write open.
69
+ # % higgs_backup -f images -t ~/misc/photon/dat/1 -v restore
70
+ # 2007-10-08 20:56:07.048 [18133]: **** START RESTORE SCENARIO ****
71
+ # 2007-10-08 20:56:07.066 [18133]: start storage files restore.
72
+ # 2007-10-08 21:09:49.614 [18133]: completed storage files restore.
73
+ # 2007-10-08 21:09:49.614 [18133]: start restored storage recovery.
74
+ # 2007-10-08 21:09:51.090 [18133]: completed restored storage recovery.
75
+ # 2007-10-08 21:09:51.093 [18133]: start restored storage verify.
76
+ # 2007-10-08 21:13:26.521 [18133]: completed restored storage verify.
77
+ # 2007-10-08 21:13:26.521 [18133]: **** COMPLETED RESTORE SCENARIO ****
75
78
  #
76
- # <em>WARNING.</em> Higgs::Storage is normal shutdown and last
77
- # journal log is not broken. last journal log is not applied and
78
- # storage data is old version. <em>this situation is inconsistent.</em>
79
+ # restore scenario includes these processes.
80
+ #
81
+ # 1. storage files restore. see Higgs::Utils::BackupManager#restore_files.
82
+ # 2. restored storage recovery. see Higgs::Utils::BackupManager#restore_recover.
83
+ # 3. restored storage verify. see Higgs::Utils::BackupManager#restore_verify.
79
84
  #
80
85
  # == command-line options
81
86
  #
82
87
  # % higgs_backup --help
83
- # Usage: higgs_backup [options]
84
- # --command=BACKUP_COMMAND
88
+ # Usage: higgs_backup [OPTIONs] [COMMANDs]
89
+ # COMMANDs:
90
+ # online_backup
91
+ # index
92
+ # data
93
+ # rotate
94
+ # jlog
95
+ # recover
96
+ # verify
97
+ # clean_from
98
+ # clean_to
99
+ # restore
100
+ # restore_files
101
+ # restore_recover
102
+ # restore_verify
103
+ # OPTIONs:
85
104
  # -f, --from=BACKUP_TARGET_STORAGE
86
105
  # -t, --to-dir=DIR_TO_BACKUP
87
106
  # -n, --to-name=NAME_TO_BACKUP
@@ -90,9 +109,9 @@ module Higgs
90
109
  # -v, --verbose, --[no-]verbose
91
110
  # --verbose-level=LEVEL
92
111
  #
93
- # === option: <tt>--command=BACKUP_COMMAND</tt>
112
+ # === COMMANDs
94
113
  # select a process of online-backup.
95
- # <tt>BACKUP_COMMAND</tt>s are these.
114
+ # COMMANDs for online-backup are these.
96
115
  #
97
116
  # <tt>online_backup</tt>:: default. run online-backup scenario.
98
117
  # see Higgs::Utils::BackupManager#online_backup.
@@ -102,33 +121,44 @@ module Higgs
102
121
  # <tt>jlog</tt>:: journal logs backup. see Higgs::Utils::BackupManager#backup_jlog.
103
122
  # <tt>recover</tt>:: backup storage recovery. see Higgs::Utils::BackupManager#recover.
104
123
  # <tt>verify</tt>:: backup storage verify. see Higgs::Utils::BackupManager#verify.
105
- # <tt>clean</tt>:: journal logs clean. see Higgs::Utils::BackupManager#clean_jlog.
124
+ # <tt>clean_from</tt>:: journal logs clean. see Higgs::Utils::BackupManager#clean_jlog_from.
125
+ # <tt>clean_to</tt>:: journal logs clean. see Higgs::Utils::BackupManager#clean_jlog_to.
126
+ #
127
+ # COMMANDs for restore are these.
128
+ #
129
+ # <tt>restore</tt>:: run restore scenario. see Higgs::Utils::BackupManager#restore.
130
+ # <tt>restore_files</tt>:: storage files restore.
131
+ # see Higgs::Utils::BackupManager#restore_files.
132
+ # <tt>restore_recover</tt>:: restored storage recovery.
133
+ # see Higgs::Utils::BackupManager#restore_recover.
134
+ # <tt>restore_verify</tt>:: restored storage verify.
135
+ # see Higgs::Utils::BackupManager#restore_verify.
106
136
  #
107
- # === option: <tt>--from=BACKUP_TARGET_STORAGE</tt>
137
+ # === OPTION: <tt>--from=BACKUP_TARGET_STORAGE</tt>
108
138
  # <tt>BACKUP_TARGET_STORAGE</tt> is the name of backup target storage.
109
139
  #
110
- # === option: <tt>--to-dir=DIR_TO_BACKUP</tt>
140
+ # === OPTION: <tt>--to-dir=DIR_TO_BACKUP</tt>
111
141
  # backuped storage is copied to the directory of <tt>DIR_TO_BACKUP</tt>.
112
142
  #
113
- # === option: <tt>--to-name=NAME_TO_BACKUP</tt>
114
- # <tt>NAME_to_BACKUP</tt> is the name of backuped storage.
143
+ # === OPTION: <tt>--to-name=NAME_TO_BACKUP</tt>
144
+ # <tt>NAME_TO_BACKUP</tt> is the name of backuped storage.
115
145
  # if this option is omitted then <tt>NAME_TO_BACKUP</tt> is the same
116
146
  # as <tt>BACKUP_TARGET_STORAGE</tt>.
117
147
  #
118
- # === option: <tt>--jlog-rotate-service-uri=URI</tt>
148
+ # === OPTION: <tt>--jlog-rotate-service-uri=URI</tt>
119
149
  # access point journal log rotation remote service.
120
150
  # <tt>URI</tt> is the same as <tt>:jlog_rotate_service_uri</tt>
121
151
  # when Higgs::Storage is opened.
122
152
  #
123
- # === option: <tt>--verbose</tt>
153
+ # === OPTION: <tt>--verbose</tt>
124
154
  # verbose level up.
125
155
  #
126
- # === option: <tt>--verbose-level=LEVEL</tt>
156
+ # === OPTION: <tt>--verbose-level=LEVEL</tt>
127
157
  # set verbose level to <tt>LEVEL</tt>.
128
158
  #
129
159
  class BackupManager
130
160
  # for ident(1)
131
- CVS_ID = '$Id: bman.rb 559 2007-09-25 15:20:20Z toki $'
161
+ CVS_ID = '$Id: bman.rb 621 2007-10-08 13:10:08Z toki $'
132
162
 
133
163
  def initialize(options={})
134
164
  @from = options[:from]
@@ -201,7 +231,7 @@ module Higgs
201
231
  unless (@to) then
202
232
  raise 'required to_storage'
203
233
  end
204
- for path in Storage.rotate_entries(@from + '.jlog')
234
+ for path in Storage.rotate_entries("#{@from}.jlog")
205
235
  path =~ /\.jlog\.\d+$/ or raise "mismatch jlog name: #{path}"
206
236
  ext = $&
207
237
  FileUtils.cp(path, "#{@to}#{ext}", :preserve => true, :verbose => @verbose >= 2)
@@ -235,8 +265,8 @@ module Higgs
235
265
  nil
236
266
  end
237
267
 
238
- def clean_jlog
239
- @out << log('start journal logs clean.') if (@verbose >= 1)
268
+ def clean_jlog_from
269
+ @out << log('start journal logs clean of from-storage.') if (@verbose >= 1)
240
270
 
241
271
  unless (@from) then
242
272
  raise 'required from_storage'
@@ -254,11 +284,22 @@ module Higgs
254
284
  end
255
285
  end
256
286
 
287
+ @out << log('completed jounal logs clean of from-storage.') if (@verbose >= 1)
288
+ nil
289
+ end
290
+
291
+ def clean_jlog_to
292
+ @out << log('start journal logs clean of to-storage.') if (@verbose >= 1)
293
+
294
+ unless (@to) then
295
+ raise 'required to_storage'
296
+ end
297
+
257
298
  for to_jlog in Storage.rotate_entries("#{@to}.jlog")
258
299
  FileUtils.rm(to_jlog, :verbose => @verbose >= 2)
259
300
  end
260
301
 
261
- @out << log('completed journal logs clean.') if (@verbose >= 1)
302
+ @out << log('completed jounal logs clean of to-storage.') if (@verbose >= 1)
262
303
  nil
263
304
  end
264
305
 
@@ -271,10 +312,67 @@ module Higgs
271
312
  backup_jlog
272
313
  recover
273
314
  verify
274
- clean_jlog
315
+ clean_jlog_from
316
+ clean_jlog_to
275
317
  @out << log('**** COMPLETED BACKUP SCENARIO ****') if (@verbose >= 1)
276
318
  nil
277
319
  end
320
+
321
+ def restore_files
322
+ @out << log('start storage files restore.') if (@verbose >= 1)
323
+ unless (@from) then
324
+ raise 'required from_storage'
325
+ end
326
+ unless (@to) then
327
+ raise 'required to_storage'
328
+ end
329
+ FileLock.new("#{@from}.lock").synchronize{
330
+ FileUtils.cp("#{@to}.idx", "#{@from}.idx", :preserve => true, :verbose => @verbose >= 2)
331
+ FileUtils.cp("#{@to}.tar", "#{@from}.tar", :preserve => true, :verbose => @verbose >= 2)
332
+ for path in Storage.rotate_entries("#{@to}.jlog")
333
+ path =~ /\.jlog\.\d+$/ or raise "mismatch jlog name: #{path}"
334
+ ext = $&
335
+ FileUtils.cp(path, "#{@from}#{ext}", :preserve => true, :verbose => @verbose >= 2)
336
+ end
337
+ }
338
+ @out << log('completed storage files restore.') if (@verbose >= 1)
339
+ nil
340
+ end
341
+
342
+ def restore_recover
343
+ @out << log('start restored storage recovery.') if (@verbose >= 1)
344
+ unless (@from) then
345
+ raise 'required from_storage'
346
+ end
347
+ Storage.recover(@from, @out, @verbose - 1)
348
+ @out << log('completed restored storage recovery.') if (@verbose >= 1)
349
+ nil
350
+ end
351
+
352
+ def restore_verify
353
+ @out << log('start restored storage verify.') if (@verbose >= 1)
354
+ unless (@from) then
355
+ raise 'required from_storage'
356
+ end
357
+ st = Storage.new(@from) # read-write open for recovery
358
+ begin
359
+ st.verify(@out, @verbose - 1)
360
+ ensure
361
+ st.shutdown
362
+ end
363
+ @out << log('completed restored storage verify.') if (@verbose >= 1)
364
+ nil
365
+ end
366
+
367
+ # run restore scenario
368
+ def restore
369
+ @out << log('**** START RESTORE SCENARIO ****') if (@verbose >= 1)
370
+ restore_files
371
+ restore_recover
372
+ restore_verify
373
+ @out << log('**** COMPLETED RESTORE SCENARIO ****') if (@verbose >= 1)
374
+ nil
375
+ end
278
376
  end
279
377
  end
280
378
  end
data/lib/higgs/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # = version
2
2
  #
3
3
  # Author:: $Author: toki $
4
- # Date:: $Date: 2007-09-29 18:06:25 +0900 (Sat, 29 Sep 2007) $
5
- # Revision:: $Revision: 578 $
4
+ # Date:: $Date: 2007-10-08 22:16:13 +0900 (Mon, 08 Oct 2007) $
5
+ # Revision:: $Revision: 622 $
6
6
  #
7
7
  # == license
8
8
  # :include:LICENSE
@@ -10,9 +10,9 @@
10
10
 
11
11
  module Higgs
12
12
  # for ident(1)
13
- CVS_ID = '$Id: version.rb 578 2007-09-29 09:06:25Z toki $'
13
+ CVS_ID = '$Id: version.rb 622 2007-10-08 13:16:13Z toki $'
14
14
 
15
- VERSION = '0.1.0'
15
+ VERSION = '0.1.1'
16
16
  end
17
17
 
18
18
  # Local Variables:
data/mkrdoc.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/local/bin/ruby
2
2
 
3
- CVS_ID = '$Id: mkrdoc.rb 564 2007-09-27 16:10:25Z toki $' # for ident(1)
3
+ # for ident(1)
4
+ CVS_ID = '$Id: mkrdoc.rb 604 2007-10-02 15:28:03Z toki $'
4
5
 
6
+ require 'fileutils'
5
7
  require 'yaml'
6
8
 
7
9
  rdoc_opts = YAML.load(IO.read('rdoc.yml'))
8
- system 'rdoc', *(rdoc_opts['CommonOptions'] + rdoc_opts['CommandLineOptions']).flatten
10
+ FileUtils.rm_rf(rdoc_opts['CommandLineOptions'].assoc('-o')[1], :verbose => true)
11
+ system('rdoc', *(rdoc_opts['CommonOptions'] + rdoc_opts['CommandLineOptions']).flatten)
data/test/test_block.rb CHANGED
@@ -10,7 +10,7 @@ module Higgs::Test
10
10
  include Higgs::Block
11
11
 
12
12
  # for ident(1)
13
- CVS_ID = '$Id: test_block.rb 559 2007-09-25 15:20:20Z toki $'
13
+ CVS_ID = '$Id: test_block.rb 591 2007-09-30 06:20:15Z toki $'
14
14
 
15
15
  def setup
16
16
  @io = File.open('block.test_io', 'w+')
@@ -154,6 +154,64 @@ module Higgs::Test
154
154
  block_read(@io, 'FOO')
155
155
  }
156
156
  end
157
+
158
+ def test_head_write_BrokenError_short_write
159
+ def @io.write(*args)
160
+ super
161
+ 0
162
+ end
163
+
164
+ body = 'foo'
165
+ body_cksum_bin = Digest::SHA512.digest(body)
166
+ assert_raise(BrokenError) {
167
+ head_write(@io, 'FOO', body.length, 'SHA512', body_cksum_bin)
168
+ }
169
+ end
170
+
171
+ def test_block_write_body_BrokenError_short_write
172
+ def @io.write(*args)
173
+ @count = 0 unless @count
174
+ @count += 1
175
+ r = super(*args)
176
+ case (@count)
177
+ when 1
178
+ return r
179
+ else
180
+ return 0
181
+ end
182
+ end
183
+
184
+ body = 'foo'
185
+ assert_raise(BrokenError) {
186
+ block_write(@io, 'FOO', body)
187
+ }
188
+ end
189
+
190
+ def test_block_write_padding_BrokenError_short_write
191
+ def @io.write(*args)
192
+ @count = 0 unless @count
193
+ @count += 1
194
+ r = super(*args)
195
+ case (@count)
196
+ when 1, 2
197
+ return r
198
+ else
199
+ return 0
200
+ end
201
+ end
202
+
203
+ body = 'foo'
204
+ assert_raise(BrokenError) {
205
+ block_write(@io, 'FOO', body)
206
+ }
207
+ end
208
+
209
+ def test_block_write_ArgumentError_unknown_body_hash_type
210
+ body = 'foo'
211
+ assert_raise(ArgumentError) {
212
+ block_write(@io, 'FOO', body, :UNKNWON)
213
+ }
214
+ end
157
215
  end
158
216
  end
159
217
 
data/test/test_cache.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_cache.rb 559 2007-09-25 15:20:20Z toki $'
13
+ CVS_ID = '$Id: test_cache.rb 588 2007-09-30 05:39:54Z toki $'
14
14
 
15
15
  CACHE_LIMIT_SIZE = 10
16
16
 
@@ -84,7 +84,7 @@ module Higgs::Test
84
84
  include Higgs
85
85
 
86
86
  # for ident(1)
87
- CVS_ID = '$Id: test_cache.rb 559 2007-09-25 15:20:20Z toki $'
87
+ CVS_ID = '$Id: test_cache.rb 588 2007-09-30 05:39:54Z toki $'
88
88
 
89
89
  def setup
90
90
  @calc_calls = 0
@@ -192,13 +192,27 @@ module Higgs::Test
192
192
  assert_equal(2, @calc_calls, "#{n}th")
193
193
  end
194
194
  end
195
+
196
+ def test_store
197
+ @cache[WORK_COUNT] = 0
198
+ assert_equal(0, @cache[WORK_COUNT])
199
+ assert_equal(0, @calc_calls, 'no call')
200
+ end
201
+
202
+ def test_store_overwrite
203
+ assert(@cache[WORK_COUNT] != 0)
204
+ assert_equal(1, @calc_calls)
205
+ @cache[WORK_COUNT] = 0
206
+ assert_equal(0, @cache[WORK_COUNT])
207
+ assert_equal(1, @calc_calls)
208
+ end
195
209
  end
196
210
 
197
211
  class SharedWorkCacheNoWorkBlockTest < Test::Unit::TestCase
198
212
  include Higgs
199
213
 
200
214
  # for ident(1)
201
- CVS_ID = '$Id: test_cache.rb 559 2007-09-25 15:20:20Z toki $'
215
+ CVS_ID = '$Id: test_cache.rb 588 2007-09-30 05:39:54Z toki $'
202
216
 
203
217
  def test_no_work_block
204
218
  assert_raise(RuntimeError) {
data/test/test_dbm.rb ADDED
@@ -0,0 +1,163 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'fileutils'
4
+ require 'higgs/dbm'
5
+ require 'logger'
6
+ require 'test/unit'
7
+
8
+ module Higgs::Test
9
+ class DBMTest < Test::Unit::TestCase
10
+ include Higgs
11
+
12
+ # for ident(1)
13
+ CVS_ID = '$Id: test_dbm.rb 597 2007-10-01 15:21:47Z toki $'
14
+
15
+ def setup
16
+ @test_dir = 'dbm_test'
17
+ FileUtils.rm_rf(@test_dir) # for debug
18
+ FileUtils.mkdir_p(@test_dir)
19
+ @name = File.join(@test_dir, 'foo')
20
+ @db = DBM.new(@name,
21
+ :logger => proc{|path|
22
+ logger = Logger.new(path, 1)
23
+ logger.level = Logger::DEBUG
24
+ logger
25
+ })
26
+ end
27
+
28
+ def teardown
29
+ @db.shutdown unless @db.shutdown?
30
+ FileUtils.rm_rf(@test_dir) unless $DEBUG
31
+ end
32
+
33
+ def test_fetch_and_store
34
+ @db.transaction{|tx|
35
+ assert_equal(nil, tx['foo'])
36
+ assert_equal(nil, tx['bar'])
37
+
38
+ assert_equal(false, (tx.key? 'foo'))
39
+ assert_equal(false, (tx.key? 'bar'))
40
+
41
+ tx['foo'] = 'HALO'
42
+ tx['bar'] = ''
43
+
44
+ assert_equal('HALO', tx['foo'])
45
+ assert_equal('', tx['bar'])
46
+
47
+ assert_equal(true, (tx.key? 'foo'))
48
+ assert_equal(true, (tx.key? 'bar'))
49
+ }
50
+
51
+ @db.transaction{|tx|
52
+ assert_equal('HALO', tx['foo'])
53
+ assert_equal('', tx['bar'])
54
+
55
+ assert_equal(true, (tx.key? 'foo'))
56
+ assert_equal(true, (tx.key? 'bar'))
57
+ }
58
+ end
59
+
60
+ def test_store_TypeError_cant_convert_into_String
61
+ @db.transaction{|tx|
62
+ tx['foo'] = :foo
63
+ assert_raise(TypeError) { tx.commit }
64
+ tx.rollback
65
+ }
66
+ end
67
+
68
+ def test_update_no_use
69
+ @db.transaction{|tx|
70
+ tx['foo'] = ''
71
+ }
72
+
73
+ @db.transaction{|tx|
74
+ tx.update('foo') {|s|
75
+ assert_equal(true, s.frozen?)
76
+ assert_raise(TypeError) {
77
+ s << 'foo' << ',' << 'bar' << ',' << 'baz'
78
+ }
79
+ }
80
+
81
+ assert_equal('', tx['foo'], 'not updated')
82
+ }
83
+ end
84
+
85
+ def test_rollback
86
+ @db.transaction{|tx|
87
+ tx['foo'] = 'apple'
88
+ }
89
+
90
+ @db.transaction{|tx|
91
+ assert_equal('apple', tx['foo'])
92
+ tx['foo'] = 'banana'
93
+ assert_equal('banana', tx['foo'])
94
+ tx.rollback
95
+ assert_equal('apple', tx['foo'])
96
+ }
97
+
98
+ @db.transaction{|tx|
99
+ assert_equal('apple', tx['foo'])
100
+ }
101
+ end
102
+
103
+ def test_each_key
104
+ @db.transaction{|tx|
105
+ tx['foo'] = 'HALO'
106
+ tx['bar'] = ''
107
+
108
+ expected_keys = %w[ foo bar ]
109
+ tx.each_key do |key|
110
+ assert((expected_keys.include? key), key)
111
+ expected_keys.delete(key)
112
+ end
113
+ assert_equal([], expected_keys)
114
+ }
115
+
116
+ @db.transaction{|tx|
117
+ expected_keys = %w[ foo bar ]
118
+ tx.each_key do |key|
119
+ assert((expected_keys.include? key), key)
120
+ expected_keys.delete(key)
121
+ end
122
+ assert_equal([], expected_keys)
123
+ }
124
+ end
125
+ end
126
+
127
+ class DBMOpenTest < Test::Unit::TestCase
128
+ include Higgs
129
+
130
+ # for ident(1)
131
+ CVS_ID = '$Id: test_dbm.rb 597 2007-10-01 15:21:47Z toki $'
132
+
133
+ def setup
134
+ @test_dir = 'dbm_test'
135
+ FileUtils.rm_rf(@test_dir) # for debug
136
+ FileUtils.mkdir_p(@test_dir)
137
+ @name = File.join(@test_dir, 'foo')
138
+ end
139
+
140
+ def teardown
141
+ FileUtils.rm_rf(@test_dir) unless $DEBUG
142
+ end
143
+
144
+ def test_open
145
+ DBM.open(@name) {|db|
146
+ db.transaction{|tx|
147
+ tx['foo'] = 'apple'
148
+ }
149
+ }
150
+
151
+ DBM.open(@name, :read_only => true) {|db|
152
+ db.transaction{|tx|
153
+ assert_equal('apple', tx['foo'])
154
+ }
155
+ }
156
+ end
157
+ end
158
+ end
159
+
160
+ # Local Variables:
161
+ # mode: Ruby
162
+ # indent-tabs-mode: nil
163
+ # End: