ObjectModel 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +849 -0
- data/lib/ObjectModel.res/config.yaml +5 -0
- data/lib/ObjectModel/AnEntity/BackReferences.rb +113 -0
- data/lib/ObjectModel/AnEntity/Bag.rb +129 -0
- data/lib/ObjectModel/AnEntity/BagCopy.rb +29 -0
- data/lib/ObjectModel/AnEntity/ChildrenBag.rb +10 -0
- data/lib/ObjectModel/AnEntity/EntityCopy.rb +38 -0
- data/lib/ObjectModel/AnEntity/EntityType.rb +408 -0
- data/lib/ObjectModel/AnEntity/ReferencesBag.rb +10 -0
- data/lib/ObjectModel/AnEntity/entity_cm.rb +108 -0
- data/lib/ObjectModel/Entity.rb +278 -0
- data/lib/ObjectModel/Errors/LoadError.rb +3 -0
- data/lib/ObjectModel/Errors/NoTransactionError.rb +3 -0
- data/lib/ObjectModel/Errors/NotFoundError.rb +2 -0
- data/lib/ObjectModel/Errors/OutdatedError.rb +8 -0
- data/lib/ObjectModel/Errors/ValidationError.rb +3 -0
- data/lib/ObjectModel/Indexes/HashIndex.rb +64 -0
- data/lib/ObjectModel/Indexes/IndexStorage.rb +64 -0
- data/lib/ObjectModel/Indexes/Manager.rb +72 -0
- data/lib/ObjectModel/Metadata.rb +34 -0
- data/lib/ObjectModel/Metadata.res/after_event_types.rb +25 -0
- data/lib/ObjectModel/Metadata.res/attribute_types_shortcuts.rb +10 -0
- data/lib/ObjectModel/Metadata.res/before_event_types.rb +25 -0
- data/lib/ObjectModel/Metadata.res/child_types_shortcuts.rb +4 -0
- data/lib/ObjectModel/Metadata.res/metadata_checks.rb +9 -0
- data/lib/ObjectModel/Metadata.res/reference_types_shortcuts.rb +4 -0
- data/lib/ObjectModel/Metadata/DSL.rb +11 -0
- data/lib/ObjectModel/Metadata/attribute.rb +56 -0
- data/lib/ObjectModel/Metadata/child.rb +50 -0
- data/lib/ObjectModel/Metadata/events.rb +109 -0
- data/lib/ObjectModel/Metadata/name.rb +20 -0
- data/lib/ObjectModel/Metadata/reference.rb +50 -0
- data/lib/ObjectModel/Metadata/require.rb +10 -0
- data/lib/ObjectModel/Metadata/validate.rb +66 -0
- data/lib/ObjectModel/Repository.rb +326 -0
- data/lib/ObjectModel/Repository/EventProcessor.rb +58 -0
- data/lib/ObjectModel/Repository/ObjectStorage.rb +102 -0
- data/lib/ObjectModel/Repository/StreamID.rb +20 -0
- data/lib/ObjectModel/Repository/StreamStorage.rb +121 -0
- data/lib/ObjectModel/Repository/SystemListener.rb +143 -0
- data/lib/ObjectModel/Repository/Transaction.rb +63 -0
- data/lib/ObjectModel/Repository/TransactionProcessor.rb +36 -0
- data/lib/ObjectModel/Tools/DefaultTransactionStrategy.rb +9 -0
- data/lib/ObjectModel/Tools/InMemoryCache.rb +9 -0
- data/lib/ObjectModel/Tools/NoCache.rb +18 -0
- data/lib/ObjectModel/Tools/OGLRUCache.rb +37 -0
- data/lib/ObjectModel/Types/BagType.rb +94 -0
- data/lib/ObjectModel/Types/BooleanType.rb +42 -0
- data/lib/ObjectModel/Types/ClassType.rb +43 -0
- data/lib/ObjectModel/Types/DataType.rb +44 -0
- data/lib/ObjectModel/Types/DateType.rb +43 -0
- data/lib/ObjectModel/Types/NumberType.rb +62 -0
- data/lib/ObjectModel/Types/ObjectType.rb +164 -0
- data/lib/ObjectModel/Types/ProcType.rb +43 -0
- data/lib/ObjectModel/Types/SingleType.rb +59 -0
- data/lib/ObjectModel/Types/StringType.rb +39 -0
- data/lib/ObjectModel/_require.rb +43 -0
- data/lib/ObjectModel/require.rb +1 -0
- data/rakefile +62 -0
- data/spec/ObjectModel/BasicSpec/BaseClass.rb +7 -0
- data/spec/ObjectModel/BasicSpec/BaseTypes.rb +11 -0
- data/spec/ObjectModel/BasicSpec/Descendant.rb +5 -0
- data/spec/ObjectModel/BasicSpec/EachTest.rb +14 -0
- data/spec/ObjectModel/BasicSpec/UpChild.rb +10 -0
- data/spec/ObjectModel/BasicSpec/UpParent.rb +11 -0
- data/spec/ObjectModel/ErrorsSpec/AfterCommitError.rb +9 -0
- data/spec/ObjectModel/ExtendedSpec/CustomInitialization.rb +11 -0
- data/spec/ObjectModel/ExtendedSpec/UpNotNil.rb +8 -0
- data/spec/ObjectModel/ExtendedSpec/UpParent.rb +11 -0
- data/spec/ObjectModel/ValidationSpec/BaseTypes.rb +11 -0
- data/spec/aspect_spec.rb +55 -0
- data/spec/back_references_spec.rb +161 -0
- data/spec/basic_spec.rb +162 -0
- data/spec/cascade_delete_spec.rb +168 -0
- data/spec/complex_events_spec.rb +134 -0
- data/spec/concurrency_spec.rb +186 -0
- data/spec/containment_spec.rb +146 -0
- data/spec/data_migration_spec.rb +51 -0
- data/spec/errors_spec.rb +65 -0
- data/spec/events_spec.rb +173 -0
- data/spec/extended_spec.rb +171 -0
- data/spec/indexing_spec.rb +56 -0
- data/spec/set_in_memory.rb +2 -0
- data/spec/set_no_cache.rb +2 -0
- data/spec/smoke_test_spec.rb +85 -0
- data/spec/stream_spec.rb +143 -0
- data/spec/stream_storage.rb +148 -0
- data/spec/timer.rb +5 -0
- data/spec/validation_spec.rb +87 -0
- metadata +186 -0
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module CascadeDelete
|
6
|
+
describe "Events" do
|
7
|
+
class CompositeEntity
|
8
|
+
inherit Entity
|
9
|
+
metadata do
|
10
|
+
child :child
|
11
|
+
child :children, :bag
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class EnityDeleteAllChildren
|
16
|
+
inherit Entity
|
17
|
+
metadata do
|
18
|
+
child :child
|
19
|
+
child :child2
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "Shouldn't allow to assign non-Entities to Children" do
|
24
|
+
lambda{
|
25
|
+
@r.transaction{
|
26
|
+
@r['e'].child = "string"
|
27
|
+
}.commit
|
28
|
+
}.should raise_error(/Child should be Entity or Nil/)
|
29
|
+
|
30
|
+
lambda{
|
31
|
+
@r.transaction{
|
32
|
+
@r['e'].children << "string"
|
33
|
+
}.commit
|
34
|
+
}.should raise_error(/Child should be Entity or Nil/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "Shouldn't allow to assign self as Child" do
|
38
|
+
lambda{
|
39
|
+
@r.transaction{
|
40
|
+
entity = @r['e']
|
41
|
+
entity.child = entity
|
42
|
+
}.commit
|
43
|
+
}.should raise_error(/Forbiden to add self as Child/)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "Shouldn't allow to assign the same Child twice (for the same Entity)" do
|
47
|
+
lambda{
|
48
|
+
@r.transaction{
|
49
|
+
entity = @r['e']
|
50
|
+
child = CompositeEntity.new 'child'
|
51
|
+
entity.child = child
|
52
|
+
entity.children << child
|
53
|
+
}.commit
|
54
|
+
}.should raise_error(/Forbiden to add the same Child twice/)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "Delete should delete Entity from it's Parent Childrens" do
|
58
|
+
@r.transaction{
|
59
|
+
p = CompositeEntity.new 'parent'
|
60
|
+
|
61
|
+
c1 = CompositeEntity.new 'child1'
|
62
|
+
c2 = CompositeEntity.new 'child2'
|
63
|
+
|
64
|
+
p.child = c1
|
65
|
+
p.children << c2
|
66
|
+
}.commit
|
67
|
+
|
68
|
+
@r.transaction{
|
69
|
+
@r['parent/child1'].delete
|
70
|
+
@r['parent/child2'].delete
|
71
|
+
}.commit
|
72
|
+
|
73
|
+
@r['parent'].child.should be_nil
|
74
|
+
@r['parent'].children.should be_empty
|
75
|
+
end
|
76
|
+
|
77
|
+
it "Should also delete all Children for_deleted Entity" do
|
78
|
+
@r.transaction{
|
79
|
+
p = CompositeEntity.new 'parent'
|
80
|
+
|
81
|
+
c1 = CompositeEntity.new 'child1'
|
82
|
+
c2 = CompositeEntity.new 'child2'
|
83
|
+
|
84
|
+
p.child = c1
|
85
|
+
p.children << c2
|
86
|
+
}.commit
|
87
|
+
|
88
|
+
@r.should_not include('child1')
|
89
|
+
@r.should_not include('child2')
|
90
|
+
|
91
|
+
@r.transaction{
|
92
|
+
@r['parent'].delete
|
93
|
+
}.commit
|
94
|
+
|
95
|
+
@r.should_not include('parent')
|
96
|
+
@r.should_not include('child1')
|
97
|
+
@r.should_not include('child2')
|
98
|
+
@r.should_not include('parent/child1')
|
99
|
+
@r.should_not include('parent/child1')
|
100
|
+
end
|
101
|
+
|
102
|
+
it "Should also delete all Children Entity (from error)" do
|
103
|
+
@r.transaction{
|
104
|
+
p = EnityDeleteAllChildren.new 'parent'
|
105
|
+
|
106
|
+
c1 = EnityDeleteAllChildren.new 'child1'
|
107
|
+
c2 = EnityDeleteAllChildren.new 'child2'
|
108
|
+
|
109
|
+
p.child = c1
|
110
|
+
p.child2 = c2
|
111
|
+
}.commit
|
112
|
+
|
113
|
+
@r.transaction{
|
114
|
+
@r['parent'].delete
|
115
|
+
}.commit
|
116
|
+
|
117
|
+
@r.should_not include('child1')
|
118
|
+
@r.should_not include('child2')
|
119
|
+
@r.should_not include('parent/child1')
|
120
|
+
@r.should_not include('parent/child1')
|
121
|
+
end
|
122
|
+
|
123
|
+
it "Deleting Child from Children should also delete Child.parent but not delete Child themself" do
|
124
|
+
@r.transaction{
|
125
|
+
p = CompositeEntity.new 'parent'
|
126
|
+
|
127
|
+
c1 = CompositeEntity.new 'child1'
|
128
|
+
c2 = CompositeEntity.new 'child2'
|
129
|
+
|
130
|
+
p.child = c1
|
131
|
+
p.children << c2
|
132
|
+
}.commit
|
133
|
+
|
134
|
+
tr = @r.transaction{
|
135
|
+
p = @r['parent']
|
136
|
+
p.child = nil
|
137
|
+
p.children.clear
|
138
|
+
}
|
139
|
+
@r['parent'].child.should_not be_nil
|
140
|
+
@r['parent/child1'].parent.should_not be_nil
|
141
|
+
@r['parent/child2'].parent.should_not be_nil
|
142
|
+
|
143
|
+
tr.commit
|
144
|
+
@r['parent'].child.should be_nil
|
145
|
+
@r['parent'].children.should be_empty
|
146
|
+
@r['child1'].parent.should be_nil
|
147
|
+
@r['child2'].parent.should be_nil
|
148
|
+
@r.should include('child1')
|
149
|
+
@r.should include('child2')
|
150
|
+
@r.should_not include('parent/child1')
|
151
|
+
@r.should_not include('parent/child2')
|
152
|
+
end
|
153
|
+
|
154
|
+
before :each do
|
155
|
+
ObjectModel::CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
156
|
+
|
157
|
+
Repository.delete :test
|
158
|
+
@r = Repository.new :test
|
159
|
+
@r.transaction{CompositeEntity.new 'e'}.commit
|
160
|
+
end
|
161
|
+
|
162
|
+
after :each do
|
163
|
+
@r.close
|
164
|
+
Repository.delete :test
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
module ObjectModel
|
5
|
+
module ComplexEventsSpec
|
6
|
+
describe "Events" do
|
7
|
+
class MockListener
|
8
|
+
attr_reader :events, :arguments
|
9
|
+
def initialize
|
10
|
+
@events, @arguments = [], []
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing m, *p, &b
|
14
|
+
@events << m
|
15
|
+
@arguments << p
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_to? symbol
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def clear
|
23
|
+
@events.clear
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class BeforeRollbackEntity
|
28
|
+
inherit Entity
|
29
|
+
metadata do
|
30
|
+
before :new do
|
31
|
+
raise "abort"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AfterRollbackEntity
|
37
|
+
inherit Entity
|
38
|
+
metadata do
|
39
|
+
after :new do
|
40
|
+
raise "abort"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "Should Rollback Transaction if Exception is thrown during Before & After Event" do
|
46
|
+
lambda{
|
47
|
+
@r.transaction{BeforeRollbackEntity.new 'e'}.commit
|
48
|
+
}.should raise_error(/abort/)
|
49
|
+
@r.should_not include('e')
|
50
|
+
|
51
|
+
lambda{
|
52
|
+
@r.transaction{AfterRollbackEntity.new 'e'}.commit
|
53
|
+
}.should raise_error(/abort/)
|
54
|
+
@r.should_not include('e')
|
55
|
+
end
|
56
|
+
|
57
|
+
class AfterCommitEntity
|
58
|
+
inherit Entity
|
59
|
+
metadata do
|
60
|
+
after :commit do
|
61
|
+
raise "abort"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "Shouldn't Rollback Transaction if Exception is thrown during after_commit" do
|
67
|
+
lambda{
|
68
|
+
@r.transaction{AfterCommitEntity.new 'e'}.commit
|
69
|
+
}.should raise_error(/abort/)
|
70
|
+
@r.should include('e')
|
71
|
+
end
|
72
|
+
|
73
|
+
class User
|
74
|
+
inherit Entity
|
75
|
+
metadata do
|
76
|
+
child :folder
|
77
|
+
after :new do |e|
|
78
|
+
e.folder = UserFolder.new "#{e.name} folder"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class UserFolder
|
84
|
+
inherit Entity
|
85
|
+
metadata{}
|
86
|
+
end
|
87
|
+
|
88
|
+
it "Changing another Entity during Event" do
|
89
|
+
@r.transaction{User.new 'u'}.commit
|
90
|
+
@r['u'].folder.name.should == "u folder"
|
91
|
+
end
|
92
|
+
|
93
|
+
class BaseEntity
|
94
|
+
inherit Entity
|
95
|
+
metadata do
|
96
|
+
after :new do
|
97
|
+
BaseEntity.events << "base"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.events
|
102
|
+
@events ||= []
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
class DescendantEntity < BaseEntity
|
107
|
+
metadata do
|
108
|
+
after :new do
|
109
|
+
BaseEntity.events << "descendant"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "Events call sequence, first SuperClass Events should be called" do
|
115
|
+
@r.transaction{DescendantEntity.new 'de'}.commit
|
116
|
+
BaseEntity.events.should == ["base", "descendant"]
|
117
|
+
end
|
118
|
+
|
119
|
+
before :each do
|
120
|
+
ObjectModel::CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
121
|
+
|
122
|
+
Repository.delete :test
|
123
|
+
@r = Repository.new :test
|
124
|
+
@l = MockListener.new
|
125
|
+
@r.entity_listeners << @l
|
126
|
+
end
|
127
|
+
|
128
|
+
after :each do
|
129
|
+
@r.close
|
130
|
+
Repository.delete :test
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'ObjectModel/require'
|
2
|
+
require 'spec'
|
3
|
+
require "#{File.dirname(__FILE__)}/timer"
|
4
|
+
|
5
|
+
module ObjectModel
|
6
|
+
module ConcurrencySpec
|
7
|
+
describe "Concurrency" do
|
8
|
+
class SimpleEntity
|
9
|
+
inherit Entity
|
10
|
+
metadata do
|
11
|
+
attribute :label, :string
|
12
|
+
attribute :value, :number
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before :each do
|
17
|
+
ObjectModel::CONFIG[:directory] = "#{File.dirname __FILE__}/data"
|
18
|
+
|
19
|
+
Repository.delete :test
|
20
|
+
@r = Repository.new :test
|
21
|
+
end
|
22
|
+
|
23
|
+
after :each do
|
24
|
+
@r.close
|
25
|
+
Repository.delete :test
|
26
|
+
end
|
27
|
+
|
28
|
+
it "Should raise Error if update is outdated" do
|
29
|
+
@r.transaction{
|
30
|
+
SimpleEntity.new 'one'
|
31
|
+
}.commit
|
32
|
+
|
33
|
+
t1 = Thread.new do
|
34
|
+
lambda{
|
35
|
+
tr = @r.transaction{
|
36
|
+
@r['one'].label = "name one"
|
37
|
+
}
|
38
|
+
sleep 0.5
|
39
|
+
tr.commit
|
40
|
+
}.should raise_error(OutdatedError)
|
41
|
+
end
|
42
|
+
|
43
|
+
t2 = Thread.new do
|
44
|
+
@r.transaction{
|
45
|
+
@r['one'].label = "name two"
|
46
|
+
}.commit
|
47
|
+
end
|
48
|
+
t1.join; t2.join
|
49
|
+
@r['one'].label.should == "name two"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "General concurrency test" do
|
53
|
+
@r.transaction{
|
54
|
+
from = SimpleEntity.new 'from'
|
55
|
+
from.value = 5
|
56
|
+
to = SimpleEntity.new 'to'
|
57
|
+
to.value = 0
|
58
|
+
}.commit
|
59
|
+
|
60
|
+
threads = []
|
61
|
+
20.times do
|
62
|
+
threads << Thread.new do
|
63
|
+
catch :done do
|
64
|
+
while true do
|
65
|
+
@r.isolate do
|
66
|
+
throw :done if @r['from'].value <= 0
|
67
|
+
|
68
|
+
sleep(rand(10) / 1000.0)
|
69
|
+
|
70
|
+
begin
|
71
|
+
@r.transaction{
|
72
|
+
@r['from'].value -= 1
|
73
|
+
@r['to'].value += 1
|
74
|
+
}.commit
|
75
|
+
rescue OutdatedError
|
76
|
+
next
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
threads.each{|t| t.join}
|
84
|
+
|
85
|
+
@r['from'].value.should == 0
|
86
|
+
@r['to'].value.should == 5
|
87
|
+
end
|
88
|
+
|
89
|
+
# # There are 2 read_streamers and 2 put_streamrs, read_streamers should works in parallel, put_streamrs exclusivelly
|
90
|
+
# #
|
91
|
+
# # 4x5-----8 put_streamr 2
|
92
|
+
# # 2x3---5 put_streamr 1
|
93
|
+
# # 0-1 read_streamer 2
|
94
|
+
# # 0-----3 7x8-9 read_streamer 1
|
95
|
+
# # 0 1 2 3 4 5 6 7 8 9 timeline
|
96
|
+
# #
|
97
|
+
# it "'read' operations should works in parallel and 'write' exclusivelly" do
|
98
|
+
# copy = @r.copy
|
99
|
+
# copy[:first] = SimpleEntity.new :first
|
100
|
+
# copy[:second] = SimpleEntity.new :second
|
101
|
+
# @r.commit
|
102
|
+
#
|
103
|
+
# timer = Timer.new
|
104
|
+
# r1 = mock("read 1")
|
105
|
+
# r1.should_receive(:created).with(0)
|
106
|
+
# r1.should_receive(:start).with(0)
|
107
|
+
# r1.should_receive(:finish).with(3)
|
108
|
+
# Thread.new do
|
109
|
+
# r1.created timer.time
|
110
|
+
# @r.isolate do
|
111
|
+
# r1.start timer.time
|
112
|
+
# @r[:first]
|
113
|
+
# sleep 3
|
114
|
+
# @r[:second]
|
115
|
+
# r1.finish timer.time
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
#
|
119
|
+
# r2 = mock("read 2")
|
120
|
+
# r2.should_receive(:created).with(0)
|
121
|
+
# r2.should_receive(:start).with(0)
|
122
|
+
# r2.should_receive(:finish).with(1)
|
123
|
+
# Thread.new do
|
124
|
+
# r2.created timer.time
|
125
|
+
# @r.isolate do
|
126
|
+
# r2.start timer.time
|
127
|
+
# @r[:first]
|
128
|
+
# sleep 1
|
129
|
+
# @r[:second]
|
130
|
+
# r2.finish timer.time
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# sleep 2
|
135
|
+
#
|
136
|
+
# w1 = mock("write 1")
|
137
|
+
# w1.should_receive(:created).with(2)
|
138
|
+
# w1.should_receive(:start).with(3)
|
139
|
+
# w1.should_receive(:finish).with(5)
|
140
|
+
# Thread.new do
|
141
|
+
# w1.created timer.time
|
142
|
+
# @r.isolate do
|
143
|
+
# copy = @r[:first].copy
|
144
|
+
# copy.value = 'new value'
|
145
|
+
# @r.om_engine.engine_commit_debug(2){w1.start timer.time} # Should sleep for 2 sec
|
146
|
+
# w1.finish timer.time
|
147
|
+
# end
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
# sleep 2
|
151
|
+
#
|
152
|
+
# w2 = mock("write 2")
|
153
|
+
# w2.should_receive(:created).with(4)
|
154
|
+
# w2.should_receive(:start).with(5)
|
155
|
+
# w2.should_receive(:finish).with(8)
|
156
|
+
# Thread.new do
|
157
|
+
# w2.created timer.time
|
158
|
+
# @r.isolate do
|
159
|
+
# copy = @r[:first].copy
|
160
|
+
# copy.value = "new value 2"
|
161
|
+
# @r.om_engine.engine_commit_debug(3){w2.start timer.time;} # Should sleep for 2 sec
|
162
|
+
# w2.finish timer.time
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
#
|
166
|
+
# sleep 3
|
167
|
+
#
|
168
|
+
# r11 = mock("put_streamr 2")
|
169
|
+
# r11.should_receive(:created).with(7)
|
170
|
+
# r11.should_receive(:start).with(8)
|
171
|
+
# r11.should_receive(:finish).with(9)
|
172
|
+
# t = Thread.new do
|
173
|
+
# r11.created timer.time
|
174
|
+
# @r.isolate do
|
175
|
+
# r11.start timer.time
|
176
|
+
# @r[:first]
|
177
|
+
# sleep 1
|
178
|
+
# @r[:second]
|
179
|
+
# r11.finish timer.time
|
180
|
+
# end
|
181
|
+
# end
|
182
|
+
# t.join
|
183
|
+
# end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|