sedna 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/CHANGES +18 -0
  2. data/README +35 -13
  3. data/Rakefile +3 -3
  4. data/ext/extconf.rb +4 -9
  5. data/ext/sedna.c +429 -118
  6. data/test/sedna_test.rb +447 -317
  7. metadata +2 -2
data/test/sedna_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
3
 
4
- # Copyright 2008 Voormedia B.V.
4
+ # Copyright 2008, 2009 Voormedia B.V.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -30,53 +30,42 @@ require 'socket'
30
30
  class SednaTest < Test::Unit::TestCase
31
31
  # Support declarative specification of test methods.
32
32
  def self.test name, &block
33
- test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
34
- defined = instance_method(test_name) rescue false
35
- raise "#{test_name} is already defined in #{self}" if defined
36
- if block_given?
37
- define_method test_name, &block
38
- else
39
- define_method test_name do
40
- flunk "No implementation provided for #{test_name}"
41
- end
42
- end
33
+ define_method "test_#{name.gsub(/\s+/,'_')}".to_sym, &block
43
34
  end
44
35
 
36
+ # Backward compatibility if __method__ is not available.
45
37
  alias :__method__ :method_name if method_defined? :method_name
46
38
 
47
- # Setup.
48
- def setup
49
- @connection = {
50
- :database => "test",
51
- :host => "localhost",
52
- :username => "SYSTEM",
53
- :password => "MANAGER",
54
- }
55
- end
39
+ @@spec = {
40
+ :database => "test",
41
+ :host => "localhost",
42
+ :username => "SYSTEM",
43
+ :password => "MANAGER",
44
+ }
45
+
46
+ # Test the remote socket before continuing.
47
+ port = 5050
48
+ begin
49
+ socket = TCPSocket.new @@spec[:host], port
50
+ rescue Errno::ECONNREFUSED, SocketError
51
+ # No DB appears to be running; fail fatally. Do not run the other tests and just exit.
52
+ puts "\nConnection to port #{port} on #{@@spec[:host]} could not be established.\nCheck if the Sedna XML database is running before running this test suite.\n\n"
53
+ exit 1
54
+ end
55
+ socket.close
56
+
57
+ # Create re-usable connection. Word of warning: because we re-use the connection,
58
+ # if one particular test screws it up, subsequent tests may fail.
59
+ @@sedna = Sedna.connect @@spec
56
60
 
57
- # Faux test that just checks if we can connect, otherwise the test
58
- # suite is aborted.
59
- test "aaa connection" do
60
- port = 5050
61
- begin
62
- s = TCPSocket.new @connection[:host], port
63
- rescue Errno::ECONNREFUSED, SocketError
64
- # No DB appears to be running; fail fatally. Do not run the other tests and just exit.
65
- puts "Connection to port #{port} on #{@connection[:host]} could not be established. Check if the Sedna XML database is running before running this test suite."
66
- exit 1
67
- end
68
- assert s
69
- s.close
70
- end
71
-
72
61
  # Test Sedna.version.
73
- test "version should return 3 0" do
62
+ test "version should return 3.0" do
74
63
  assert_equal "3.0", Sedna.version
75
64
  end
76
65
 
77
66
  # Test Sedna.blocking?
78
67
  test "blocking should return true if ruby 18 and false if ruby 19" do
79
- if RUBY_VERSION < "1.9"
68
+ if RUBY_VERSION < "1.9.1"
80
69
  assert Sedna.blocking?
81
70
  else
82
71
  assert !Sedna.blocking?
@@ -85,7 +74,7 @@ class SednaTest < Test::Unit::TestCase
85
74
 
86
75
  # Test Sedna.connect.
87
76
  test "connect should return Sedna object" do
88
- sedna = Sedna.connect @connection
77
+ sedna = Sedna.connect @@spec
89
78
  assert_kind_of Sedna, sedna
90
79
  sedna.close
91
80
  end
@@ -98,32 +87,40 @@ class SednaTest < Test::Unit::TestCase
98
87
 
99
88
  test "connect should raise exception when host not found" do
100
89
  assert_raises Sedna::ConnectionError do
101
- Sedna.connect @connection.merge(:host => "non-existent-host")
90
+ Sedna.connect @@spec.merge(:host => "non-existent-host")
102
91
  end
103
92
  end
104
93
 
105
94
  test "connect should raise exception when credentials are incorrect" do
106
95
  assert_raises Sedna::AuthenticationError do
107
- Sedna.connect @connection.merge(:username => "non-existent-user")
96
+ Sedna.connect @@spec.merge(:username => "non-existent-user")
108
97
  end
109
98
  end
110
99
 
111
100
  test "connect should return nil on error" do
112
101
  begin
113
- sedna = Sedna.connect @connection.merge(:username => "non-existent-user")
102
+ sedna = Sedna.connect @@spec.merge(:username => "non-existent-user")
114
103
  rescue
115
104
  end
116
105
  assert_nil sedna
117
106
  end
118
107
 
108
+ test "connect should not execute block if connection fails" do
109
+ assert_nothing_raised do
110
+ sedna = Sedna.connect @@spec.merge(:username => "non-existent-user") do
111
+ raise "block should not be run"
112
+ end rescue nil
113
+ end
114
+ end
115
+
119
116
  test "connect should return nil if block given" do
120
- sedna = Sedna.connect @connection do |s| end
117
+ sedna = Sedna.connect @@spec do |s| end
121
118
  assert_nil sedna
122
119
  end
123
120
 
124
121
  test "connect should close connection after block" do
125
122
  sedna = nil
126
- Sedna.connect @connection do |s|
123
+ Sedna.connect @@spec do |s|
127
124
  sedna = s
128
125
  end
129
126
  assert_raises Sedna::ConnectionError do
@@ -134,7 +131,7 @@ class SednaTest < Test::Unit::TestCase
134
131
  test "connect should close connection if exception is raised inside block" do
135
132
  sedna = nil
136
133
  begin
137
- Sedna.connect @connection do |s|
134
+ Sedna.connect @@spec do |s|
138
135
  sedna = s
139
136
  raise Exception
140
137
  end
@@ -148,7 +145,7 @@ class SednaTest < Test::Unit::TestCase
148
145
  test "connect should close connection if something is thrown inside block" do
149
146
  sedna = nil
150
147
  catch :ball do
151
- Sedna.connect @connection do |s|
148
+ Sedna.connect @@spec do |s|
152
149
  sedna = s
153
150
  throw :ball
154
151
  end
@@ -160,69 +157,142 @@ class SednaTest < Test::Unit::TestCase
160
157
 
161
158
  test "connect should re-raise exceptions from inside block" do
162
159
  assert_raises Exception do
163
- Sedna.connect @connection do
160
+ Sedna.connect @@spec do
164
161
  raise Exception
165
162
  end
166
163
  end
167
164
  end
168
165
 
166
+ test "connect should set instance variables for keys in connection specification" do
167
+ assert_equal @@spec.values, @@spec.keys.collect { |k| @@sedna.instance_variable_get "@#{k.to_s}".to_sym }
168
+ end
169
+
169
170
  # Test sedna.close.
170
171
  test "close should return nil" do
171
- sedna = Sedna.connect @connection
172
+ sedna = Sedna.connect @@spec
172
173
  assert_nil sedna.close
173
174
  end
174
175
 
175
176
  test "close should fail silently if connection is already closed" do
176
- sedna = Sedna.connect @connection
177
+ sedna = Sedna.connect @@spec
177
178
  assert_nothing_raised do
178
179
  sedna.close
179
180
  sedna.close
180
181
  end
181
182
  end
182
183
 
183
- # Test sedna.execute / sedna.query.
184
- test "execute should raise TypeError if argument cannot be converted to String" do
185
- Sedna.connect @connection do |sedna|
186
- assert_raises TypeError do
187
- sedna.execute Object.new
184
+ # Test sedna.connected?.
185
+ test "connected? should return true if connected" do
186
+ assert_equal true, @@sedna.connected?
187
+ end
188
+
189
+ test "connected? should return false if closed" do
190
+ sedna = Sedna.connect @@spec
191
+ sedna.close
192
+ assert_equal false, sedna.connected?
193
+ end
194
+
195
+ # Test sedna.reset.
196
+ test "reset should return nil" do
197
+ assert_nil @@sedna.reset
198
+ end
199
+
200
+ test "reset should break current transaction" do
201
+ assert_raises Sedna::TransactionError do
202
+ @@sedna.transaction do
203
+ @@sedna.reset
188
204
  end
189
205
  end
190
206
  end
191
207
 
192
- test "execute should return nil for data structure query" do
193
- Sedna.connect @connection do |sedna|
194
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
195
- assert_nil sedna.execute("create document '#{__method__}'")
196
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
208
+ test "reset should implicitly roll back current transaction" do
209
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
210
+ @@sedna.execute "create document '#{__method__}'"
211
+ @@sedna.transaction do
212
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
213
+ @@sedna.reset
214
+ end rescue nil
215
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
216
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
217
+ end
218
+
219
+ test "reset should close and reconnect if the connection is open" do
220
+ @@sedna.reset
221
+ assert_nothing_raised do
222
+ @@sedna.execute "<test/>"
197
223
  end
198
224
  end
199
225
 
200
- test "execute should return array for select query" do
201
- Sedna.connect @connection do |sedna|
202
- assert_kind_of Array, sedna.execute("<test/>")
226
+ test "reset should reconnect if the connection is closed" do
227
+ @@sedna.close
228
+ @@sedna.reset
229
+ assert_nothing_raised do
230
+ @@sedna.execute "<test/>"
231
+ end
232
+ end
233
+
234
+ test "reset should raise exception when host not found" do
235
+ sedna = Sedna.connect @@spec
236
+ sedna.instance_variable_set :@host, "non-existent-host"
237
+ assert_raises Sedna::ConnectionError do
238
+ sedna.reset
239
+ end
240
+ end
241
+
242
+ test "reset should raise exception when credentials are incorrect" do
243
+ sedna = Sedna.connect @@spec
244
+ sedna.instance_variable_set :@username, "non-existent-user"
245
+ assert_raises Sedna::AuthenticationError do
246
+ sedna.reset
247
+ end
248
+ end
249
+
250
+ test "reset should preserve disabled autocommit status" do
251
+ Sedna.connect @@spec do |sedna|
252
+ sedna.autocommit = false
253
+ sedna.reset
254
+ assert_raises Sedna::Exception do
255
+ sedna.execute "<test/>"
256
+ end
203
257
  end
204
258
  end
205
259
 
206
- test "execute should return array with single string for single select query" do
207
- Sedna.connect @connection do |sedna|
208
- assert_equal ["<test/>"], sedna.execute("<test/>")
260
+ # Test sedna.execute / sedna.query.
261
+ test "execute should raise TypeError if argument cannot be converted to String" do
262
+ assert_raises TypeError do
263
+ @@sedna.execute Object.new
209
264
  end
210
265
  end
211
266
 
267
+ test "execute should return nil for data structure query" do
268
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
269
+ assert_nil @@sedna.execute("create document '#{__method__}'")
270
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
271
+ end
272
+
273
+ test "execute should return subclass of array for select query" do
274
+ assert_kind_of Array, @@sedna.execute("<test/>")
275
+ end
276
+
277
+ test "execute should return array with single string for single select query" do
278
+ assert_equal ["<test/>"], @@sedna.execute("<test/>")
279
+ end
280
+
212
281
  test "execute should return array with strings for select query" do
213
- Sedna.connect @connection do |sedna|
214
- assert_equal ["<test/>", "<test/>", "<test/>"], sedna.execute("<test/>, <test/>, <test/>")
215
- end
282
+ assert_equal ["<test/>", "<test/>", "<test/>"], @@sedna.execute("<test/>, <test/>, <test/>")
216
283
  end
217
284
 
218
285
  test "execute should return tainted strings" do
219
- Sedna.connect @connection do |sedna|
220
- assert sedna.execute("<test/>").first.tainted?
221
- end
286
+ assert @@sedna.execute("<test/>").first.tainted?
287
+ end
288
+
289
+ test "execute should return utf-8 strings" do
290
+ str = "<utf8> Ѩ 乗 </utf8>"
291
+ assert_equal [str], @@sedna.execute(str)
222
292
  end
223
293
 
224
294
  test "execute should fail if autocommit is false" do
225
- Sedna.connect @connection do |sedna|
295
+ Sedna.connect @@spec do |sedna|
226
296
  sedna.autocommit = false
227
297
  assert_raises Sedna::Exception do
228
298
  sedna.execute "<test/>"
@@ -231,15 +301,13 @@ class SednaTest < Test::Unit::TestCase
231
301
  end
232
302
 
233
303
  test "execute should fail with Sedna::Exception for invalid statements" do
234
- Sedna.connect @connection do |sedna|
235
- assert_raises Sedna::Exception do
236
- sedna.execute "INVALID"
237
- end
304
+ assert_raises Sedna::Exception do
305
+ @@sedna.execute "INVALID"
238
306
  end
239
307
  end
240
308
 
241
309
  test "execute should fail with Sedna::ConnectionError if connection is closed" do
242
- Sedna.connect @connection do |sedna|
310
+ Sedna.connect @@spec do |sedna|
243
311
  sedna.close
244
312
  assert_raises Sedna::ConnectionError do
245
313
  sedna.execute "<test/>"
@@ -248,165 +316,107 @@ class SednaTest < Test::Unit::TestCase
248
316
  end
249
317
 
250
318
  test "execute should strip first newline of all but first results" do
251
- Sedna.connect @connection do |sedna|
252
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
253
- sedna.execute("create document '#{__method__}'")
254
- sedna.execute("update insert <test><a>\n\nt</a><a>\n\nt</a><a>\n\nt</a></test> into doc('#{__method__}')")
255
- assert_equal ["\n\nt", "\n\nt", "\n\nt"], sedna.execute("doc('#{__method__}')/test/a/text()")
256
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
257
- end
319
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
320
+ @@sedna.execute("create document '#{__method__}'")
321
+ @@sedna.execute("update insert <test><a>\n\nt</a><a>\n\nt</a><a>\n\nt</a></test> into doc('#{__method__}')")
322
+ assert_equal ["\n\nt", "\n\nt", "\n\nt"], @@sedna.execute("doc('#{__method__}')/test/a/text()")
323
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
258
324
  end
259
325
 
260
- test "execute should block other threads for ruby 18 and not block for ruby 19" do
261
- n = 5 # Amount of threads to be run. Increase for more accuracy.
262
- i = 10000 # Times to loop in query. Increase for more accuracy.
326
+ test "execute should be run serially if called from different threads on same connection" do
327
+ i = 1000
263
328
  threads = []
264
- start_times = {}
265
- end_times = {}
266
- n.times do |number|
329
+ exceptions = []
330
+ Thread.abort_on_exception = true
331
+ 5.times do
267
332
  threads << Thread.new do
268
- Sedna.connect @connection do |sedna|
269
- start_times[number] = Time.now
270
- sedna.execute "for $x in 1 to #{i} where $x = 1 return <node/>"
271
- end_times[number] = Time.now
333
+ begin
334
+ @@sedna.execute "for $x in #{i} where $x = 1 return <node/>"
335
+ rescue StandardError => e
336
+ exceptions << e
272
337
  end
273
338
  end
274
339
  end
275
340
  threads.each do |thread| thread.join end
276
- # Count the amount of time that is overlapped between threads. If the execute
277
- # method blocks, there should be hardly any overlap.
278
- time_diff = 0
279
- (n - 1).times do |number|
280
- time_diff += start_times[number + 1] - end_times[number]
281
- end
282
- if RUBY_VERSION < "1.9"
283
- # Blocking behaviour. The start/end times of two threads should not overlap.
284
- assert time_diff > 0
285
- else
286
- # We have concurrency, the execute method in the threads should have been
287
- # run in parallel and there should be considerable overlap in the start/end
288
- # times of the executed threads.
289
- assert time_diff < 0
290
- end
291
- end
292
-
293
- test "execute should be run in serially if called from different threads on same connection" do
294
- Sedna.connect @connection do |sedna|
295
- i = 1000
296
- threads = []
297
- exceptions = []
298
- Thread.abort_on_exception = true
299
- 5.times do
300
- threads << Thread.new do
301
- begin
302
- sedna.execute "for $x in #{i} where $x = 1 return <node/>"
303
- rescue StandardError => e
304
- exceptions << e
305
- end
306
- end
307
- end
308
- threads.each do |thread| thread.join end
309
- assert_equal [], exceptions
310
- end
341
+ assert_equal [], exceptions
311
342
  end
312
343
 
313
344
  test "execute should quit if exception is raised in it by another thread in ruby 19" do
314
- Sedna.connect @connection do |sedna|
315
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
316
- begin
317
- thread = Thread.new do
318
- sedna.execute "create document '#{__method__}'"
319
- end
320
- thread.raise
321
- thread.join
322
- rescue
323
- end
324
- count = sedna.execute("count(doc('$documents')//*[@name='#{__method__}'])").first.to_i
325
- if RUBY_VERSION < "1.9"
326
- assert_equal 1, count
327
- else
328
- assert_equal 0, count
345
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
346
+ begin
347
+ thread = Thread.new do
348
+ @@sedna.execute "create document '#{__method__}'"
329
349
  end
350
+ thread.raise
351
+ thread.join
352
+ rescue
353
+ end
354
+ count = @@sedna.execute("count(doc('$documents')//*[@name='#{__method__}'])").first.to_i
355
+ if RUBY_VERSION < "1.9"
356
+ assert_equal 1, count
357
+ else
358
+ assert_equal 0, count
330
359
  end
331
360
  end
332
361
 
333
362
  test "query should be alias of execute" do
334
- Sedna.connect @connection do |sedna|
335
- assert_equal ["<test/>"], sedna.query("<test/>")
336
- end
363
+ assert_equal ["<test/>"], @@sedna.query("<test/>")
337
364
  end
338
365
 
339
366
  # Test sedna.load_document.
340
367
  test "load_document should raise TypeError if document argument cannot be converted to String" do
341
- Sedna.connect @connection do |sedna|
342
- assert_raises TypeError do
343
- sedna.load_document Object.new, __method__.to_s
344
- end
368
+ assert_raises TypeError do
369
+ @@sedna.load_document Object.new, __method__.to_s
345
370
  end
346
371
  end
347
372
 
348
373
  test "load_document should raise TypeError if doc_name argument cannot be converted to String" do
349
- Sedna.connect @connection do |sedna|
350
- assert_raises TypeError do
351
- sedna.load_document "<doc/>", Object.new
352
- end
374
+ assert_raises TypeError do
375
+ @@sedna.load_document "<doc/>", Object.new
353
376
  end
354
377
  end
355
378
 
356
379
  test "load_document should raise TypeError if col_name argument cannot be converted to String" do
357
- Sedna.connect @connection do |sedna|
358
- assert_raises TypeError do
359
- sedna.load_document "<doc/>", __method__.to_s, Object.new
360
- end
380
+ assert_raises TypeError do
381
+ @@sedna.load_document "<doc/>", __method__.to_s, Object.new
361
382
  end
362
383
  end
363
384
 
364
385
  test "load_document should create document in given collection" do
365
- Sedna.connect @connection do |sedna|
366
- col = "test_collection"
367
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
368
-
369
- sedna.execute "create collection '#{col}'" rescue Sedna::Exception
370
- sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue Sedna::Exception
371
- sedna.load_document doc, __method__.to_s, col
372
- assert_equal doc, sedna.execute("doc('#{__method__}', '#{col}')").first
373
- sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue Sedna::Exception
374
- sedna.execute "drop collection '#{col}'" rescue Sedna::Exception
375
- end
386
+ col = "test_collection"
387
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
388
+ @@sedna.execute "create collection '#{col}'" rescue nil
389
+ @@sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue nil
390
+ @@sedna.load_document doc, __method__.to_s, col
391
+ assert_equal doc, @@sedna.execute("doc('#{__method__}', '#{col}')").first
392
+ @@sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue nil
393
+ @@sedna.execute "drop collection '#{col}'" rescue nil
376
394
  end
377
395
 
378
396
  test "load_document should create standalone document if collection is unspecified" do
379
- Sedna.connect @connection do |sedna|
380
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
381
-
382
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
383
- sedna.load_document doc, __method__.to_s
384
- assert_equal doc, sedna.execute("doc('#{__method__}')").first
385
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
386
- end
397
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
398
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
399
+ @@sedna.load_document doc, __method__.to_s
400
+ assert_equal doc, @@sedna.execute("doc('#{__method__}')").first
401
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
387
402
  end
388
403
 
389
404
  test "load_document should create standalone document if collection is nil" do
390
- Sedna.connect @connection do |sedna|
391
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
392
-
393
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
394
- sedna.load_document doc, __method__.to_s, nil
395
- assert_equal doc, sedna.execute("doc('#{__method__}')").first
396
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
397
- end
405
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
406
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
407
+ @@sedna.load_document doc, __method__.to_s, nil
408
+ assert_equal doc, @@sedna.execute("doc('#{__method__}')").first
409
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
398
410
  end
399
411
 
400
412
  test "load_document should return nil if standalone document loaded successfully" do
401
- Sedna.connect @connection do |sedna|
402
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
403
- assert_nil sedna.load_document("<document><node/></document>", __method__.to_s)
404
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
405
- end
413
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
414
+ assert_nil @@sedna.load_document("<document><node/></document>", __method__.to_s)
415
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
406
416
  end
407
417
 
408
418
  test "load_document should fail if autocommit is false" do
409
- Sedna.connect @connection do |sedna|
419
+ Sedna.connect @@spec do |sedna|
410
420
  sedna.autocommit = false
411
421
  assert_raises Sedna::Exception do
412
422
  sedna.load_document "<test/>", "some_doc"
@@ -415,26 +425,22 @@ class SednaTest < Test::Unit::TestCase
415
425
  end
416
426
 
417
427
  test "load_document should fail with Sedna::Exception for invalid documents" do
418
- Sedna.connect @connection do |sedna|
419
- assert_raises Sedna::Exception do
420
- sedna.load_document "<doc/> this is an invalid document", "some_doc"
421
- end
428
+ assert_raises Sedna::Exception do
429
+ @@sedna.load_document "<doc/> this is an invalid document", "some_doc"
422
430
  end
423
431
  end
424
432
 
425
433
  test "load_document should raise exception with complete details for invalid documents" do
426
- Sedna.connect @connection do |sedna|
427
- e = nil
428
- begin
429
- sedna.load_document "<doc/> junk here", "some_doc"
430
- rescue Sedna::Exception => e
431
- end
432
- assert_match /junk after document element/, e.message
434
+ e = nil
435
+ begin
436
+ @@sedna.load_document "<doc/> junk here", "some_doc"
437
+ rescue Sedna::Exception => e
433
438
  end
439
+ assert_match /junk after document element/, e.message
434
440
  end
435
441
 
436
442
  test "load_document should fail with Sedna::ConnectionError if connection is closed" do
437
- Sedna.connect @connection do |sedna|
443
+ Sedna.connect @@spec do |sedna|
438
444
  sedna.close
439
445
  assert_raises Sedna::ConnectionError do
440
446
  sedna.load_document "<doc/>", "some_doc"
@@ -443,71 +449,63 @@ class SednaTest < Test::Unit::TestCase
443
449
  end
444
450
 
445
451
  test "load_document should create document if given document is IO object" do
446
- Sedna.connect @connection do |sedna|
447
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>" << ("\n <some_very_often_repeated_node/>" * 800) << "\n</document>"
448
- p_out, p_in = IO.pipe
449
- p_in.write doc
450
- p_in.close
452
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>" << ("\n <some_very_often_repeated_node/>" * 800) << "\n</document>"
453
+ p_out, p_in = IO.pipe
454
+ p_in.write doc
455
+ p_in.close
451
456
 
452
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
453
- sedna.load_document p_out, __method__.to_s, nil
454
- assert_equal doc.length, sedna.execute("doc('#{__method__}')").first.length
455
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
456
- end
457
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
458
+ @@sedna.load_document p_out, __method__.to_s, nil
459
+ assert_equal doc.length, @@sedna.execute("doc('#{__method__}')").first.length
460
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
457
461
  end
458
462
 
459
463
  test "load_document should raise Sedna::Exception if given document is empty IO object" do
460
- Sedna.connect @connection do |sedna|
461
- p_out, p_in = IO.pipe
462
- p_in.close
463
-
464
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
465
- e = nil
466
- begin
467
- sedna.load_document p_out, __method__.to_s, nil
468
- rescue Sedna::Exception => e
469
- end
470
- assert_equal "Document is empty.", e.message
471
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
464
+ p_out, p_in = IO.pipe
465
+ p_in.close
466
+
467
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
468
+ e = nil
469
+ begin
470
+ @@sedna.load_document p_out, __method__.to_s, nil
471
+ rescue Sedna::Exception => e
472
472
  end
473
+ assert_equal "Document is empty.", e.message
474
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
473
475
  end
474
476
 
475
477
  test "load_document should raise Sedna::Exception if given document is empty string" do
476
- Sedna.connect @connection do |sedna|
477
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
478
- e = nil
479
- begin
480
- sedna.load_document "", __method__.to_s, nil
481
- rescue Sedna::Exception => e
482
- end
483
- assert_equal "Document is empty.", e.message
484
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
478
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
479
+ e = nil
480
+ begin
481
+ @@sedna.load_document "", __method__.to_s, nil
482
+ rescue Sedna::Exception => e
485
483
  end
484
+ assert_equal "Document is empty.", e.message
485
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
486
486
  end
487
-
487
+
488
488
  # Test sedna.autocommit= / sedna.autocommit.
489
489
  test "autocommit should return true by default" do
490
- Sedna.connect @connection do |sedna|
491
- assert_equal true, sedna.autocommit
492
- end
490
+ assert_equal true, @@sedna.autocommit
493
491
  end
494
492
 
495
493
  test "autocommit should return true if set to true" do
496
- Sedna.connect @connection do |sedna|
494
+ Sedna.connect @@spec do |sedna|
497
495
  sedna.autocommit = true
498
496
  assert_equal true, sedna.autocommit
499
497
  end
500
498
  end
501
499
 
502
500
  test "autocommit should return false if set to false" do
503
- Sedna.connect @connection do |sedna|
501
+ Sedna.connect @@spec do |sedna|
504
502
  sedna.autocommit = false
505
503
  assert_equal false, sedna.autocommit
506
504
  end
507
505
  end
508
506
 
509
507
  test "autocommit should return true if set to true after being set to false" do
510
- Sedna.connect @connection do |sedna|
508
+ Sedna.connect @@spec do |sedna|
511
509
  sedna.autocommit = false
512
510
  sedna.autocommit = true
513
511
  assert_equal true, sedna.autocommit
@@ -515,21 +513,21 @@ class SednaTest < Test::Unit::TestCase
515
513
  end
516
514
 
517
515
  test "autocommit should return true if argument evaluates to true" do
518
- Sedna.connect @connection do |sedna|
516
+ Sedna.connect @@spec do |sedna|
519
517
  sedna.autocommit = "string evaluates to true"
520
518
  assert_equal true, sedna.autocommit
521
519
  end
522
520
  end
523
521
 
524
522
  test "autocommit should return false if argument evaluates to false" do
525
- Sedna.connect @connection do |sedna|
523
+ Sedna.connect @@spec do |sedna|
526
524
  sedna.autocommit = nil
527
525
  assert_equal false, sedna.autocommit
528
526
  end
529
527
  end
530
528
 
531
- test "autocommit should be re-enabled after transactions" do
532
- Sedna.connect @connection do |sedna|
529
+ test "autocommit should be re-enabled after a transaction" do
530
+ Sedna.connect @@spec do |sedna|
533
531
  sedna.autocommit = true
534
532
  sedna.transaction do end
535
533
  assert_nothing_raised do
@@ -538,23 +536,66 @@ class SednaTest < Test::Unit::TestCase
538
536
  end
539
537
  end
540
538
 
541
- # Test sedna.transaction.
542
- test "transaction should return nil if committed" do
543
- Sedna.connect @connection do |sedna|
544
- assert_nil sedna.transaction(){}
539
+ test "autocommit should be re-enabled after an explicit commit" do
540
+ Sedna.connect @@spec do |sedna|
541
+ sedna.autocommit = true
542
+ sedna.transaction
543
+ sedna.commit
544
+ assert_nothing_raised do
545
+ sedna.execute "<test/>"
546
+ end
547
+ end
548
+ end
549
+
550
+ test "autocommit should be re-enabled after an explicit rollback" do
551
+ Sedna.connect @@spec do |sedna|
552
+ sedna.autocommit = true
553
+ sedna.transaction
554
+ sedna.rollback
555
+ assert_nothing_raised do
556
+ sedna.execute "<test/>"
557
+ end
545
558
  end
546
559
  end
547
560
 
548
- test "transaction should raise LocalJumpError if no block is given" do
549
- assert_raises LocalJumpError do
550
- Sedna.connect @connection do |sedna|
551
- sedna.transaction
561
+ test "autocommit should be re-enabled after a transaction was rolled back" do
562
+ Sedna.connect @@spec do |sedna|
563
+ sedna.autocommit = true
564
+ catch :rollback do
565
+ sedna.transaction do
566
+ throw :rollback
567
+ end
568
+ end
569
+ assert_nothing_raised do
570
+ sedna.execute "<test/>"
552
571
  end
553
572
  end
554
573
  end
555
574
 
575
+ test "autocommit should be re-enabled after a transaction raised an error" do
576
+ Sedna.connect @@spec do |sedna|
577
+ sedna.autocommit = true
578
+ sedna.transaction do
579
+ sedna.execute "INVALID" rescue nil
580
+ end rescue nil
581
+ assert_nothing_raised do
582
+ sedna.execute "<test/>"
583
+ end
584
+ end
585
+ end
586
+
587
+ # Test sedna.transaction.
588
+ test "transaction should return nil if called without block" do
589
+ assert_nil @@sedna.transaction
590
+ @@sedna.rollback
591
+ end
592
+
593
+ test "transaction should return nil if committed" do
594
+ assert_nil @@sedna.transaction(){}
595
+ end
596
+
556
597
  test "transaction should be possible with autocommit" do
557
- Sedna.connect @connection do |sedna|
598
+ Sedna.connect @@spec do |sedna|
558
599
  sedna.autocommit = true
559
600
  assert_nothing_raised do
560
601
  sedna.transaction do end
@@ -563,74 +604,86 @@ class SednaTest < Test::Unit::TestCase
563
604
  end
564
605
 
565
606
  test "transaction should fail with Sedna::TransactionError if another transaction is started inside it" do
566
- Sedna.connect @connection do |sedna|
567
- assert_raises Sedna::TransactionError do
568
- sedna.transaction do
569
- sedna.transaction do end
570
- end
607
+ assert_raises Sedna::TransactionError do
608
+ @@sedna.transaction do
609
+ @@sedna.transaction do end
571
610
  end
572
611
  end
573
612
  end
574
613
 
614
+ test "transaction should fail with Sedna::TransactionError if another transaction is started before it is committed" do
615
+ @@sedna.transaction
616
+ assert_raises Sedna::TransactionError do
617
+ @@sedna.transaction
618
+ end
619
+ @@sedna.rollback
620
+ end
621
+
575
622
  test "transaction should commit if block given" do
576
- Sedna.connect @connection do |sedna|
577
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
578
- sedna.execute "create document '#{__method__}'"
579
- sedna.transaction do
580
- sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
581
- end
582
- assert_equal 1, sedna.execute("count(doc('#{__method__}')/test)").first.to_i
583
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
623
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
624
+ @@sedna.execute "create document '#{__method__}'"
625
+ @@sedna.transaction do
626
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
584
627
  end
628
+ assert_equal 1, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
629
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
585
630
  end
586
631
 
587
632
  test "transaction should rollback if exception is raised inside block" do
588
- Sedna.connect @connection do |sedna|
589
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
590
- sedna.execute "create document '#{__method__}'"
591
- begin
592
- sedna.transaction do
593
- sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
594
- raise Exception
595
- end
596
- rescue Exception
633
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
634
+ @@sedna.execute "create document '#{__method__}'"
635
+ begin
636
+ @@sedna.transaction do
637
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
638
+ raise Exception
597
639
  end
598
- assert_equal 0, sedna.execute("count(doc('#{__method__}')/test)").first.to_i
599
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
640
+ rescue Exception
600
641
  end
642
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
643
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
601
644
  end
602
645
 
603
646
  test "transaction should rollback if something is thrown inside block" do
604
- Sedna.connect @connection do |sedna|
605
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
606
- sedna.execute "create document '#{__method__}'"
607
- catch :ball do
608
- sedna.transaction do
609
- sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
610
- throw :ball
611
- end
647
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
648
+ @@sedna.execute "create document '#{__method__}'"
649
+ catch :ball do
650
+ @@sedna.transaction do
651
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
652
+ throw :ball
612
653
  end
613
- assert_equal 0, sedna.execute("count(doc('#{__method__}')/test)").first.to_i
614
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
615
654
  end
655
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
656
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
616
657
  end
617
658
 
618
659
  test "transaction should raise Sedna::TransactionError if invalid statement caused exception but it was rescued" do
619
- Sedna.connect @connection do |sedna|
620
- assert_raises Sedna::TransactionError do
621
- sedna.transaction do
622
- sedna.execute "FAILS" rescue Sedna::Exception
623
- end
660
+ assert_raises Sedna::TransactionError do
661
+ @@sedna.transaction do
662
+ @@sedna.execute "FAILS" rescue nil
624
663
  end
625
664
  end
626
665
  end
627
-
666
+
667
+ test "transaction should raise Sedna::TransactionError if it was committed inside the block" do
668
+ assert_raises Sedna::TransactionError do
669
+ @@sedna.transaction do
670
+ @@sedna.commit
671
+ end
672
+ end
673
+ end
674
+
675
+ test "transaction should raise Sedna::TransactionError if it was rolled back inside the block" do
676
+ assert_raises Sedna::TransactionError do
677
+ @@sedna.transaction do
678
+ @@sedna.rollback
679
+ end
680
+ end
681
+ end
682
+
628
683
  test "transaction should re-raise exceptions from inside block" do
629
- Sedna.connect @connection do |sedna|
630
- assert_raises Exception do
631
- sedna.transaction do
632
- raise Exception
633
- end
684
+ assert_raises Exception do
685
+ @@sedna.transaction do
686
+ raise Exception
634
687
  end
635
688
  end
636
689
  end
@@ -638,10 +691,8 @@ class SednaTest < Test::Unit::TestCase
638
691
  test "transaction with invalid statements should cause transaction to roll back once" do
639
692
  exc = nil
640
693
  begin
641
- Sedna.connect @connection do |sedna|
642
- sedna.transaction do
643
- sedna.execute "FAILS"
644
- end
694
+ @@sedna.transaction do
695
+ @@sedna.execute "FAILS"
645
696
  end
646
697
  rescue Sedna::Exception => exc
647
698
  end
@@ -649,23 +700,102 @@ class SednaTest < Test::Unit::TestCase
649
700
  end
650
701
 
651
702
  test "transaction should raise Sedna::TransactionError if called from different threads on same connection" do
652
- Sedna.connect @connection do |sedna|
653
- threads = []
654
- exceptions = []
655
- Thread.abort_on_exception = true
656
- 5.times do
657
- threads << Thread.new do
658
- begin
659
- sedna.transaction do
660
- sleep 0.1
661
- end
662
- rescue StandardError => e
663
- exceptions << e.class
703
+ threads = []
704
+ exceptions = []
705
+ Thread.abort_on_exception = true
706
+ 5.times do
707
+ threads << Thread.new do
708
+ begin
709
+ @@sedna.transaction do
710
+ sleep 0.1
664
711
  end
712
+ rescue StandardError => e
713
+ exceptions << e.class
665
714
  end
666
715
  end
667
- threads.each do |thread| thread.join end
668
- assert_equal [Sedna::TransactionError] * 4, exceptions
669
716
  end
717
+ threads.each do |thread| thread.join end
718
+ assert_equal [Sedna::TransactionError] * 4, exceptions
719
+ end
720
+
721
+ test "transaction should raise Sedna::Exception if connection is closed before it could be committed" do
722
+ sedna = Sedna.connect @@spec
723
+ assert_raises Sedna::Exception do
724
+ sedna.transaction do
725
+ sedna.execute "<test/>"
726
+ sedna.close
727
+ end
728
+ end
729
+ end
730
+
731
+ # Test sedna.commit.
732
+ test "commit should commit transaction" do
733
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
734
+ @@sedna.execute "create document '#{__method__}'"
735
+
736
+ @@sedna.transaction
737
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
738
+ @@sedna.commit
739
+
740
+ assert_equal 1, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
741
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
742
+ end
743
+
744
+ test "commit should raise Sedna::Exception if connection is closed before transaction could be committed" do
745
+ sedna = Sedna.connect @@spec
746
+ sedna.transaction
747
+ sedna.execute "<test/>"
748
+ sedna.close
749
+ assert_raises Sedna::Exception do
750
+ sedna.commit
751
+ end
752
+ end
753
+
754
+ test "commit should raise Sedna::TransactionError if no transaction is in progress" do
755
+ assert_raises Sedna::TransactionError do
756
+ @@sedna.commit
757
+ end
758
+ end
759
+
760
+ test "commit should return nil" do
761
+ @@sedna.transaction
762
+ assert_nil @@sedna.commit
763
+ end
764
+
765
+ # Test sedna.rollback.
766
+ test "rollback should roll back transaction" do
767
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
768
+ @@sedna.execute "create document '#{__method__}'"
769
+
770
+ @@sedna.transaction
771
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
772
+ @@sedna.rollback
773
+
774
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
775
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
776
+ end
777
+
778
+ test "rollback should roll back transaction if called inside transaction block" do
779
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
780
+ @@sedna.execute "create document '#{__method__}'"
781
+
782
+ @@sedna.transaction do
783
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
784
+ @@sedna.rollback
785
+ end rescue nil
786
+
787
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
788
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
789
+ end
790
+
791
+ test "rollback should fail silently if no transaction is in progress" do
792
+ assert_nothing_raised do
793
+ @@sedna.rollback
794
+ end
795
+ end
796
+
797
+ test "rollback should return nil" do
798
+ @@sedna.transaction
799
+ assert_nil @@sedna.rollback
670
800
  end
671
801
  end