isono 0.1.0 → 0.2.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,64 @@
1
+
2
+ require File.expand_path('../spec_helper', __FILE__)
3
+
4
+ require 'isono'
5
+ include Isono
6
+
7
+ class HookTest < Isono::NodeModules::Base
8
+ before_connect_hook do
9
+ $pass.shift.should.equal :before_connect
10
+ end
11
+
12
+ after_connect_hook do
13
+ $pass.shift.should.equal :after_connect
14
+ end
15
+
16
+ before_close_hook do
17
+ $pass.shift.should.equal :before_close
18
+ end
19
+
20
+ after_close_hook do
21
+ $pass.shift.should.equal :after_close
22
+ end
23
+ end
24
+
25
+ class MockNode < Isono::Node
26
+ def initialize()
27
+ super(Isono::Manifest.new do
28
+ end)
29
+ end
30
+ end
31
+
32
+ describe Isono::Node do
33
+
34
+ em "connects to AMQP broker" do
35
+ a = MockNode.new
36
+ a.connect('amqp://localhost/') {
37
+ a.amqp_client.should.not.nil?
38
+ a.amqp_client.instance_variable_get(:@connection_status).should.is_a?(Proc)
39
+ EM.next_tick {
40
+ a.close {
41
+ EM.stop
42
+ }
43
+ }
44
+ }
45
+ end
46
+
47
+ em "call node_module hooks" do
48
+ $pass = [:before_connect, :after_connect,
49
+ :before_close, :after_close]
50
+ a = Node.new(Isono::Manifest.new do
51
+ load_module HookTest
52
+ end)
53
+ a.connect('amqp://localhost/') {
54
+ EM.next_tick {
55
+ a.close {
56
+ $pass.size.should.equal 0
57
+ EM.stop
58
+ }
59
+ }
60
+ }
61
+ end
62
+
63
+
64
+ end
@@ -0,0 +1,113 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ require 'isono'
4
+
5
+ MM = Isono::ManagerModules
6
+
7
+ describe "ResourceLoader Test" do
8
+
9
+ it "loads manifest block" do
10
+ rm = Isono::ResourceManifest.new('./')
11
+
12
+ Isono::ResourceManifest::Loader.new(rm).instance_eval {
13
+ state_monitor 'Hva::XenInstanceStore::XenMonitor'
14
+ #monitor Hva::XenCapacityMonitor
15
+
16
+ description "resource1"
17
+
18
+ statemachine {
19
+ trans :init, :on_load, :ready
20
+ trans :ready, :on_start, :starting
21
+ trans :starting, :on_online, :running
22
+ trans :running, :on_attach_volume, :attaching_volume
23
+ trans :attaching_volume, :on_back_to_run, :running
24
+ trans :running, :on_stop, :shuttingdown
25
+ trans :shuttingdown, :on_offline, :terminated
26
+ }
27
+
28
+ #entry_state(:running) do
29
+ # resource_graph.find(:connected, my_resource_uuid).each { |res_uuid|
30
+ # on_event :stopped, res_uuid do
31
+ # #do something
32
+ # end
33
+ # }
34
+ #end
35
+
36
+ entry_state(:running) do
37
+ on_event :stop_vm, 'mgr-master' do
38
+ process_event(:on_stop)
39
+ end
40
+
41
+ on_event(:attach_volume, 'storage_node') {
42
+ process_event(:on_attach_volume)
43
+ }
44
+
45
+ task {
46
+ }
47
+ end
48
+
49
+ entry_state(:ready) do
50
+ task do
51
+ # immediatry change the state
52
+ state_monitor.start
53
+ process_event(:on_start)
54
+ end
55
+ end
56
+
57
+ entry_state(:starting) {
58
+ task :rake, 'start_vm'
59
+ }
60
+
61
+ entry_state(:shuttingdown) {
62
+ task :rake, 'stop_vm'
63
+ }
64
+
65
+ entry_state(:attaching_volume) {
66
+ task :rake, 'attach_file_vol'
67
+ }
68
+
69
+ entry_state(:terminated) {
70
+ task do
71
+ state_monitor.stop
72
+ end
73
+ }
74
+
75
+ }
76
+
77
+ rm.stm.should.is_a? Statemachine::Statemachine
78
+
79
+ end
80
+
81
+
82
+
83
+ it "resource instance process" do
84
+
85
+ rm = Isono::ResourceManifest.new('./')
86
+
87
+ Isono::ResourceManifest::Loader.new(rm).instance_eval {
88
+ state_monitor 'Hva::XenInstanceStore::XenMonitor'
89
+ #monitor Hva::XenCapacityMonitor
90
+
91
+ description "resource1"
92
+
93
+ statemachine {
94
+ trans :init, :on_load, :ready
95
+ trans :ready, :on_start, :starting
96
+ trans :starting, :on_online, :running
97
+ trans :running, :on_attach_volume, :attaching_volume
98
+ trans :attaching_volume, :on_back_to_run, :running
99
+ trans :running, :on_stop, :shuttingdown
100
+ trans :shuttingdown, :on_offline, :terminated
101
+ }
102
+ }
103
+
104
+ EM.run {
105
+ Isono::ResourceInstance.start('testuuid', rm, {:amqp_server_uri => URI.parse('amqp://guest:guest@localhost/'),
106
+ })
107
+ EM.add_timer(1) {
108
+ Isono::ResourceInstance.stop
109
+ EM.stop
110
+ }
111
+ }
112
+ end
113
+ end
@@ -0,0 +1,172 @@
1
+
2
+ require File.expand_path('../spec_helper', __FILE__)
3
+
4
+ require 'isono'
5
+
6
+ MM = Isono::NodeModules
7
+ include Isono
8
+
9
+ def client_connect(main_cb, pre_cb=nil, post_cb=nil)
10
+ manifest = Manifest.new(File.expand_path('../', __FILE__)) {
11
+ node_name :cli
12
+ node_instance_id :xxx
13
+
14
+ load_module MM::EventChannel
15
+ load_module MM::RpcChannel
16
+ }
17
+ c = Node.new(manifest)
18
+ pre_cb.call if pre_cb
19
+ c.connect('amqp://localhost/') {
20
+ main_cb.call(c)
21
+ }
22
+ end
23
+
24
+
25
+ def svr_connect(main_cb, pre_cb=nil, post_cb=nil)
26
+ manifest = Manifest.new(File.expand_path('../', __FILE__)) {
27
+ node_name :endpoint
28
+ node_instance_id :xxx
29
+
30
+ load_module MM::EventChannel
31
+ load_module MM::RpcChannel
32
+ }
33
+ c = Node.new(manifest)
34
+ pre_cb.call if pre_cb
35
+ c.connect('amqp://localhost/') {
36
+ main_cb.call(c)
37
+ }
38
+ end
39
+
40
+
41
+ describe Isono::NodeModules::RpcChannel do
42
+ em "creates connection" do
43
+ done = []
44
+ svr_connect(proc{ |c|
45
+ c.close {
46
+ done << 1
47
+ }
48
+ })
49
+
50
+ client_connect(proc {|c|
51
+ c.close {
52
+ done << 1
53
+ }
54
+ })
55
+
56
+ EM.tick_loop {
57
+ if done == [1, 1]
58
+ done.should.equal [1, 1]
59
+ EM.stop
60
+ end
61
+ }
62
+ end
63
+
64
+ em "send async request" do
65
+ svr_connect(proc{|c|
66
+ rpc = MM::RpcChannel.new(c)
67
+ rpc.register_endpoint('endpoint1', Isono::Rack::Map.build { |t|
68
+ t.map('kill') {
69
+ request.args[0].should.equal 'arg1'
70
+ request.args[1].should.equal 'arg2'
71
+ request.args[2].should.equal 'arg3'
72
+
73
+ EM.next_tick { EM.stop }
74
+ response.response({:code=>1})
75
+ }
76
+ })
77
+ })
78
+ client_connect(proc {|c|
79
+ rpc = MM::RpcChannel.new(c)
80
+ req0 = rpc.request('endpoint1', 'kill', 'arg1', "arg2", "arg3") { |req|
81
+ req.on_success { |res|
82
+ req0.ticket.should.equal req.ticket
83
+ res[:code].should.equal 1
84
+ c.close
85
+ }
86
+ }
87
+ }
88
+ )
89
+
90
+ end
91
+
92
+
93
+ em "request timeout" do
94
+ client_connect(proc {|c|
95
+ rpc = MM::RpcChannel.new(c)
96
+ rpc.request('test', 'test1') { |req|
97
+ req.timeout_sec = 0.2
98
+ req.on_error { |e|
99
+ e.should.equal :timeout
100
+ c.close { EM.stop }
101
+ }
102
+ }
103
+ })
104
+ end
105
+
106
+
107
+ em "use Isono::Rack dispatcher" do
108
+ func1_count = 0
109
+ svr_connect(proc{|c|
110
+ rpc = MM::RpcChannel.new(c)
111
+ endpoint1 = Isono::Rack::Map.build { |t|
112
+ t.map('kill') {
113
+ func1_count.should.equal 10
114
+ EM.next_tick { EM.stop }
115
+ }
116
+ t.map('func1') {
117
+ request.args[0].should.equal 'arg1'
118
+ func1_count += 1
119
+ response.response({:code=>1})
120
+ }
121
+ }
122
+
123
+ rpc.register_endpoint('endpoint1', Isono::Rack::ThreadPass.new(endpoint1))
124
+ })
125
+ client_connect(proc {|c|
126
+ rpc = MM::RpcChannel.new(c)
127
+ 10.times { |no|
128
+ req0 = rpc.request('endpoint1', 'func1', 'arg1') { |req|
129
+ req.on_success { |res|
130
+ req0.ticket.should.equal req.ticket
131
+ req0.complete_status.should.equal :success
132
+ #((req0.completed_at - req0.sent_at) > 1.5).should.be.true
133
+ res[:code].should.equal 1
134
+ #puts "#{no} elapesed: #{req0.elapsed_time}"
135
+ if no == 9
136
+ rpc.request('endpoint1', 'kill') do |req|
137
+ req.on_success { |res|
138
+ res[:code].should.equal 1
139
+ }
140
+ end
141
+ end
142
+ }
143
+ }
144
+ }
145
+ })
146
+
147
+ end
148
+
149
+ em "catch remote exception" do
150
+ svr_connect(proc{|c|
151
+ rpc = MM::RpcChannel.new(c)
152
+ rpc.register_endpoint('endpoint1', Isono::Rack::Map.build { |t|
153
+ t.map('kill') {
154
+ raise StandardError, "message"
155
+ response.response({:code=>1})
156
+ }
157
+ })
158
+ }, proc{
159
+ })
160
+ client_connect(proc {|c|
161
+ rpc = MM::RpcChannel.new(c)
162
+ rpc.request('endpoint1', 'kill') { |req|
163
+ req.on_error { |e|
164
+ e.should.equal({:error_type=>'StandardError', :message=>'message'})
165
+ EM.stop
166
+ }
167
+ }
168
+ })
169
+
170
+ end
171
+
172
+ end
@@ -0,0 +1,62 @@
1
+
2
+ require 'rubygems'
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+
6
+ require 'bacon'
7
+ #require 'spec'
8
+ require 'isono'
9
+
10
+ class AmqpStub < Isono::Node
11
+ include Isono::Logger
12
+
13
+
14
+ def fork_and_connect(broker_uri='amqp://localhost/', *args, &blk)
15
+ EM.fork_reactor {
16
+ connect(broker_uri, *args, &blk)
17
+ }
18
+ end
19
+
20
+ def connect(broker_uri='amqp://localhost/', *args, &blk)
21
+ super
22
+ end
23
+
24
+ def on_connect
25
+ manifest.managers.each { |a|
26
+ a[0].class.reset_instance
27
+ }
28
+
29
+ super
30
+ end
31
+
32
+ #def on_close
33
+ #end
34
+
35
+
36
+ def mm_instance(mgr_class, *args)
37
+ raise ArgumentError unless mgr_class < Isono::ManagerModules::Base
38
+
39
+ m = mgr_class.instance
40
+ m.agent = self
41
+ m.on_init(args)
42
+ m
43
+ end
44
+ end
45
+
46
+
47
+ def em_fork(main_cb, post_cb=nil)
48
+ fork {
49
+ EM.run {
50
+ main_cb.call
51
+ }
52
+ post_cb.call if post_cb
53
+ }
54
+ end
55
+
56
+ class Bacon::Context
57
+ def em(desc, &blk)
58
+ it(desc) {
59
+ EM.run &blk
60
+ }
61
+ end
62
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ require 'isono'
4
+
5
+
6
+ describe "ThreadPool Test" do
7
+
8
+ it "create a thread pool" do
9
+ a = Isono::ThreadPool.new
10
+ #a.should Isono::ThreadPool
11
+ end
12
+
13
+ it "call pass() with single thread" do
14
+ a = Isono::ThreadPool.new
15
+ t = 0
16
+ a.pass { t = 1 }
17
+
18
+ t.should eql(1)
19
+ end
20
+
21
+ it "call barrier() with single thread" do
22
+ a = Isono::ThreadPool.new
23
+ t = 0
24
+ a.barrier { t = 1 }
25
+
26
+ t.should eql(1)
27
+ end
28
+
29
+ it "catch exception from barrier()" do
30
+ a = Isono::ThreadPool.new
31
+ lambda {
32
+ a.barrier { raise "Error" }
33
+ }.should raise_error(RuntimeError, "Error")
34
+ end
35
+ end