sippy_cup 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.markdown +2 -2
- data/lib/sippy_cup/runner.rb +1 -1
- data/lib/sippy_cup/scenario.rb +16 -8
- data/lib/sippy_cup/version.rb +1 -1
- data/sippy_cup.gemspec +1 -1
- data/spec/sippy_cup/runner_spec.rb +21 -45
- data/spec/sippy_cup/scenario_spec.rb +28 -0
- data/spec/spec_helper.rb +38 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cec1cec887891ded08da44c8bf7e35d533923924
|
4
|
+
data.tar.gz: 3f79938ed6a455dd62b883f4db39ddd6273876a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63276337ff8887505d17e00dc3e26ff1ae4670b6f905d432bc911c082f7dc740c23acdcd8e7f17466fdf0746d2756e67fad1f4ebeae3cd37acf43e9884c92852
|
7
|
+
data.tar.gz: 3bce73eada59e55f0610a8667441712c3b3b3f93d36ec7311f38b4f63569440998972c94a21eafd5064c703a7dbf0b60413aef2a132dbdfde77d72d8c57b252b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# develop
|
2
2
|
|
3
|
+
# [0.7.0](https://github.com/mojolingo/sippy_cup/compare/v0.6.0...v0.7.0)
|
4
|
+
* Feature: Permit `To` domain to be different from the destination. This permits testing multi-tenant systems more easily.
|
5
|
+
|
3
6
|
# [0.6.0](https://github.com/mojolingo/sippy_cup/compare/v0.5.0...v0.6.0)
|
4
7
|
* Change: Call limits (`number_of_calls`, `concurrent_max` and `calls_per_second`) no longer have default values for simplicity of UAS scenarios. The value of `to_user` now defaults to the SIPp default of `s`.
|
5
8
|
* Feature: Support for setting rate scaling independently of reporting frequency via the new `calls_per_second_interval` option. See also https://github.com/SIPp/sipp/pull/107 and https://github.com/SIPp/sipp/pull/126.
|
data/README.markdown
CHANGED
@@ -201,8 +201,8 @@ Each parameter has an impact on the test, and may either be changed once the XML
|
|
201
201
|
<dt>from_user</dt>
|
202
202
|
<dd>SIP user from which traffic should appear. Default: sipp</dd>
|
203
203
|
|
204
|
-
<dt>
|
205
|
-
<dd>SIP user to send requests to. Defaults to SIPp's default: `s` (as in `s@127.0.0.1`)
|
204
|
+
<dt>to</dt>
|
205
|
+
<dd>SIP user / address to send requests to. Defaults to SIPp's default: `s@[destination]` (as in `s@127.0.0.1`). Can specify either a user (`foouser`) or a full address (`foouser@there.com`), the latter being useful for testing multi-tenant systems where the `To` domain is not the same as the hostname of the system.</dd>
|
206
206
|
|
207
207
|
<dt>transport</dt>
|
208
208
|
<dd>Specify the SIP transport. Valid options are `udp` (default) or `tcp`. Default: `udp`</dd>
|
data/lib/sippy_cup/runner.rb
CHANGED
@@ -105,7 +105,7 @@ module SippyCup
|
|
105
105
|
options[:l] = max_concurrent if max_concurrent
|
106
106
|
options[:m] = @scenario_options[:number_of_calls] if @scenario_options[:number_of_calls]
|
107
107
|
options[:r] = @scenario_options[:calls_per_second] if @scenario_options[:calls_per_second]
|
108
|
-
options[:s] = @scenario_options[:
|
108
|
+
options[:s] = @scenario_options[:to] if @scenario_options[:to]
|
109
109
|
|
110
110
|
options[:i] = @scenario_options[:source] if @scenario_options[:source]
|
111
111
|
options[:mp] = @scenario_options[:media_port] if @scenario_options[:media_port]
|
data/lib/sippy_cup/scenario.rb
CHANGED
@@ -83,7 +83,8 @@ module SippyCup
|
|
83
83
|
# @option options [String] :destination The target system at which to direct traffic.
|
84
84
|
# @option options [String] :advertise_address The IP address to advertise in SIP and SDP if different from the bind IP (defaults to the bind IP).
|
85
85
|
# @option options [String] :from_user The SIP user from which traffic should appear.
|
86
|
-
# @option options [String] :to_user The SIP user to send requests to.
|
86
|
+
# @option options [String] :to_user The SIP user to send requests to. Alias for `:to` and deprecated in favour of the same.
|
87
|
+
# @option options [String] :to The SIP user / address to send requests to.
|
87
88
|
# @option options [Integer] :media_port The RTCP (media) port to bind to locally.
|
88
89
|
# @option options [String, Numeric] :max_concurrent The maximum number of concurrent calls to execute.
|
89
90
|
# @option options [String, Numeric] :number_of_calls The maximum number of calls to execute in the test run.
|
@@ -155,10 +156,9 @@ module SippyCup
|
|
155
156
|
# FIXME: The DTMF mapping (101) is hard-coded. It would be better if we could
|
156
157
|
# get this from the DTMF payload generator
|
157
158
|
from_addr = "#{@from_user}@#{@adv_ip}:[local_port]"
|
158
|
-
to_addr = "[service]@[remote_ip]:[remote_port]"
|
159
159
|
msg = <<-MSG
|
160
160
|
|
161
|
-
INVITE sip
|
161
|
+
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
|
162
162
|
Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch]
|
163
163
|
From: "#{@from_user}" <sip:#{from_addr}>;tag=[call_number]
|
164
164
|
To: <sip:#{to_addr}>
|
@@ -325,7 +325,7 @@ Content-Type: application/sdp
|
|
325
325
|
Content-Length: [len]
|
326
326
|
|
327
327
|
v=0
|
328
|
-
o=user1 53655765 2353687637 IN IP[local_ip_type] #{@adv_ip}
|
328
|
+
o=user1 53655765 2353687637 IN IP[local_ip_type] #{@adv_ip}
|
329
329
|
s=-
|
330
330
|
c=IN IP[media_ip_type] [media_ip]
|
331
331
|
t=0 0
|
@@ -448,7 +448,7 @@ a=rtpmap:0 PCMU/8000
|
|
448
448
|
ACK [next_url] SIP/2.0
|
449
449
|
Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch]
|
450
450
|
From: "#{@from_user}" <sip:#{@from_user}@#{@adv_ip}:[local_port]>;tag=[call_number]
|
451
|
-
To: <sip
|
451
|
+
To: <sip:#{to_addr}>[peer_tag_param]
|
452
452
|
Call-ID: [call_id]
|
453
453
|
CSeq: [cseq] ACK
|
454
454
|
Contact: <sip:[$local_addr];transport=[transport]>
|
@@ -499,7 +499,7 @@ Content-Length: 0
|
|
499
499
|
INFO [next_url] SIP/2.0
|
500
500
|
Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch]
|
501
501
|
From: "#{@from_user}" <sip:#{@from_user}@#{@adv_ip}:[local_port]>;tag=[call_number]
|
502
|
-
To: <sip
|
502
|
+
To: <sip:#{to_addr}>[peer_tag_param]
|
503
503
|
Call-ID: [call_id]
|
504
504
|
CSeq: [cseq] INFO
|
505
505
|
Contact: <sip:[$local_addr];transport=[transport]>
|
@@ -736,6 +736,10 @@ Content-Length: 0
|
|
736
736
|
|
737
737
|
private
|
738
738
|
|
739
|
+
def to_addr
|
740
|
+
@to_addr ||= "[service]@#{@to_domain}:[remote_port]"
|
741
|
+
end
|
742
|
+
|
739
743
|
#TODO: SIPS support?
|
740
744
|
def parse_user(user)
|
741
745
|
user.slice! 0, 4 if user =~ /sip:/
|
@@ -774,9 +778,13 @@ Content-Length: 0
|
|
774
778
|
@dtmf_mode = :rfc2833
|
775
779
|
end
|
776
780
|
|
777
|
-
@from_addr, @from_port = args[:source].split ':' if args[:source]
|
778
|
-
@to_addr, @to_port = args[:destination].split ':' if args[:destination]
|
779
781
|
@from_user = args[:from_user] || "sipp"
|
782
|
+
|
783
|
+
args[:to] ||= args[:to_user] if args.has_key?(:to_user)
|
784
|
+
if args[:to]
|
785
|
+
@to_user, @to_domain = args[:to].to_s.split('@')
|
786
|
+
end
|
787
|
+
@to_domain ||= "[remote_ip]"
|
780
788
|
end
|
781
789
|
|
782
790
|
def compile_media
|
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'
|
@@ -86,7 +86,7 @@ steps:
|
|
86
86
|
name: foobar
|
87
87
|
source: 'dah.com'
|
88
88
|
destination: 'bar.com'
|
89
|
-
|
89
|
+
to: 1
|
90
90
|
concurrent_max: 5
|
91
91
|
calls_per_second: 2
|
92
92
|
number_of_calls: 10
|
@@ -166,7 +166,7 @@ steps:
|
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
169
|
-
context "specifying a
|
169
|
+
context "specifying a to in the Scenario" do
|
170
170
|
let(:manifest) do
|
171
171
|
<<-MANIFEST
|
172
172
|
name: foobar
|
@@ -176,7 +176,7 @@ concurrent_max: 5
|
|
176
176
|
calls_per_second: 2
|
177
177
|
number_of_calls: 10
|
178
178
|
from_user: pat
|
179
|
-
|
179
|
+
to: frank@there.com
|
180
180
|
steps:
|
181
181
|
- invite
|
182
182
|
- wait_for_answer
|
@@ -450,9 +450,7 @@ steps:
|
|
450
450
|
let(:exit_code) { 0 }
|
451
451
|
|
452
452
|
it "doesn't raise anything if SIPp returns 0" do
|
453
|
-
|
454
|
-
subject.run.should be true
|
455
|
-
end
|
453
|
+
subject.run.should be true
|
456
454
|
end
|
457
455
|
end
|
458
456
|
|
@@ -460,10 +458,8 @@ steps:
|
|
460
458
|
let(:exit_code) { 1 }
|
461
459
|
|
462
460
|
it "returns false if SIPp returns 1" do
|
463
|
-
|
464
|
-
|
465
|
-
subject.run.should be false
|
466
|
-
end
|
461
|
+
logger.should_receive(:info).ordered.with(/Test completed successfully but some calls failed./)
|
462
|
+
subject.run.should be false
|
467
463
|
end
|
468
464
|
end
|
469
465
|
|
@@ -471,9 +467,7 @@ steps:
|
|
471
467
|
let(:exit_code) { 97 }
|
472
468
|
|
473
469
|
it "raises a ExitOnInternalCommand error if SIPp returns 97" do
|
474
|
-
|
475
|
-
expect { subject.run }.to raise_error SippyCup::ExitOnInternalCommand, error_string
|
476
|
-
end
|
470
|
+
expect { subject.run }.to raise_error SippyCup::ExitOnInternalCommand, error_string
|
477
471
|
end
|
478
472
|
end
|
479
473
|
|
@@ -481,9 +475,7 @@ steps:
|
|
481
475
|
let(:exit_code) { 99 }
|
482
476
|
|
483
477
|
it "raises a NoCallsProcessed error if SIPp returns 99" do
|
484
|
-
|
485
|
-
expect { subject.run }.to raise_error SippyCup::NoCallsProcessed, error_string
|
486
|
-
end
|
478
|
+
expect { subject.run }.to raise_error SippyCup::NoCallsProcessed, error_string
|
487
479
|
end
|
488
480
|
end
|
489
481
|
|
@@ -491,9 +483,7 @@ steps:
|
|
491
483
|
let(:exit_code) { 255 }
|
492
484
|
|
493
485
|
it "raises a FatalError error if SIPp returns 255" do
|
494
|
-
|
495
|
-
expect { subject.run }.to raise_error SippyCup::FatalError, error_string
|
496
|
-
end
|
486
|
+
expect { subject.run }.to raise_error SippyCup::FatalError, error_string
|
497
487
|
end
|
498
488
|
end
|
499
489
|
|
@@ -501,9 +491,7 @@ steps:
|
|
501
491
|
let(:exit_code) { 254 }
|
502
492
|
|
503
493
|
it "raises a FatalSocketBindingError error if SIPp returns 254" do
|
504
|
-
|
505
|
-
expect { subject.run }.to raise_error SippyCup::FatalSocketBindingError, error_string
|
506
|
-
end
|
494
|
+
expect { subject.run }.to raise_error SippyCup::FatalSocketBindingError, error_string
|
507
495
|
end
|
508
496
|
end
|
509
497
|
|
@@ -511,15 +499,11 @@ steps:
|
|
511
499
|
let(:exit_code) { 128 }
|
512
500
|
|
513
501
|
it "raises a SippGenericError error if SIPp returns 255" do
|
514
|
-
|
515
|
-
expect { subject.run }.to raise_error SippyCup::SippGenericError, error_string
|
516
|
-
end
|
502
|
+
expect { subject.run }.to raise_error SippyCup::SippGenericError, error_string
|
517
503
|
end
|
518
504
|
|
519
505
|
it "raises a SippGenericError error with the appropriate message" do
|
520
|
-
|
521
|
-
expect { subject.run }.to raise_error SippyCup::SippGenericError, error_string
|
522
|
-
end
|
506
|
+
expect { subject.run }.to raise_error SippyCup::SippGenericError, error_string
|
523
507
|
end
|
524
508
|
end
|
525
509
|
end
|
@@ -537,24 +521,18 @@ steps:
|
|
537
521
|
|
538
522
|
context "by default" do
|
539
523
|
it "proxies stdout to the terminal" do
|
540
|
-
|
541
|
-
capture(:stdout) { subject.run }.strip.should == output_string
|
542
|
-
end
|
524
|
+
capture(:stdout) { subject.run }.strip.should == output_string
|
543
525
|
end
|
544
526
|
|
545
527
|
it "proxies stderr to the terminal" do
|
546
|
-
|
547
|
-
capture(:stderr) { subject.run }.strip.should == error_string
|
548
|
-
end
|
528
|
+
capture(:stderr) { subject.run }.strip.should == error_string
|
549
529
|
end
|
550
530
|
|
551
531
|
it "does not leak threads" do
|
552
532
|
Thread.list.each { |t| t.kill unless t = Thread.main }
|
553
533
|
sleep 0.1
|
554
534
|
original_thread_count = active_thread_count
|
555
|
-
|
556
|
-
subject.run
|
557
|
-
end
|
535
|
+
subject.run
|
558
536
|
sleep 0.1
|
559
537
|
active_thread_count.should == original_thread_count
|
560
538
|
end
|
@@ -572,14 +550,12 @@ steps:
|
|
572
550
|
end
|
573
551
|
|
574
552
|
it "does not leak threads" do
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
active_thread_count.should == original_thread_count
|
582
|
-
end
|
553
|
+
Thread.list.each { |t| t.kill unless t = Thread.main }
|
554
|
+
sleep 0.1
|
555
|
+
original_thread_count = active_thread_count
|
556
|
+
subject.run
|
557
|
+
sleep 0.1
|
558
|
+
active_thread_count.should == original_thread_count
|
583
559
|
end
|
584
560
|
end
|
585
561
|
end
|
@@ -91,6 +91,34 @@ describe SippyCup::Scenario do
|
|
91
91
|
subject.to_xml.should match(%r{Contact: <sip:sipp@})
|
92
92
|
end
|
93
93
|
end
|
94
|
+
|
95
|
+
context "when a to user is specified" do
|
96
|
+
let(:args) { {to: 'usera'} }
|
97
|
+
|
98
|
+
it "includes the specified user in the To header and URI line" do
|
99
|
+
subject.invite
|
100
|
+
subject.to_xml.should match(%r{To: <sip:\[service\]@\[remote_ip\]})
|
101
|
+
subject.to_xml.should match(%r{INVITE sip:\[service\]@\[remote_ip\]})
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when a to address is specified" do
|
106
|
+
let(:args) { {to: 'usera@foo.bar'} }
|
107
|
+
|
108
|
+
it "includes the specified address in the To header, but not the URI line" do
|
109
|
+
subject.invite
|
110
|
+
subject.to_xml.should match(%r{To: <sip:\[service\]@foo.bar})
|
111
|
+
subject.to_xml.should match(%r{INVITE sip:\[service\]@\[remote_ip\]})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when no to is specified" do
|
116
|
+
it "uses a default of '[remote_ip]' in the To header and URI line" do
|
117
|
+
subject.invite
|
118
|
+
subject.to_xml.should match(%r{To: <sip:\[service\]@\[remote_ip\]})
|
119
|
+
subject.to_xml.should match(%r{INVITE sip:\[service\]@\[remote_ip\]})
|
120
|
+
end
|
121
|
+
end
|
94
122
|
end
|
95
123
|
|
96
124
|
describe "#register" do
|
data/spec/spec_helper.rb
CHANGED
@@ -3,15 +3,52 @@
|
|
3
3
|
%w{
|
4
4
|
sippy_cup
|
5
5
|
fakefs/spec_helpers
|
6
|
+
tempfile
|
6
7
|
}.each { |f| require f }
|
7
8
|
|
9
|
+
module SippyCup
|
10
|
+
module SpecHelpers
|
11
|
+
def capture(stream)
|
12
|
+
stream = stream.to_s
|
13
|
+
captured_stream = Tempfile.new(stream)
|
14
|
+
stream_io = eval("$#{stream}")
|
15
|
+
origin_stream = stream_io.dup
|
16
|
+
stream_io.reopen(captured_stream)
|
17
|
+
|
18
|
+
yield
|
19
|
+
|
20
|
+
stream_io.rewind
|
21
|
+
return captured_stream.read
|
22
|
+
ensure
|
23
|
+
captured_stream.close
|
24
|
+
captured_stream.unlink
|
25
|
+
stream_io.reopen(origin_stream)
|
26
|
+
end
|
27
|
+
|
28
|
+
def silence_stream(stream)
|
29
|
+
old_stream = stream.dup
|
30
|
+
stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
|
31
|
+
stream.sync = true
|
32
|
+
yield
|
33
|
+
ensure
|
34
|
+
stream.reopen(old_stream)
|
35
|
+
old_stream.close
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
8
40
|
RSpec.configure do |config|
|
41
|
+
config.include SippyCup::SpecHelpers
|
9
42
|
config.mock_framework = :rspec
|
10
43
|
config.filter_run :focus => true
|
11
44
|
config.run_all_when_everything_filtered = true
|
12
45
|
config.color = true
|
13
46
|
|
14
47
|
config.around(:each) do |example|
|
15
|
-
|
48
|
+
silence_stream(STDOUT) do
|
49
|
+
silence_stream(STDERR) do
|
50
|
+
example.run
|
51
|
+
end
|
52
|
+
end
|
16
53
|
end
|
17
54
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sippy_cup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Klang
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-07-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: packetfu
|
@@ -43,14 +43,14 @@ dependencies:
|
|
43
43
|
name: activesupport
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '3.0'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- - "
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '3.0'
|
56
56
|
- !ruby/object:Gem::Dependency
|