sippy_cup 0.6.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec38982988f13808a01d0edb5d995d05235d5000
4
- data.tar.gz: 18b80cca252826d0790c2152b0e72b507610a804
3
+ metadata.gz: cec1cec887891ded08da44c8bf7e35d533923924
4
+ data.tar.gz: 3f79938ed6a455dd62b883f4db39ddd6273876a2
5
5
  SHA512:
6
- metadata.gz: ed52b5856e8df516dbeaf1da79ca86ece5f83f76b8e414cce292bc09b3c77fca976150b1980486460562f3166125f38f0bee8a23eaf694cde97a0959dd48c702
7
- data.tar.gz: be9366e3fe1c86649c361c79bd265a0608ad8195843bce5d9dbc1797fff60f69419b3dfcea2aaab02cdfcdf52f1124ddab63cf5584925cb3a0c1484c5531e1ac
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>to_user</dt>
205
- <dd>SIP user to send requests to. Defaults to SIPp's default: `s` (as in `s@127.0.0.1`)</dd>
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>
@@ -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[:to_user] if @scenario_options[:to_user]
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]
@@ -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:#{to_addr} SIP/2.0
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:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
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:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
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
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module SippyCup
4
- VERSION = '0.6.0'
4
+ VERSION = '0.7.0'
5
5
  end
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', ["~> 3.0"]
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
- to_user: 1
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 to_user in the Scenario" do
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
- to_user: frank
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
- quietly do
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
- quietly do
464
- logger.should_receive(:info).ordered.with(/Test completed successfully but some calls failed./)
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
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
- quietly do
576
- Thread.list.each { |t| t.kill unless t = Thread.main }
577
- sleep 0.1
578
- original_thread_count = active_thread_count
579
- subject.run
580
- sleep 0.1
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
- quietly { example.run }
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.6.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-03-17 00:00:00.000000000 Z
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