hyperactive 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/GPL-2 +339 -0
- data/README +33 -0
- data/lib/hyperactive/hooker.rb +63 -0
- data/lib/hyperactive/record.rb +358 -0
- data/lib/hyperactive/tree.rb +216 -0
- data/lib/hyperactive.rb +6 -0
- data/tests/record_test.rb +158 -0
- data/tests/test_helper.rb +66 -0
- data/tests/tree_benchmark.rb +66 -0
- data/tests/tree_test.rb +75 -0
- metadata +65 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
3
|
+
|
4
|
+
class MyRecord < Hyperactive::Record
|
5
|
+
attr_accessor :bajs
|
6
|
+
|
7
|
+
def self.save_hook(instance, &block)
|
8
|
+
$BEFORE_SAVE += 1
|
9
|
+
yield
|
10
|
+
$AFTER_SAVE += 1
|
11
|
+
end
|
12
|
+
save_hooks << self.method(:save_hook)
|
13
|
+
|
14
|
+
def self.create_hook(instance, &block)
|
15
|
+
$BEFORE_CREATE += 1
|
16
|
+
yield
|
17
|
+
$AFTER_CREATE += 1
|
18
|
+
end
|
19
|
+
create_hooks << self.method(:create_hook)
|
20
|
+
|
21
|
+
def self.destroy_hook(instance, &block)
|
22
|
+
$BEFORE_DESTROY += 1
|
23
|
+
yield
|
24
|
+
$AFTER_DESTROY += 1
|
25
|
+
end
|
26
|
+
destroy_hooks << self.method(:destroy_hook)
|
27
|
+
end
|
28
|
+
|
29
|
+
class RecordTest < Test::Unit::TestCase
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@c = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest.db")))
|
33
|
+
@c.publish!
|
34
|
+
@c2 = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest2.db")))
|
35
|
+
@c2.publish!
|
36
|
+
@tm = TestManager.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("tranny1.db")))
|
37
|
+
@tm.publish!
|
38
|
+
Hyperactive::CAPTAIN.setup(:chest_description => {:class => 'TestChest'},
|
39
|
+
:tranny_description => {:class => 'TestManager'})
|
40
|
+
Hyperactive::CAPTAIN.update_services!
|
41
|
+
assert_within(10) do
|
42
|
+
Hyperactive::CAPTAIN.chests.keys.sort == [@c.service_id, @c2.service_id].sort
|
43
|
+
end
|
44
|
+
assert_within(10) do
|
45
|
+
Hyperactive::CAPTAIN.trannies.keys == [@tm.service_id]
|
46
|
+
end
|
47
|
+
$BEFORE_SAVE = 0
|
48
|
+
$AFTER_SAVE = 0
|
49
|
+
$BEFORE_DESTROY = 0
|
50
|
+
$AFTER_DESTROY = 0
|
51
|
+
$BEFORE_CREATE = 0
|
52
|
+
$AFTER_CREATE = 0
|
53
|
+
end
|
54
|
+
|
55
|
+
def teardown
|
56
|
+
@c.stop!
|
57
|
+
@c.persistence_provider.unlink
|
58
|
+
@c2.stop!
|
59
|
+
@c2.persistence_provider.unlink
|
60
|
+
@tm.stop!
|
61
|
+
@tm.persistence_provider.unlink
|
62
|
+
Archipelago::Disco::MC.clear!
|
63
|
+
Hyperactive::CAPTAIN.update_services!
|
64
|
+
assert_within(10) do
|
65
|
+
Hyperactive::CAPTAIN.chests.empty?
|
66
|
+
end
|
67
|
+
assert_within(10) do
|
68
|
+
Hyperactive::CAPTAIN.trannies.empty?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_index_find
|
73
|
+
MyRecord.class_eval do
|
74
|
+
index_by :bajs
|
75
|
+
end
|
76
|
+
r1 = MyRecord.get_instance
|
77
|
+
r1.bajs = "brunt"
|
78
|
+
r2 = MyRecord.get_instance
|
79
|
+
r2.bajs = "brunt"
|
80
|
+
r3 = MyRecord.get_instance
|
81
|
+
r3.bajs = "gult"
|
82
|
+
r4 = MyRecord.get_instance
|
83
|
+
r4.bajs = "beige"
|
84
|
+
|
85
|
+
assert_equal(Set.new([r2.record_id,r1.record_id]), Set.new(MyRecord.find_by_bajs("brunt").collect(Proc.new do |k,v|
|
86
|
+
v.record_id
|
87
|
+
end)))
|
88
|
+
assert_equal([r3.record_id], MyRecord.find_by_bajs("gult").collect(Proc.new do |k,v|
|
89
|
+
v.record_id
|
90
|
+
end))
|
91
|
+
|
92
|
+
r1.destroy
|
93
|
+
|
94
|
+
assert_equal([r2.record_id], MyRecord.find_by_bajs("brunt").collect(Proc.new do |k,v|
|
95
|
+
v.record_id
|
96
|
+
end))
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_select_reject
|
101
|
+
MyRecord.class_eval do
|
102
|
+
select(:brunt, Proc.new do |r|
|
103
|
+
r.bajs == "brunt"
|
104
|
+
end)
|
105
|
+
reject(:not_brunt, Proc.new do |r|
|
106
|
+
r.bajs == "brunt"
|
107
|
+
end)
|
108
|
+
end
|
109
|
+
r1 = MyRecord.get_instance
|
110
|
+
r1.bajs = "brunt"
|
111
|
+
r2 = MyRecord.get_instance
|
112
|
+
r2.bajs = "brunt"
|
113
|
+
r3 = MyRecord.get_instance
|
114
|
+
r3.bajs = "gult"
|
115
|
+
r4 = MyRecord.get_instance
|
116
|
+
r4.bajs = "beige"
|
117
|
+
|
118
|
+
assert_equal(Set.new([r2.record_id,r1.record_id]), Set.new(MyRecord.brunt.collect(Proc.new do |k,v|
|
119
|
+
v.record_id
|
120
|
+
end)))
|
121
|
+
assert_equal(Set.new([r3.record_id,r4.record_id]), Set.new(MyRecord.not_brunt.collect(Proc.new do |k,v|
|
122
|
+
v.record_id
|
123
|
+
end)))
|
124
|
+
|
125
|
+
r1.destroy
|
126
|
+
r2.destroy
|
127
|
+
r3.destroy
|
128
|
+
r4.destroy
|
129
|
+
|
130
|
+
assert_equal(Set.new, Set.new(MyRecord.brunt.collect(Proc.new do |k,v|
|
131
|
+
v.record_id
|
132
|
+
end)))
|
133
|
+
assert_equal(Set.new, Set.new(MyRecord.not_brunt.collect(Proc.new do |k,v|
|
134
|
+
v.record_id
|
135
|
+
end)))
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_create_update_destroy
|
139
|
+
r = MyRecord.get_instance
|
140
|
+
assert(Archipelago::Treasure::Dubloon === r)
|
141
|
+
assert_equal(1, $BEFORE_SAVE)
|
142
|
+
assert_equal(1, $AFTER_SAVE)
|
143
|
+
assert_equal(1, $BEFORE_CREATE)
|
144
|
+
assert_equal(1, $AFTER_CREATE)
|
145
|
+
r.bajs = "brunt"
|
146
|
+
assert_equal(2, $BEFORE_SAVE)
|
147
|
+
assert_equal(2, $AFTER_SAVE)
|
148
|
+
assert_equal("brunt", r.bajs)
|
149
|
+
assert_equal("brunt", Hyperactive::CAPTAIN[r.record_id].bajs)
|
150
|
+
i = r.record_id
|
151
|
+
assert_equal(r, Hyperactive::CAPTAIN[i])
|
152
|
+
r.destroy
|
153
|
+
assert_equal(1, $BEFORE_DESTROY)
|
154
|
+
assert_equal(1, $AFTER_DESTROY)
|
155
|
+
assert_equal(nil, Hyperactive::CAPTAIN[i])
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
home = File.expand_path(File.dirname(__FILE__))
|
3
|
+
$: << File.join(home, "..", "lib")
|
4
|
+
|
5
|
+
require 'hyperactive'
|
6
|
+
require 'pp'
|
7
|
+
require 'test/unit'
|
8
|
+
require 'benchmark'
|
9
|
+
require 'drb'
|
10
|
+
require 'archipelago'
|
11
|
+
require 'socket'
|
12
|
+
require 'ipaddr'
|
13
|
+
require 'thread'
|
14
|
+
|
15
|
+
DRb.start_service
|
16
|
+
|
17
|
+
class TestTransaction
|
18
|
+
def join(o)
|
19
|
+
end
|
20
|
+
def state
|
21
|
+
:active
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class TestManager < Archipelago::Tranny::Manager
|
26
|
+
attr_reader :persistence_provider
|
27
|
+
def log_error(e)
|
28
|
+
puts e
|
29
|
+
pp e.backtrace
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class TestJockey < Archipelago::Disco::Jockey
|
34
|
+
attr_reader :remote_services, :local_services
|
35
|
+
end
|
36
|
+
|
37
|
+
class TestChest < Archipelago::Treasure::Chest
|
38
|
+
attr_reader :persistence_provider
|
39
|
+
end
|
40
|
+
|
41
|
+
def bm(label = "", options = {})
|
42
|
+
n = options[:n] || 1000
|
43
|
+
width = options[:width] || 50
|
44
|
+
Benchmark.benchmark(" " * width + Benchmark::Tms::CAPTION, width, Benchmark::Tms::FMTSTR, "ms/call") do |b|
|
45
|
+
times = b.report("#{n}x#{label}") do
|
46
|
+
n.times do
|
47
|
+
yield
|
48
|
+
end
|
49
|
+
end
|
50
|
+
[times * 1000 / n.to_f]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Test::Unit::TestCase
|
55
|
+
|
56
|
+
def assert_within(timeout, &block)
|
57
|
+
t = Time.new
|
58
|
+
rval = yield
|
59
|
+
while !rval && t > Time.new - timeout
|
60
|
+
rval = yield
|
61
|
+
sleep(0.05)
|
62
|
+
end
|
63
|
+
assert(rval)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
3
|
+
|
4
|
+
class TreeBenchmark < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@c = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest.db")))
|
8
|
+
@c.publish!
|
9
|
+
@c2 = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest2.db")))
|
10
|
+
@c2.publish!
|
11
|
+
@tm = TestManager.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("tranny1.db")))
|
12
|
+
@tm.publish!
|
13
|
+
Hyperactive::CAPTAIN.setup(:chest_description => {:class => 'TestChest'},
|
14
|
+
:tranny_description => {:class => 'TestManager'})
|
15
|
+
assert_within(20) do
|
16
|
+
Set.new(Hyperactive::CAPTAIN.chests.keys) == Set.new([@c.service_id, @c2.service_id])
|
17
|
+
end
|
18
|
+
assert_within(20) do
|
19
|
+
Hyperactive::CAPTAIN.trannies.keys == [@tm.service_id]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
@c.stop!
|
25
|
+
@c.persistence_provider.unlink
|
26
|
+
@c2.stop!
|
27
|
+
@c2.persistence_provider.unlink
|
28
|
+
@tm.stop!
|
29
|
+
@tm.persistence_provider.unlink
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_set_get
|
33
|
+
h = Hyperactive::Tree.get_instance
|
34
|
+
r = Hyperactive::Record.get_instance
|
35
|
+
hash_test("Tree", h, r, 100)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_regular_hash_set_get
|
39
|
+
Hyperactive::CAPTAIN["h"] = {}
|
40
|
+
h = Hyperactive::CAPTAIN["h"]
|
41
|
+
r = Hyperactive::Record.get_instance
|
42
|
+
hash_test("Hash", h, r, 100)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def hash_test(label, h, r, c)
|
48
|
+
bm("#{label}#set/get/delete", :n => c * 1) do
|
49
|
+
f = rand(1 << 32)
|
50
|
+
h[f] = r
|
51
|
+
x = h[f]
|
52
|
+
h.delete(f)
|
53
|
+
end
|
54
|
+
bm("#{label}#set", :n => c * 10) do
|
55
|
+
f = rand(1 << 32)
|
56
|
+
h[f] = r
|
57
|
+
end
|
58
|
+
bm("#{label}#set/get/delete (big)", :n => c * 1) do
|
59
|
+
f = rand(1 << 32)
|
60
|
+
h[f] = r
|
61
|
+
x = h[f]
|
62
|
+
h.delete(f)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/tests/tree_test.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
3
|
+
|
4
|
+
class RecordMatcher
|
5
|
+
def initialize(i)
|
6
|
+
@i = i
|
7
|
+
end
|
8
|
+
def call(k,v)
|
9
|
+
k == @i
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TreeTest < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@c = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest.db")))
|
17
|
+
@c.publish!
|
18
|
+
@c2 = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest2.db")))
|
19
|
+
@c2.publish!
|
20
|
+
@tm = TestManager.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("tranny1.db")))
|
21
|
+
@tm.publish!
|
22
|
+
Hyperactive::CAPTAIN.setup(:chest_description => {:class => 'TestChest'},
|
23
|
+
:tranny_description => {:class => 'TestManager'})
|
24
|
+
Hyperactive::CAPTAIN.update_services!
|
25
|
+
assert_within(10) do
|
26
|
+
Hyperactive::CAPTAIN.chests.keys.sort == [@c.service_id, @c2.service_id].sort
|
27
|
+
end
|
28
|
+
assert_within(10) do
|
29
|
+
Hyperactive::CAPTAIN.trannies.keys == [@tm.service_id]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def teardown
|
34
|
+
@c.stop!
|
35
|
+
@c.persistence_provider.unlink
|
36
|
+
@c2.stop!
|
37
|
+
@c2.persistence_provider.unlink
|
38
|
+
@tm.stop!
|
39
|
+
@tm.persistence_provider.unlink
|
40
|
+
Archipelago::Disco::MC.clear!
|
41
|
+
Hyperactive::CAPTAIN.update_services!
|
42
|
+
assert_within(10) do
|
43
|
+
Hyperactive::CAPTAIN.chests.empty?
|
44
|
+
end
|
45
|
+
assert_within(10) do
|
46
|
+
Hyperactive::CAPTAIN.trannies.empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_select_reject
|
51
|
+
h = Hyperactive::Tree.get_instance
|
52
|
+
r1 = Hyperactive::Record.get_instance
|
53
|
+
r2 = Hyperactive::Record.get_instance
|
54
|
+
h[r1.record_id] = r1
|
55
|
+
h[r2.record_id] = r2
|
56
|
+
assert_equal(r1.record_id, h.select(RecordMatcher.new(r1.record_id)).first.first)
|
57
|
+
assert_equal(r1.record_id, h.reject(RecordMatcher.new(r2.record_id)).keys.first)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_set_get
|
61
|
+
h = Hyperactive::Tree.get_instance
|
62
|
+
h2 = {}
|
63
|
+
10.times do
|
64
|
+
r = Hyperactive::Record.get_instance
|
65
|
+
h[r.record_id] = r
|
66
|
+
h2[r.record_id] = r
|
67
|
+
end
|
68
|
+
|
69
|
+
h2.each do |k,v|
|
70
|
+
assert_equal(v, h[k])
|
71
|
+
assert_equal(v, Hyperactive::CAPTAIN[h.record_id][k])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: hyperactive
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2006-11-27 00:00:00 +01:00
|
8
|
+
summary: A base class for persistent objects that uses archipelago for persistence. Useful for Ruby on Rails models for example.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: zond at troja dot ath dot cx
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: hyperactive
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Martin Kihlgren
|
30
|
+
files:
|
31
|
+
- lib/hyperactive.rb
|
32
|
+
- lib/hyperactive/hooker.rb
|
33
|
+
- lib/hyperactive/record.rb
|
34
|
+
- lib/hyperactive/tree.rb
|
35
|
+
- tests/record_test.rb
|
36
|
+
- tests/test_helper.rb
|
37
|
+
- tests/tree_benchmark.rb
|
38
|
+
- tests/tree_test.rb
|
39
|
+
- GPL-2
|
40
|
+
- README
|
41
|
+
test_files:
|
42
|
+
- tests/record_test.rb
|
43
|
+
- tests/tree_test.rb
|
44
|
+
- tests/test_helper.rb
|
45
|
+
rdoc_options:
|
46
|
+
- --line-numbers
|
47
|
+
- --inline-source
|
48
|
+
extra_rdoc_files:
|
49
|
+
- README
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
dependencies:
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: archipelago
|
59
|
+
version_requirement:
|
60
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 0.2.0
|
65
|
+
version:
|