odba 1.0.0

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.
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ # TestCacheEntry -- odba-- 29.04.2004 -- hwyss@ywesee.com mwalder@ywesee.com
3
+
4
+ $: << File.dirname(__FILE__)
5
+ $: << File.expand_path("../lib", File.dirname(__FILE__))
6
+
7
+ require 'test/unit'
8
+ require 'flexmock'
9
+ require 'odba/cache_entry'
10
+ require 'odba/odba'
11
+ require 'odba/persistable'
12
+
13
+ module ODBA
14
+ class CacheEntry
15
+ attr_accessor :accessed_by
16
+ end
17
+ class TestCacheEntry < Test::Unit::TestCase
18
+ include FlexMock::TestCase
19
+ def setup
20
+ @mock = flexmock
21
+ @mock.should_receive(:odba_add_observer)
22
+ @mock.should_receive(:odba_observers).and_return { [] }
23
+ @mock.should_receive(:odba_id).and_return { 123 }
24
+ @cache_entry = ODBA::CacheEntry.new(@mock)
25
+ ODBA.cache = flexmock("cache")
26
+ ODBA.cache.should_receive(:retire_age).and_return(0.9)
27
+ ODBA.cache.should_receive(:destroy_age).and_return(0.9)
28
+ end
29
+ def test_retire_check
30
+ @mock.should_receive(:odba_unsaved?).and_return { false }
31
+ @mock.should_receive(:odba_unsaved?).and_return { false }
32
+ assert_equal(false, @cache_entry.odba_old?(Time.now - 1))
33
+ assert_equal(true, @cache_entry.odba_old?(Time.now + 1))
34
+ end
35
+ def test_retire
36
+ obj_1 = Object.new
37
+ obj_1.extend(Persistable)
38
+ obj_1.instance_variable_set('@odba_id', 36)
39
+ obj_2 = Object.new
40
+ obj_2.extend(Persistable)
41
+ obj_2.instance_variable_set('@odba_id', 34)
42
+ ODBA.cache.should_receive(:include?).with(34).and_return(false)
43
+ ODBA.cache.should_receive(:include?).with(35).and_return(false)
44
+ ODBA.cache.should_receive(:include?).with(36).and_return(true)
45
+ ODBA.cache.should_receive(:fetch).with(36).and_return(obj_1)
46
+ hash = {}
47
+ hash.instance_variable_set('@odba_id', 35)
48
+ hash.instance_variable_set('@odba_persistent', true)
49
+ @cache_entry.accessed_by = {
50
+ obj_1.object_id => 36,
51
+ obj_2.object_id => 34,
52
+ hash.object_id => 35,
53
+ }
54
+ @cache_entry.odba_retire
55
+ assert_equal({hash.object_id => 35}, @cache_entry.accessed_by)
56
+ end
57
+ def test_odba_add_reference
58
+ mock = flexmock
59
+ @cache_entry.odba_add_reference(mock)
60
+ id = mock.object_id
61
+ assert_equal({id => nil}, @cache_entry.accessed_by)
62
+ mock2 = flexmock
63
+ mock2.should_receive(:odba_id).and_return(123)
64
+ @cache_entry.odba_add_reference(mock2)
65
+ assert_equal({mock2.object_id => 123, id => nil}, @cache_entry.accessed_by)
66
+ end
67
+ def test_odba_id
68
+ assert_equal(123, @cache_entry.odba_id)
69
+ end
70
+ def test_odba_cut_connections
71
+ ## transaction-rollback for unsaved items
72
+ item1 = flexmock('Item1', :odba_id => 145)
73
+ item2 = flexmock('Item2', :odba_id => 148)
74
+ ODBA.cache.should_receive(:include?).with(145).and_return(false)
75
+ ODBA.cache.should_receive(:include?).with(148).and_return(true)
76
+ ODBA.cache.should_receive(:fetch).with(148).and_return(item2)
77
+ @cache_entry.accessed_by.store(item1.object_id, 145)
78
+ @cache_entry.accessed_by.store(item2.object_id, 148)
79
+ item1.should_receive(:respond_to?).with(:odba_cut_connection)\
80
+ .and_return(false)
81
+ item2.should_receive(:respond_to?).with(:odba_cut_connection)\
82
+ .and_return(true)
83
+ item2.should_receive(:odba_cut_connection).with(@mock)\
84
+ .times(1).and_return { assert(true) }
85
+ @cache_entry.odba_cut_connections!
86
+ end
87
+ def test_odba_replace
88
+ ## transaction-rollback for saved items
89
+ modified = Object.new
90
+ modified.extend(ODBA::Persistable)
91
+ modified.instance_variable_set('@data', 'foo')
92
+ modified.instance_variable_set('@odba_id', 124)
93
+ cache_entry = CacheEntry.new(modified)
94
+
95
+ reloaded = modified.dup
96
+
97
+ modified.instance_variable_set('@data', 'bar')
98
+ assert_equal('bar', modified.instance_variable_get('@data'))
99
+
100
+ cache_entry.odba_replace!(reloaded)
101
+ assert_equal('foo', modified.instance_variable_get('@data'))
102
+ end
103
+ def test_odba_notify_observers
104
+ @mock.should_receive(:odba_notify_observers).with(:foo, 2, 'bar')\
105
+ .and_return { assert(true) }
106
+ @cache_entry.odba_notify_observers(:foo, 2, 'bar')
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+ # TestConnectionPool -- odba -- 03.08.2005 -- hwyss@ywesee.com
3
+
4
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
5
+
6
+ require 'test/unit'
7
+ require 'flexmock'
8
+ require 'odba/connection_pool'
9
+ ## connection_pool requires 'dbi', which unshifts the site_ruby dir
10
+ # to the first position in $LOAD_PATH ( == $: ). As a result, files are
11
+ # loaded from site_ruby if they are installed there, and thus ignored
12
+ # by rcov. Workaround:
13
+ $:.shift
14
+
15
+ module ODBA
16
+ class TestConnectionPool < Test::Unit::TestCase
17
+ include FlexMock::TestCase
18
+ def test_survive_error
19
+ flexstub(DBI).should_receive(:connect).times(10).and_return {
20
+ conn = FlexMock.new("Connection")
21
+ conn.should_ignore_missing
22
+ conn
23
+ }
24
+ pool = ConnectionPool.new()
25
+ pool.connections.each { |conn|
26
+ conn.should_receive(:execute).and_return {
27
+ raise DBI::InterfaceError.new
28
+ ## after the first error is raised, ConnectionPool reconnects.
29
+ }
30
+ }
31
+ assert_nothing_raised { pool.execute('statement') }
32
+ end
33
+ def test_multiple_errors__give_up
34
+ flexstub(DBI).should_receive(:connect).times(20).and_return {
35
+ conn = FlexMock.new("Connection")
36
+ conn.should_receive(:execute).and_return {
37
+ raise DBI::InterfaceError.new
38
+ }
39
+ conn
40
+ }
41
+ pool = ConnectionPool.new()
42
+ assert_raises(DBI::InterfaceError) { pool.execute('statement') }
43
+ end
44
+ def test_size
45
+ flexstub(DBI).should_receive(:connect).times(5).and_return {
46
+ conn = FlexMock.new("Connection")
47
+ conn.should_ignore_missing
48
+ conn
49
+ }
50
+ pool = ConnectionPool.new()
51
+ assert_equal(5, pool.size)
52
+ end
53
+ def test_disconnect
54
+ flexstub(DBI).should_receive(:connect).times(5).and_return {
55
+ conn = FlexMock.new("Connection")
56
+ conn.should_ignore_missing
57
+ conn
58
+ }
59
+ pool = ConnectionPool.new()
60
+ pool.connections.each { |conn|
61
+ conn.should_receive(:disconnect).and_return { assert(true) }
62
+ }
63
+ pool.disconnect
64
+ end
65
+ def test_disconnect_error
66
+ flexstub(DBI).should_receive(:connect).times(5).and_return {
67
+ conn = FlexMock.new("Connection")
68
+ conn.should_receive(:disconnect).times(1).and_return {
69
+ raise DBI::InterfaceError.new
70
+ }
71
+ conn
72
+ }
73
+ pool = ConnectionPool.new()
74
+ assert_nothing_raised { pool.disconnect }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+ # TestDRbWrapper -- odba -- 13.06.2006 -- hwyss@ywesee.com
3
+
4
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
5
+
6
+ require 'test/unit'
7
+ require 'odba/drbwrapper'
8
+ require 'flexmock'
9
+
10
+ module ODBA
11
+ class TestDRbWrapper < Test::Unit::TestCase
12
+ include FlexMock::TestCase
13
+ def test_include
14
+ obj = FlexMock.new
15
+ obj2 = FlexMock.new
16
+ arr = [obj]
17
+ assert_equal(false, arr.include?(obj2))
18
+ assert_equal(true, arr.include?(DRbWrapper.new(obj)))
19
+ assert_equal(false, arr.include?(DRbWrapper.new(obj2)))
20
+ arr = [DRbWrapper.new(obj)]
21
+ assert_equal(true, arr.include?(DRbWrapper.new(obj)))
22
+ assert_equal(false, arr.include?(DRbWrapper.new(obj2)))
23
+ end
24
+ def test_respond_to
25
+ obj = FlexMock.new
26
+ wrap = DRbWrapper.new(obj)
27
+ obj.should_receive(:respond_to?).with(:foo).times(1).and_return(true)
28
+ obj.should_receive(:respond_to?).with(:bar).times(1).and_return(false)
29
+ assert_equal(true, wrap.respond_to?(:foo))
30
+ assert_equal(false, wrap.respond_to?(:bar))
31
+ end
32
+ def test_method_missing
33
+ obj = FlexMock.new
34
+ wrap = DRbWrapper.new(obj)
35
+ obj.should_receive(:foo).with(:arg1, :arg2).times(1).and_return('result_foo')
36
+ assert_equal('result_foo', wrap.foo(:arg1, :arg2))
37
+ pers = flexmock('Persistable')
38
+ pers.should_receive(:is_a?).with(Persistable).and_return(true)
39
+ obj.should_receive(:bar).with(:arg1).times(1).and_return([pers])
40
+ res = wrap.bar(:arg1)
41
+ assert_instance_of(Array, res)
42
+ assert_equal(1, res.size)
43
+ wrapped_res = res.first
44
+ assert_respond_to(wrapped_res, :__wrappee)
45
+ assert_equal(pers, wrapped_res.__wrappee)
46
+ obj.should_receive(:baz).times(1).and_return { |block|
47
+ block.call(pers)
48
+ }
49
+ wrap.baz { |res|
50
+ assert_respond_to(wrapped_res, :__wrappee)
51
+ assert_equal(pers, wrapped_res.__wrappee)
52
+ }
53
+ end
54
+ end
55
+ class TestDRbIdConv < Test::Unit::TestCase
56
+ include FlexMock::TestCase
57
+ def setup
58
+ ODBA.cache = flexmock('cache')
59
+ @idconv = ODBA::DRbIdConv.new
60
+ end
61
+ def test_to_id
62
+ ODBA.cache.should_receive(:store)
63
+ o = Object.new
64
+ assert_equal(o.object_id, @idconv.to_id(o))
65
+ o.extend(ODBA::Persistable)
66
+ o.instance_variable_set('@odba_id', 4)
67
+ o.odba_isolated_store
68
+ assert_equal('4', @idconv.to_id(o))
69
+ end
70
+ def test_to_id__odba_unsaved
71
+ o = Object.new
72
+ o.extend(ODBA::Persistable)
73
+ assert_equal(o.object_id, @idconv.to_id(o))
74
+ assert_equal([@idconv], o.odba_observers)
75
+ end
76
+ def test_to_obj
77
+ ODBA.cache.should_receive(:store)
78
+ o = Object.new
79
+ assert_equal(o, @idconv.to_obj(o.object_id))
80
+ o.extend(ODBA::Persistable)
81
+ o.instance_variable_set('@odba_id', 4)
82
+ o.odba_isolated_store
83
+ ODBA.cache.should_receive(:fetch).with(4).times(1)
84
+ @idconv.to_obj('4')
85
+ end
86
+ def test_to_obj__error
87
+ ODBA.cache.should_receive(:fetch).with(4).times(1).and_return {
88
+ raise "some error"
89
+ }
90
+ assert_raises(RangeError) { @idconv.to_obj('4') }
91
+ end
92
+ def test_odba_update
93
+ id = Object.new.object_id
94
+ @idconv.odba_update(:store, 4, id)
95
+ ODBA.cache.should_receive(:fetch).with(4).times(1)
96
+ @idconv.to_obj(id)
97
+ @idconv.odba_update(:clean, 4, id)
98
+ GC.start
99
+ assert_raises(RangeError) { @idconv.to_obj(id) }
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env ruby
2
+ # TestHash -- odba -- ??.??.???? -- hwyss@ywesee.com
3
+
4
+ $: << File.dirname(__FILE__)
5
+ $: << File.expand_path('../lib/', File.dirname(__FILE__))
6
+
7
+ require 'odba/persistable'
8
+ require 'odba/stub'
9
+ require 'odba/odba'
10
+ require 'test/unit'
11
+ require 'flexmock'
12
+
13
+ module ODBA
14
+ class TestHash < Test::Unit::TestCase
15
+ include FlexMock::TestCase
16
+ class ODBAContainer
17
+ include Persistable
18
+ attr_accessor :non_replaceable, :replaceable, :odba_id
19
+ end
20
+ class Container
21
+ attr_accessor :content
22
+ end
23
+ class TestStub
24
+ attr_accessor :receiver, :odba_replace
25
+ def is_a?(arg)
26
+ true
27
+ end
28
+ end
29
+ def setup
30
+ @hash = Hash.new
31
+ ODBA.cache = flexmock("cache")
32
+ ODBA.storage = flexmock("storage")
33
+ @hash.clear
34
+ end
35
+ def test_odba_unsaved_neighbors_hash
36
+ repkey1 = ODBAContainer.new
37
+ repkey2 = ODBAContainer.new
38
+ repvalue1 = ODBAContainer.new
39
+ repvalue2 = ODBAContainer.new
40
+ @hash.store(repkey1, repvalue1)
41
+ @hash.store(repkey2, repvalue2)
42
+ result = @hash.odba_unsaved_neighbors(1)
43
+ assert_equal(true, result.include?(repkey1))
44
+ assert_equal(true, result.include?(repkey2))
45
+ assert_equal(true, result.include?(repvalue1))
46
+ assert_equal(true, result.include?(repvalue2))
47
+ end
48
+ def test_odba_replace_persistables_hash
49
+ key1 = flexmock("key")
50
+ value1 = flexmock("value")
51
+ @hash.store(key1, value1)
52
+ @hash.odba_replace_persistables
53
+ assert_equal(@hash, {})
54
+ end
55
+ def test_odba_prefetch
56
+ key1 = flexmock("key")
57
+ val1 = flexmock("val1")
58
+ @hash.store(key1, val1)
59
+ assert_equal(false, @hash.odba_prefetch?)
60
+ end
61
+ def test_odba_unsaved_true
62
+ key = flexmock("key")
63
+ val = flexmock("val")
64
+ @hash.instance_variable_set("@odba_persistent", true)
65
+ @hash.store(key, val)
66
+ val.should_receive(:is_a?).and_return { |klass| true }
67
+ val.should_receive(:odba_unsaved?).and_return { true }
68
+
69
+ assert_equal(true, @hash.odba_unsaved?)
70
+ end
71
+ def test_odba_cut_connection
72
+ remove_obj = Object.new
73
+ remove_obj.extend(ODBA::Persistable)
74
+ remove_obj.instance_variable_set('@odba_id', 2)
75
+ other = Object.new
76
+ other.extend(ODBA::Persistable)
77
+ other.instance_variable_set('@odba_id', 3)
78
+ receiver = ODBA::Stub.new(2, nil, remove_obj)
79
+ ODBA.cache.should_receive(:fetch).with(2,nil).and_return(remove_obj)
80
+ @hash.store('foo', receiver)
81
+ @hash.store(receiver, 'bar')
82
+ @hash.store('bar', other)
83
+ @hash.store(other, 'baz')
84
+ @hash.odba_cut_connection(remove_obj)
85
+ assert_equal({'bar' => other, other => 'baz'}, @hash)
86
+ end
87
+ def test_odba_collection
88
+ @hash.update('foo' => 'bar', 'trouble' => 'not')
89
+ assert_equal([['foo', 'bar'],['trouble', 'not']],
90
+ @hash.odba_collection.sort)
91
+ end
92
+ def test_odba_replace
93
+ modified = { 'foo' => 'bar' }
94
+ reloaded = modified.dup
95
+ modified.update('foo' => 'baz', 'han' => 'solo')
96
+
97
+ modified.odba_replace!(reloaded)
98
+
99
+ assert_equal(reloaded, modified)
100
+ end
101
+ def test_odba_restore
102
+ collection = [[:foo, 'bar'],[:trouble, 'not']]
103
+ @hash.odba_restore(collection)
104
+ assert_equal({:foo => 'bar', :trouble => 'not'}, @hash)
105
+ end
106
+ def test_odba_target_ids
107
+ o = ODBAContainer.new
108
+ o.odba_id = 1
109
+ p = ODBAContainer.new
110
+ p.odba_id = 2
111
+ q = ODBAContainer.new
112
+ q.odba_id = 3
113
+ @hash.store('foo', p)
114
+ @hash.store(p, 'bar')
115
+ @hash.store('bar', q)
116
+ @hash.store(q, 'baz')
117
+ @hash.instance_variable_set('@var', o)
118
+ assert_equal([1,2,3], @hash.odba_target_ids.sort)
119
+ end
120
+ def test_odba_stubize
121
+ obj = Object.new
122
+ obj.extend(ODBA::Persistable)
123
+ id = 10
124
+ ODBA.cache.should_receive(:next_id).times(2).and_return { id += 1 }
125
+ assert_equal(11, obj.odba_id)
126
+ hash = {1 => obj}
127
+ assert_equal(12, hash.odba_id)
128
+ assert_equal(true, hash.odba_stubize(obj, :force => true))
129
+ assert_equal([1], hash.keys)
130
+ assert_equal false, hash.values.first.is_a?(ODBA::Stub)
131
+ end
132
+ def test_odba_stubize__key
133
+ obj = Object.new
134
+ obj.extend(ODBA::Persistable)
135
+ id = 10
136
+ ODBA.cache.should_receive(:next_id).times(2).and_return { id += 1 }
137
+ assert_equal(11, obj.odba_id)
138
+ hash = {obj => 'foo'}
139
+ assert_equal(12, hash.odba_id)
140
+ assert_equal(true, hash.odba_stubize(obj, :force => true))
141
+ assert_equal({obj => 'foo'}, hash)
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ # TestIdServer -- odba -- 10.11.2004 -- hwyss@ywesee.com
3
+
4
+ $: << File.dirname(__FILE__)
5
+ $: << File.expand_path('../lib', File.dirname(__FILE__))
6
+
7
+ require 'test/unit'
8
+ require 'flexmock'
9
+ require 'odba/id_server'
10
+ require 'odba/odba'
11
+ require 'odba/marshal'
12
+
13
+ module ODBA
14
+ class TestIdServer < Test::Unit::TestCase
15
+ include FlexMock::TestCase
16
+ def setup
17
+ @cache = ODBA.cache = flexmock('cache')
18
+ @id_server = IdServer.new
19
+ @id_server.instance_variable_set('@odba_id', 1)
20
+ end
21
+ def test_first
22
+ @cache.should_receive(:store).with(@id_server).times(3)
23
+ assert_equal(1, @id_server.next_id(:foo))
24
+ assert_equal(1, @id_server.next_id(:bar))
25
+ assert_equal(1, @id_server.next_id(:baz))
26
+ end
27
+ def test_consecutive
28
+ @cache.should_receive(:store).with(@id_server).times(3)
29
+ assert_equal(1, @id_server.next_id(:foo))
30
+ assert_equal(2, @id_server.next_id(:foo))
31
+ assert_equal(3, @id_server.next_id(:foo))
32
+ end
33
+ def test_dumpable
34
+ @cache.should_receive(:store).with(@id_server).times(1)
35
+ @id_server.next_id(:foo)
36
+ dump = nil
37
+ assert_nothing_raised {
38
+ dump = @id_server.odba_isolated_dump
39
+ }
40
+ assert_instance_of(ODBA::IdServer, ODBA.marshaller.load(dump))
41
+ end
42
+ end
43
+ end