sippy_cup 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +0 -2
- data/CHANGELOG.md +16 -0
- data/Guardfile +1 -1
- data/README.markdown +35 -2
- data/bin/sippy_cup +9 -1
- data/examples/navigate_ivr.yml +14 -0
- data/examples/simple_call.yml +11 -0
- data/examples/wait_for_call.yml +15 -0
- data/lib/sippy_cup/runner.rb +46 -10
- data/lib/sippy_cup/scenario.rb +268 -54
- data/lib/sippy_cup/version.rb +1 -1
- data/sippy_cup.gemspec +1 -1
- data/spec/sippy_cup/runner_spec.rb +102 -12
- data/spec/sippy_cup/scenario_spec.rb +78 -83
- data/spec/spec_helper.rb +1 -1
- metadata +8 -7
- data/.ruby-version +0 -1
data/lib/sippy_cup/version.rb
CHANGED
data/sippy_cup.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_runtime_dependency 'packetfu'
|
22
22
|
s.add_runtime_dependency 'nokogiri', ["~> 1.6.0"]
|
23
|
-
s.add_runtime_dependency 'activesupport', ["
|
23
|
+
s.add_runtime_dependency 'activesupport', ["~> 3.0"]
|
24
24
|
s.add_runtime_dependency 'psych', ["~> 2.0.1"] unless RUBY_PLATFORM == 'java'
|
25
25
|
|
26
26
|
s.add_development_dependency 'guard-rspec'
|
@@ -20,7 +20,7 @@ describe SippyCup::Runner do
|
|
20
20
|
name: foobar
|
21
21
|
source: 'dah.com'
|
22
22
|
destination: 'bar.com'
|
23
|
-
|
23
|
+
concurrent_max: 5
|
24
24
|
calls_per_second: 2
|
25
25
|
number_of_calls: 10
|
26
26
|
steps:
|
@@ -48,7 +48,7 @@ steps:
|
|
48
48
|
describe '#run' do
|
49
49
|
it "executes the correct command to invoke SIPp" do
|
50
50
|
full_scenario_path = File.join(Dir.tmpdir, '/scenario.*')
|
51
|
-
expect_command_execution %r{sudo \$\(which sipp\) -
|
51
|
+
expect_command_execution %r{sudo \$\(which sipp\) -p 8836 -sf #{full_scenario_path} -l 5 -m 10 -r 2 -s 1 -i dah.com bar.com}
|
52
52
|
subject.run
|
53
53
|
end
|
54
54
|
|
@@ -89,7 +89,7 @@ steps:
|
|
89
89
|
name: foobar
|
90
90
|
source: 'dah.com'
|
91
91
|
destination: 'bar.com'
|
92
|
-
|
92
|
+
concurrent_max: 5
|
93
93
|
calls_per_second: 2
|
94
94
|
number_of_calls: 10
|
95
95
|
options:
|
@@ -119,7 +119,7 @@ steps:
|
|
119
119
|
name: foobar
|
120
120
|
source: 'dah.com'
|
121
121
|
destination: 'bar.com'
|
122
|
-
|
122
|
+
concurrent_max: 5
|
123
123
|
calls_per_second: 2
|
124
124
|
number_of_calls: 10
|
125
125
|
source_port: 1234
|
@@ -147,7 +147,7 @@ steps:
|
|
147
147
|
name: foobar
|
148
148
|
source: 'dah.com'
|
149
149
|
destination: 'bar.com'
|
150
|
-
|
150
|
+
concurrent_max: 5
|
151
151
|
calls_per_second: 2
|
152
152
|
number_of_calls: 10
|
153
153
|
from_user: pat
|
@@ -176,7 +176,7 @@ steps:
|
|
176
176
|
name: foobar
|
177
177
|
source: 'dah.com'
|
178
178
|
destination: 'bar.com'
|
179
|
-
|
179
|
+
concurrent_max: 5
|
180
180
|
calls_per_second: 2
|
181
181
|
number_of_calls: 10
|
182
182
|
media_port: 6000
|
@@ -204,7 +204,7 @@ steps:
|
|
204
204
|
name: foobar
|
205
205
|
source: 'dah.com'
|
206
206
|
destination: 'bar.com'
|
207
|
-
|
207
|
+
concurrent_max: 5
|
208
208
|
calls_per_second: 2
|
209
209
|
number_of_calls: 10
|
210
210
|
stats_file: stats.csv
|
@@ -231,7 +231,7 @@ steps:
|
|
231
231
|
name: foobar
|
232
232
|
source: 'dah.com'
|
233
233
|
destination: 'bar.com'
|
234
|
-
|
234
|
+
concurrent_max: 5
|
235
235
|
calls_per_second: 2
|
236
236
|
number_of_calls: 10
|
237
237
|
stats_file: stats.csv
|
@@ -269,13 +269,99 @@ steps:
|
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
272
|
+
context "specifying a summary report file in the manifest" do
|
273
|
+
let(:manifest) do
|
274
|
+
<<-MANIFEST
|
275
|
+
name: foobar
|
276
|
+
source: 'dah.com'
|
277
|
+
destination: 'bar.com'
|
278
|
+
concurrent_max: 5
|
279
|
+
calls_per_second: 2
|
280
|
+
number_of_calls: 10
|
281
|
+
summary_report_file: report.txt
|
282
|
+
steps:
|
283
|
+
- invite
|
284
|
+
- wait_for_answer
|
285
|
+
- ack_answer
|
286
|
+
- sleep 3
|
287
|
+
- send_digits 'abc'
|
288
|
+
- sleep 5
|
289
|
+
- send_digits '#'
|
290
|
+
- wait_for_hangup
|
291
|
+
MANIFEST
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should turn on -trace_screen and set the -screen_file option to the filename provided' do
|
295
|
+
expect_command_execution(/-trace_screen -screen_file report.txt/)
|
296
|
+
subject.run
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context "specifying a errors report file in the manifest" do
|
301
|
+
let(:manifest) do
|
302
|
+
<<-MANIFEST
|
303
|
+
name: foobar
|
304
|
+
source: 'dah.com'
|
305
|
+
destination: 'bar.com'
|
306
|
+
concurrent_max: 5
|
307
|
+
calls_per_second: 2
|
308
|
+
number_of_calls: 10
|
309
|
+
errors_report_file: errors.txt
|
310
|
+
steps:
|
311
|
+
- invite
|
312
|
+
- wait_for_answer
|
313
|
+
- ack_answer
|
314
|
+
- sleep 3
|
315
|
+
- send_digits 'abc'
|
316
|
+
- sleep 5
|
317
|
+
- send_digits '#'
|
318
|
+
- wait_for_hangup
|
319
|
+
MANIFEST
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'should turn on -trace_err and set the -error_file option to the filename provided' do
|
323
|
+
expect_command_execution(/-trace_err -error_file errors.txt/)
|
324
|
+
subject.run
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context "specifying rate increase options" do
|
329
|
+
let(:manifest) do
|
330
|
+
<<-MANIFEST
|
331
|
+
name: foobar
|
332
|
+
source: 'dah.com'
|
333
|
+
destination: 'bar.com'
|
334
|
+
concurrent_max: 5
|
335
|
+
calls_per_second: 2
|
336
|
+
calls_per_second_max: 5
|
337
|
+
calls_per_second_incr: 2
|
338
|
+
number_of_calls: 10
|
339
|
+
errors_report_file: errors.txt
|
340
|
+
steps:
|
341
|
+
- invite
|
342
|
+
- wait_for_answer
|
343
|
+
- ack_answer
|
344
|
+
- sleep 3
|
345
|
+
- send_digits 'abc'
|
346
|
+
- sleep 5
|
347
|
+
- send_digits '#'
|
348
|
+
- wait_for_hangup
|
349
|
+
MANIFEST
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'should not terminate the test when reaching the rate limit and set the rate limit and increase appropriately' do
|
353
|
+
expect_command_execution(/-no_rate_quit -rate_max 5 -rate_increase 2/)
|
354
|
+
subject.run
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
272
358
|
context "specifying a variables file" do
|
273
359
|
let(:manifest) do
|
274
360
|
<<-MANIFEST
|
275
361
|
name: foobar
|
276
362
|
source: 'dah.com'
|
277
363
|
destination: 'bar.com'
|
278
|
-
|
364
|
+
concurrent_max: 5
|
279
365
|
calls_per_second: 2
|
280
366
|
number_of_calls: 10
|
281
367
|
scenario_variables: /path/to/vars.csv
|
@@ -305,7 +391,7 @@ steps:
|
|
305
391
|
name: foobar
|
306
392
|
source: 'dah.com'
|
307
393
|
destination: 'bar.com'
|
308
|
-
|
394
|
+
concurrent_max: 5
|
309
395
|
calls_per_second: 2
|
310
396
|
number_of_calls: 10
|
311
397
|
transport_mode: t1
|
@@ -339,7 +425,7 @@ steps:
|
|
339
425
|
|
340
426
|
it "doesn't raise anything if SIPp returns 0" do
|
341
427
|
quietly do
|
342
|
-
subject.run.should
|
428
|
+
subject.run.should be true
|
343
429
|
end
|
344
430
|
end
|
345
431
|
end
|
@@ -350,7 +436,7 @@ steps:
|
|
350
436
|
it "returns false if SIPp returns 1" do
|
351
437
|
quietly do
|
352
438
|
logger.should_receive(:info).ordered.with(/Test completed successfully but some calls failed./)
|
353
|
-
subject.run.should
|
439
|
+
subject.run.should be false
|
354
440
|
end
|
355
441
|
end
|
356
442
|
end
|
@@ -437,6 +523,8 @@ steps:
|
|
437
523
|
end
|
438
524
|
|
439
525
|
it "does not leak threads" do
|
526
|
+
Thread.list.each { |t| t.kill unless t = Thread.main }
|
527
|
+
sleep 0.1
|
440
528
|
original_thread_count = active_thread_count
|
441
529
|
quietly do
|
442
530
|
subject.run
|
@@ -459,6 +547,8 @@ steps:
|
|
459
547
|
|
460
548
|
it "does not leak threads" do
|
461
549
|
quietly do
|
550
|
+
Thread.list.each { |t| t.kill unless t = Thread.main }
|
551
|
+
sleep 0.1
|
462
552
|
original_thread_count = active_thread_count
|
463
553
|
subject.run
|
464
554
|
sleep 0.1
|
@@ -14,11 +14,6 @@ describe SippyCup::Scenario do
|
|
14
14
|
|
15
15
|
subject(:scenario) { described_class.new 'Test', default_args.merge(args) }
|
16
16
|
|
17
|
-
it "creates a media stream on initialization" do
|
18
|
-
SippyCup::Media.should_receive(:new).once
|
19
|
-
subject
|
20
|
-
end
|
21
|
-
|
22
17
|
it "takes a block to generate a scenario" do
|
23
18
|
s = described_class.new 'Test', default_args do
|
24
19
|
invite
|
@@ -102,7 +97,7 @@ describe SippyCup::Scenario do
|
|
102
97
|
it "sends a REGISTER message" do
|
103
98
|
subject.register 'frank'
|
104
99
|
|
105
|
-
subject.to_xml.should match(%r{<send
|
100
|
+
subject.to_xml.should match(%r{<send.*>})
|
106
101
|
subject.to_xml.should match(%r{REGISTER})
|
107
102
|
end
|
108
103
|
|
@@ -143,6 +138,7 @@ describe SippyCup::Scenario do
|
|
143
138
|
|
144
139
|
context "when a password is provided" do
|
145
140
|
it "expects a 401 response" do
|
141
|
+
pending "Need to check for initial request, then 401, then retry with authentication"
|
146
142
|
subject.register 'frank', 'abc123'
|
147
143
|
subject.to_xml.should match(%r{<recv response="401" auth="true" optional="false"/>})
|
148
144
|
end
|
@@ -218,19 +214,19 @@ describe SippyCup::Scenario do
|
|
218
214
|
it "expects a 200 with rrs and rtd true" do
|
219
215
|
subject.receive_answer
|
220
216
|
|
221
|
-
scenario.to_xml.should match(%q{<recv response="200" rrs="true" rtd="true"
|
217
|
+
scenario.to_xml.should match(%q{<recv response="200" rrs="true" rtd="true">})
|
222
218
|
end
|
223
219
|
|
224
220
|
it "allows passing options to the recv expectation" do
|
225
221
|
subject.receive_answer foo: 'bar'
|
226
222
|
|
227
|
-
scenario.to_xml.should match(%q{<recv response="200" rrs="true" rtd="true" foo="bar"
|
223
|
+
scenario.to_xml.should match(%q{<recv response="200" rrs="true" rtd="true" foo="bar">})
|
228
224
|
end
|
229
225
|
|
230
226
|
it "allows overriding options" do
|
231
227
|
subject.receive_answer rtd: false
|
232
228
|
|
233
|
-
scenario.to_xml.should match(%q{<recv response="200" rrs="true" rtd="false"
|
229
|
+
scenario.to_xml.should match(%q{<recv response="200" rrs="true" rtd="false">})
|
234
230
|
end
|
235
231
|
end
|
236
232
|
|
@@ -268,10 +264,14 @@ describe SippyCup::Scenario do
|
|
268
264
|
end
|
269
265
|
|
270
266
|
context "when media is present" do
|
271
|
-
before
|
267
|
+
before do
|
268
|
+
subject.answer
|
269
|
+
subject.sleep 1
|
270
|
+
end
|
272
271
|
|
273
272
|
it "starts the PCAP media" do
|
274
273
|
subject.ack_answer
|
274
|
+
subject.sleep 1
|
275
275
|
subject.to_xml(:pcap_path => "/dev/null").should match(%r{<nop>\n.*<action>\n.*<exec play_pcap_audio="/dev/null"/>\n.*</action>\n.*</nop>})
|
276
276
|
end
|
277
277
|
end
|
@@ -282,24 +282,6 @@ describe SippyCup::Scenario do
|
|
282
282
|
subject.to_xml(:pcap_path => "/dev/null").should_not match(%r{<nop>\n.*<action>\n.*<exec play_pcap_audio="/dev/null"/>\n.*</action>\n.*</nop>})
|
283
283
|
end
|
284
284
|
end
|
285
|
-
|
286
|
-
context "when a from user is specified" do
|
287
|
-
let(:args) { {from_user: 'frank'} }
|
288
|
-
|
289
|
-
it "includes the specified user in the From and Contact headers" do
|
290
|
-
subject.ack_answer
|
291
|
-
subject.to_xml.should match(%r{From: "frank" <sip:frank@})
|
292
|
-
subject.to_xml.should match(%r{Contact: <sip:frank@})
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
context "when no from user is specified" do
|
297
|
-
it "uses a default of 'sipp' in the From and Contact headers" do
|
298
|
-
subject.ack_answer
|
299
|
-
subject.to_xml.should match(%r{From: "sipp" <sip:sipp@})
|
300
|
-
subject.to_xml.should match(%r{Contact: <sip:sipp@})
|
301
|
-
end
|
302
|
-
end
|
303
285
|
end
|
304
286
|
|
305
287
|
describe '#wait_for_answer' do
|
@@ -312,6 +294,8 @@ describe SippyCup::Scenario do
|
|
312
294
|
xml.should =~ /recv response="183".*optional="true"/
|
313
295
|
xml.should =~ /recv response="200"/
|
314
296
|
xml.should_not =~ /recv response="200".*optional="true"/
|
297
|
+
xml.should match(%r{<send>})
|
298
|
+
xml.should match(%r{ACK})
|
315
299
|
end
|
316
300
|
|
317
301
|
it "passes through additional options" do
|
@@ -322,6 +306,8 @@ describe SippyCup::Scenario do
|
|
322
306
|
xml.should =~ /recv .*foo="bar".*response="180"/
|
323
307
|
xml.should =~ /recv .*foo="bar".*response="183"/
|
324
308
|
xml.should =~ /recv .*response="200" .*foo="bar"/
|
309
|
+
xml.should match(%r{<send.*foo="bar".*>})
|
310
|
+
xml.should match(%r{ACK})
|
325
311
|
end
|
326
312
|
end
|
327
313
|
|
@@ -361,24 +347,6 @@ describe SippyCup::Scenario do
|
|
361
347
|
subject.send_bye foo: 'bar'
|
362
348
|
subject.to_xml.should match(%r{<send foo="bar".*>})
|
363
349
|
end
|
364
|
-
|
365
|
-
context "when a from user is specified" do
|
366
|
-
let(:args) { {from_user: 'frank'} }
|
367
|
-
|
368
|
-
it "includes the specified user in the From and Contact headers" do
|
369
|
-
subject.send_bye
|
370
|
-
subject.to_xml.should match(%r{From: "frank" <sip:frank@})
|
371
|
-
subject.to_xml.should match(%r{Contact: <sip:frank@})
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
context "when no from user is specified" do
|
376
|
-
it "uses a default of 'sipp' in the From and Contact headers" do
|
377
|
-
subject.send_bye
|
378
|
-
subject.to_xml.should match(%r{From: "sipp" <sip:sipp@})
|
379
|
-
subject.to_xml.should match(%r{Contact: <sip:sipp@})
|
380
|
-
end
|
381
|
-
end
|
382
350
|
end
|
383
351
|
|
384
352
|
describe '#receive_bye' do
|
@@ -407,22 +375,6 @@ describe SippyCup::Scenario do
|
|
407
375
|
subject.okay foo: 'bar'
|
408
376
|
subject.to_xml.should match(%r{<send foo="bar".*>})
|
409
377
|
end
|
410
|
-
|
411
|
-
context "when a from user is specified" do
|
412
|
-
let(:args) { {from_user: 'frank'} }
|
413
|
-
|
414
|
-
it "includes the specified user in the Contact header" do
|
415
|
-
subject.okay
|
416
|
-
subject.to_xml.should match(%r{Contact: <sip:frank@})
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
context "when no from user is specified" do
|
421
|
-
it "uses a default of 'sipp' in the Contact header" do
|
422
|
-
subject.okay
|
423
|
-
subject.to_xml.should match(%r{Contact: <sip:sipp@})
|
424
|
-
end
|
425
|
-
end
|
426
378
|
end
|
427
379
|
|
428
380
|
describe '#wait_for_hangup' do
|
@@ -434,10 +386,25 @@ describe SippyCup::Scenario do
|
|
434
386
|
end
|
435
387
|
end
|
436
388
|
|
389
|
+
describe '#call_length_repartition' do
|
390
|
+
it 'create a partition table' do
|
391
|
+
subject.call_length_repartition('1', '10', '2')
|
392
|
+
scenario.to_xml.should match('<CallLengthRepartition value="1,3,5,7,9"/>')
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
describe '#response_time_repartition' do
|
397
|
+
it 'create a partition table' do
|
398
|
+
subject.response_time_repartition('1', '10', '2')
|
399
|
+
scenario.to_xml.should match('<ResponseTimeRepartition value="1,3,5,7,9"/>')
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
437
403
|
describe 'media-dependent operations' do
|
438
404
|
let(:media) { double :media }
|
439
405
|
before do
|
440
406
|
SippyCup::Media.should_receive(:new).once.and_return media
|
407
|
+
scenario.ack_answer
|
441
408
|
media.stub :<<
|
442
409
|
end
|
443
410
|
|
@@ -485,6 +452,7 @@ describe SippyCup::Scenario do
|
|
485
452
|
|
486
453
|
describe "#send_digits with a SIP INFO DTMF mode" do
|
487
454
|
let(:args) { {dtmf_mode: 'info'} }
|
455
|
+
before { scenario.answer }
|
488
456
|
|
489
457
|
it "creates the requested DTMF string as SIP INFO messages" do
|
490
458
|
scenario.send_digits '136'
|
@@ -516,6 +484,7 @@ describe SippyCup::Scenario do
|
|
516
484
|
end
|
517
485
|
|
518
486
|
it "writes the PCAP media to disk at name.pcap" do
|
487
|
+
scenario.ack_answer
|
519
488
|
scenario.send_digits '123'
|
520
489
|
|
521
490
|
scenario.compile!
|
@@ -540,6 +509,7 @@ describe SippyCup::Scenario do
|
|
540
509
|
end
|
541
510
|
|
542
511
|
it "writes the PCAP media to disk at filename.pcap" do
|
512
|
+
scenario.ack_answer
|
543
513
|
scenario.send_digits '123'
|
544
514
|
|
545
515
|
scenario.compile!
|
@@ -575,7 +545,10 @@ describe SippyCup::Scenario do
|
|
575
545
|
end
|
576
546
|
|
577
547
|
context "with media" do
|
578
|
-
before
|
548
|
+
before do
|
549
|
+
scenario.ack_answer
|
550
|
+
scenario.sleep 1
|
551
|
+
end
|
579
552
|
|
580
553
|
it "writes the PCAP media to a Tempfile and returns it" do
|
581
554
|
files = scenario.to_tmpfiles
|
@@ -589,7 +562,6 @@ describe SippyCup::Scenario do
|
|
589
562
|
end
|
590
563
|
|
591
564
|
it "puts the PCAP file path into the scenario XML" do
|
592
|
-
scenario.ack_answer
|
593
565
|
files = scenario.to_tmpfiles
|
594
566
|
files[:scenario].read.should match(%r{play_pcap_audio="#{files[:media].path}"})
|
595
567
|
end
|
@@ -604,7 +576,7 @@ describe SippyCup::Scenario do
|
|
604
576
|
<![CDATA[
|
605
577
|
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
606
578
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
607
|
-
From: "sipp" <sip:sipp@[local_ip]>;tag=[call_number]
|
579
|
+
From: "sipp" <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
|
608
580
|
To: <sip:[service]@[remote_ip]:[remote_port]>
|
609
581
|
Call-ID: [call_id]
|
610
582
|
CSeq: [cseq] INVITE
|
@@ -624,20 +596,24 @@ a=rtpmap:0 PCMU/8000
|
|
624
596
|
a=rtpmap:101 telephone-event/8000
|
625
597
|
a=fmtp:101 0-15
|
626
598
|
]]>
|
627
|
-
|
599
|
+
<action><assignstr assign_to="remote_addr" value="[service]@[remote_ip]:[remote_port]"/><assignstr assign_to="local_addr" value="sipp@[local_ip]:[local_port]"/><assignstr assign_to="call_addr" value="[service]@[remote_ip]:[remote_port]"/></action></send>
|
628
600
|
<recv response="100" optional="true"/>
|
629
601
|
<recv response="180" optional="true"/>
|
630
602
|
<recv response="183" optional="true"/>
|
631
|
-
<recv response="200" rrs="true" rtd="true"
|
603
|
+
<recv response="200" rrs="true" rtd="true">
|
604
|
+
<action>
|
605
|
+
<ereg regexp="<sip:(.*)>.*;tag=([^;]*)" search_in="hdr" header="To:" assign_to="dummy,remote_addr,remote_tag"/>
|
606
|
+
</action>
|
607
|
+
</recv>
|
632
608
|
<send>
|
633
609
|
<![CDATA[
|
634
610
|
ACK [next_url] SIP/2.0
|
635
611
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
636
|
-
From: "sipp" <sip:sipp@[local_ip]>;tag=[call_number]
|
612
|
+
From: "sipp" <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
|
637
613
|
To: <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
638
614
|
Call-ID: [call_id]
|
639
615
|
CSeq: [cseq] ACK
|
640
|
-
Contact: <sip:
|
616
|
+
Contact: <sip:[$local_addr];transport=[transport]>
|
641
617
|
Max-Forwards: 100
|
642
618
|
User-Agent: SIPp/sippy_cup
|
643
619
|
Content-Length: 0
|
@@ -653,19 +629,20 @@ SIP/2.0 200 OK
|
|
653
629
|
[last_To:]
|
654
630
|
[last_Call-ID:]
|
655
631
|
[last_CSeq:]
|
656
|
-
Contact: <sip:
|
632
|
+
Contact: <sip:[$local_addr];transport=[transport]>
|
657
633
|
Max-Forwards: 100
|
658
634
|
User-Agent: SIPp/sippy_cup
|
659
635
|
Content-Length: 0
|
660
636
|
[routes]
|
661
637
|
]]>
|
662
638
|
</send>
|
639
|
+
<Reference variables="remote_addr,local_addr,call_addr,dummy,remote_tag"/>
|
663
640
|
</scenario>
|
664
641
|
END
|
665
642
|
end
|
666
643
|
|
667
644
|
context "with a valid steps definition" do
|
668
|
-
let(:steps) { ['invite', 'wait_for_answer', '
|
645
|
+
let(:steps) { ['invite', 'wait_for_answer', 'wait_for_hangup'] }
|
669
646
|
|
670
647
|
it "runs each step" do
|
671
648
|
subject.build(steps)
|
@@ -673,6 +650,23 @@ Content-Length: 0
|
|
673
650
|
end
|
674
651
|
end
|
675
652
|
|
653
|
+
context "having steps with arguments" do
|
654
|
+
let(:steps) do
|
655
|
+
[
|
656
|
+
%q(register 'user@domain.com' "my password has spaces"),
|
657
|
+
%q(sleep 3),
|
658
|
+
%q(send_digits 12345)
|
659
|
+
]
|
660
|
+
end
|
661
|
+
|
662
|
+
it "each method should receive the correct arguments" do
|
663
|
+
subject.should_receive(:register).once.ordered.with('user@domain.com', 'my password has spaces')
|
664
|
+
subject.should_receive(:sleep).once.ordered.with('3')
|
665
|
+
subject.should_receive(:send_digits).once.ordered.with('12345')
|
666
|
+
subject.build steps
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
676
670
|
context "with an invalid steps definition" do
|
677
671
|
let(:steps) { ["send_digits 'b'"] }
|
678
672
|
|
@@ -696,7 +690,6 @@ from_user: #{specs_from}
|
|
696
690
|
steps:
|
697
691
|
- invite
|
698
692
|
- wait_for_answer
|
699
|
-
- ack_answer
|
700
693
|
- sleep 3
|
701
694
|
- send_digits '3125551234'
|
702
695
|
- sleep 5
|
@@ -712,7 +705,7 @@ steps:
|
|
712
705
|
<![CDATA[
|
713
706
|
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
714
707
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
715
|
-
From: "#{specs_from}" <sip:#{specs_from}@[local_ip]>;tag=[call_number]
|
708
|
+
From: "#{specs_from}" <sip:#{specs_from}@[local_ip]:[local_port]>;tag=[call_number]
|
716
709
|
To: <sip:[service]@[remote_ip]:[remote_port]>
|
717
710
|
Call-ID: [call_id]
|
718
711
|
CSeq: [cseq] INVITE
|
@@ -732,20 +725,24 @@ a=rtpmap:0 PCMU/8000
|
|
732
725
|
a=rtpmap:101 telephone-event/8000
|
733
726
|
a=fmtp:101 0-15
|
734
727
|
]]>
|
735
|
-
|
728
|
+
<action><assignstr assign_to="remote_addr" value="[service]@[remote_ip]:[remote_port]"/><assignstr assign_to="local_addr" value="#{specs_from}@[local_ip]:[local_port]"/><assignstr assign_to="call_addr" value="[service]@[remote_ip]:[remote_port]"/></action></send>
|
736
729
|
<recv response="100" optional="true"/>
|
737
730
|
<recv response="180" optional="true"/>
|
738
731
|
<recv response="183" optional="true"/>
|
739
|
-
<recv response="200" rrs="true" rtd="true"
|
732
|
+
<recv response="200" rrs="true" rtd="true">
|
733
|
+
<action>
|
734
|
+
<ereg regexp="<sip:(.*)>.*;tag=([^;]*)" search_in="hdr" header="To:" assign_to="dummy,remote_addr,remote_tag"/>
|
735
|
+
</action>
|
736
|
+
</recv>
|
740
737
|
<send>
|
741
738
|
<![CDATA[
|
742
739
|
ACK [next_url] SIP/2.0
|
743
740
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
744
|
-
From: "#{specs_from}" <sip:#{specs_from}@[local_ip]>;tag=[call_number]
|
741
|
+
From: "#{specs_from}" <sip:#{specs_from}@[local_ip]:[local_port]>;tag=[call_number]
|
745
742
|
To: <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
|
746
743
|
Call-ID: [call_id]
|
747
744
|
CSeq: [cseq] ACK
|
748
|
-
Contact: <sip
|
745
|
+
Contact: <sip:[$local_addr];transport=[transport]>
|
749
746
|
Max-Forwards: 100
|
750
747
|
User-Agent: SIPp/sippy_cup
|
751
748
|
Content-Length: 0
|
@@ -770,13 +767,14 @@ SIP/2.0 200 OK
|
|
770
767
|
[last_To:]
|
771
768
|
[last_Call-ID:]
|
772
769
|
[last_CSeq:]
|
773
|
-
Contact: <sip
|
770
|
+
Contact: <sip:[$local_addr];transport=[transport]>
|
774
771
|
Max-Forwards: 100
|
775
772
|
User-Agent: SIPp/sippy_cup
|
776
773
|
Content-Length: 0
|
777
774
|
[routes]
|
778
775
|
]]>
|
779
776
|
</send>
|
777
|
+
<Reference variables="remote_addr,local_addr,call_addr,dummy,remote_tag"/>
|
780
778
|
</scenario>
|
781
779
|
END
|
782
780
|
end
|
@@ -860,7 +858,6 @@ from_user: #{specs_from}
|
|
860
858
|
steps:
|
861
859
|
- invite
|
862
860
|
- wait_for_answer
|
863
|
-
- ack_answer
|
864
861
|
- sleep 3
|
865
862
|
- send_digits '3125551234'
|
866
863
|
- sleep 5
|
@@ -894,7 +891,6 @@ from_user: #{specs_from}
|
|
894
891
|
steps:
|
895
892
|
- invite
|
896
893
|
- wait_for_answer
|
897
|
-
- ack_answer
|
898
894
|
- sleep 3
|
899
895
|
- send_digits '3125551234'
|
900
896
|
- sleep 5
|
@@ -944,9 +940,8 @@ from_user: #{specs_from}
|
|
944
940
|
steps:
|
945
941
|
- invite
|
946
942
|
- wait_for_answer
|
947
|
-
- ack_answer
|
948
943
|
- sleep 3
|
949
|
-
- send_digits '
|
944
|
+
- send_digits 'xyz'
|
950
945
|
- sleep 5
|
951
946
|
- send_digits '#'
|
952
947
|
- wait_for_hangup
|
@@ -964,7 +959,7 @@ steps:
|
|
964
959
|
|
965
960
|
it "sets the error messages for the scenario" do
|
966
961
|
scenario = SippyCup::Scenario.from_manifest(scenario_yaml)
|
967
|
-
scenario.errors.should == [{step:
|
962
|
+
scenario.errors.should == [{step: 4, message: "send_digits 'xyz': Invalid DTMF digit requested: x"}]
|
968
963
|
end
|
969
964
|
end
|
970
965
|
end
|