sippy_cup 0.4.1 → 0.5.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.
- 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
|