-
Notifications
You must be signed in to change notification settings - Fork 128
/
initializer_spec.rb
310 lines (256 loc) · 11.8 KB
/
initializer_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# encoding: utf-8
require 'spec_helper'
module Adhearsion
class PunchblockPlugin
describe Initializer do
def reset_default_config
Adhearsion.config.punchblock do |config|
config.platform = :xmpp
config.username = "usera@127.0.0.1"
config.password = "1"
config.host = nil
config.port = nil
config.certs_directory = nil
config.root_domain = nil
config.connection_timeout = 60
config.reconnect_attempts = 1.0/0.0
config.reconnect_timer = 5
end
end
def initialize_punchblock(options = {})
reset_default_config
allow(Initializer).to receive(:connect)
Adhearsion.config.punchblock do |config|
config.platform = options[:platform] if options.has_key?(:platform)
config.username = options[:username] if options.has_key?(:username)
config.password = options[:password] if options.has_key?(:password)
config.host = options[:host] if options.has_key?(:host)
config.port = options[:port] if options.has_key?(:port)
config.certs_directory = options[:certs_directory] if options.has_key?(:certs_directory)
config.root_domain = options[:root_domain] if options.has_key?(:root_domain)
config.connection_timeout = options[:connection_timeout] if options.has_key?(:connection_timeout)
config.reconnect_attempts = options[:reconnect_attempts] if options.has_key?(:reconnect_attempts)
config.reconnect_timer = options[:reconnect_timer] if options.has_key?(:reconnect_timer)
end
Initializer.init
Adhearsion.config[:punchblock]
end
let(:call_id) { rand.to_s }
let(:offer) { Punchblock::Event::Offer.new :target_call_id => call_id }
let(:mock_call) { Call.new }
let(:mock_client) { double 'Client' }
before do
allow(mock_call).to receive_messages :id => call_id
mock_client.as_null_object
allow(mock_client).to receive_messages :event_handler= => true
Events.refresh!
allow(Adhearsion::Process).to receive_messages :fqdn => 'hostname'
allow(::Process).to receive_messages :pid => 1234
end
describe "starts the client with the default values" do
subject { initialize_punchblock }
it "should set properly the username value" do
expect(subject.username).to eq('usera@127.0.0.1')
end
it "should set properly the password value" do
expect(subject.password).to eq('1')
end
it "should set properly the host value" do
expect(subject.host).to be_nil
end
it "should set properly the port value" do
expect(subject.port).to be_nil
end
it "should set properly the certs_directory value" do
expect(subject.certs_directory).to be_nil
end
it "should set properly the root_domain value" do
expect(subject.root_domain).to be_nil
end
it "should properly set the reconnect_attempts value" do
expect(subject.reconnect_attempts).to eq(1.0/0.0)
end
it "should properly set the reconnect_timer value" do
expect(subject.reconnect_timer).to eq(5)
end
end
it "starts the client with the correct resource" do
username = "usera@127.0.0.1/hostname-1234"
expect(Punchblock::Connection::XMPP).to receive(:new).once.with(hash_including :username => username).and_return mock_client
initialize_punchblock
end
context "when the fqdn is not available" do
it "should use the local hostname instead" do
allow(Adhearsion::Process).to receive(:fqdn).and_raise SocketError
allow(Socket).to receive(:gethostname).and_return 'local_hostname'
username = "usera@127.0.0.1/local_hostname-1234"
expect(Punchblock::Connection::XMPP).to receive(:new).once.with(hash_including :username => username).and_return mock_client
initialize_punchblock
end
end
it "starts the client with any overridden settings" do
expect(Punchblock::Connection::XMPP).to receive(:new).once.with(username: 'userb@127.0.0.1/foo', password: '123', host: 'foo.bar.com', port: 200, certs: '/foo/bar', connection_timeout: 20, root_domain: 'foo.com').and_return mock_client
initialize_punchblock username: 'userb@127.0.0.1/foo', password: '123', host: 'foo.bar.com', port: 200, certs_directory: '/foo/bar', connection_timeout: 20, root_domain: 'foo.com'
end
describe "#connect" do
it 'should block until the connection is established' do
reset_default_config
mock_connection = double :mock_connection
expect(mock_connection).to receive(:register_event_handler).once
expect(Punchblock::Client).to receive(:new).once.and_return mock_connection
expect(mock_connection).to receive(:run).once
t = Thread.new { Initializer.init; Initializer.run }
t.join 5
expect(t.status).to eq("sleep")
Events.trigger_immediately :punchblock, Punchblock::Connection::Connected.new
t.join
end
end
describe '#connect_to_server' do
before :each do
Adhearsion::Process.reset
Initializer.config = reset_default_config
Initializer.config.reconnect_attempts = 1
expect(Adhearsion::Logging.get_logger(Initializer)).to receive(:fatal).at_most(:once)
allow(Initializer).to receive(:client).and_return mock_client
end
after :each do
Adhearsion::Process.reset
end
it 'should reset the Adhearsion process state to "booting"' do
Adhearsion::Process.booted
expect(Adhearsion::Process.state_name).to eq(:running)
allow(mock_client).to receive(:run).and_raise Punchblock::DisconnectedError
expect(Adhearsion::Process).to receive(:reset).at_least(:once)
Initializer.connect_to_server
end
it 'should retry the connection the specified number of times' do
Initializer.config.reconnect_attempts = 3
allow(mock_client).to receive(:run).and_raise Punchblock::DisconnectedError
Initializer.connect_to_server
expect(Initializer.attempts).to eq(3)
end
it 'should preserve a Punchblock::ProtocolError exception and give up' do
allow(mock_client).to receive(:run).and_raise Punchblock::ProtocolError
expect { Initializer.connect_to_server }.to raise_error Punchblock::ProtocolError
end
it 'should not attempt to reconnect if Adhearsion is shutting down' do
Adhearsion::Process.booted
Adhearsion::Process.shutdown
allow(mock_client).to receive(:run).and_raise Punchblock::DisconnectedError
expect { Initializer.connect_to_server }.not_to raise_error
end
end
describe 'using Asterisk' do
let(:overrides) { {:username => 'test', :password => '123', :host => 'foo.bar.com', :port => 200, :certs => nil, :connection_timeout => 20, :root_domain => 'foo.com'} }
it 'should start an Asterisk PB connection' do
expect(Punchblock::Connection::Asterisk).to receive(:new).once.with(overrides).and_return mock_client
initialize_punchblock overrides.merge(:platform => :asterisk)
end
end
describe 'using FreeSWITCH' do
let(:overrides) { {:username => 'test', :password => '123', :host => 'foo.bar.com', :port => 200, :certs => nil, :connection_timeout => 20, :root_domain => 'foo.com'} }
it 'should start a FreeSWITCH PB connection' do
expect(Punchblock::Connection::Freeswitch).to receive(:new).once.with(overrides).and_return mock_client
initialize_punchblock overrides.merge(:platform => :freeswitch)
end
end
it 'should place events from Punchblock into the event handler' do
expect(Events.instance).to receive(:trigger).once.with(:punchblock, offer)
initialize_punchblock
expect(Adhearsion::Call).to receive(:new).once.and_return mock_call
allow(mock_call).to receive_message_chain("async.route")
Initializer.client.handle_event offer
end
describe "dispatching a component event" do
let(:component) { double 'ComponentNode' }
let(:mock_event) { double 'Event' }
before { allow(mock_event).to receive_messages target_call_id: call_id, source: component }
before do
initialize_punchblock
end
it "should place the event in the call's inbox" do
expect(component).to receive(:trigger_event_handler).once.with mock_event
Events.trigger_immediately :punchblock, mock_event
end
end
describe "dispatching a call event" do
let(:mock_event) { double 'Event' }
before { allow(mock_event).to receive_messages target_call_id: call_id }
describe "with an active call" do
before do
initialize_punchblock
Adhearsion.active_calls << mock_call
end
it "should forward the event to the call actor" do
events = []
mock_call.register_event_handler do |event|
events << event
end
Initializer.dispatch_call_event mock_event
sleep 0.5
expect(events).to eql([mock_event])
end
it "should not block on the call handling the event" do
mock_call.register_event_handler do |event|
sleep 5
end
start_time = Time.now
Initializer.dispatch_call_event mock_event
sleep 0.5
expect(Time.now - start_time).to be < 1
end
end
describe "with an inactive call" do
it "should log a warning" do
expect(Adhearsion::Logging.get_logger(Initializer)).to receive(:warn).once.with("Event received for inactive call #{call_id}: #{mock_event.inspect}")
Initializer.dispatch_call_event mock_event
end
end
describe "when the registry contains a dead call" do
before do
mock_call.terminate
Adhearsion.active_calls[mock_call.id] = mock_call
end
it "should log a warning" do
expect(Adhearsion::Logging.get_logger(Initializer)).to receive(:warn).once.with("Event received for inactive call #{call_id}: #{mock_event.inspect}")
Initializer.dispatch_call_event mock_event
end
end
end
context "Punchblock configuration" do
describe "with config specified" do
before do
Adhearsion.config.punchblock do |config|
config.username = 'userb@127.0.0.1'
config.password = 'abc123'
end
end
subject do
Adhearsion.config[:punchblock]
end
it "should set properly the username value" do
expect(subject.username).to eq('userb@127.0.0.1')
end
it "should set properly the password value" do
expect(subject.password).to eq('abc123')
end
end
end
it "should allow easily registering handlers for AMI events" do
result = nil
ami_event = Punchblock::Event::Asterisk::AMI::Event.new :name => 'foobar'
latch = CountDownLatch.new 1
Events.draw do
ami :name => 'foobar' do |event|
result = event
latch.countdown!
end
end
Initializer.handle_event ami_event
expect(latch.wait(1)).to be true
expect(result).to be ami_event
end
end
end
end