[Asterisk-code-review] confbridge / pjsip: Add stream addition/removal SDP tests. (testsuite[certified/16.8])

Friendly Automation asteriskteam at digium.com
Wed Mar 4 08:20:57 CST 2020


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/testsuite/+/13871 )

Change subject: confbridge / pjsip: Add stream addition/removal SDP tests.
......................................................................

confbridge / pjsip: Add stream addition/removal SDP tests.

The 'sfu_nominal' test has two calls join an SFU
video conference bridge with video and confirms that
the appropriate reinvites are sent to each party
adding or removing video streams as appropriate.

The 'sfu_add_remove_sources' test extends this by
also adding and removing a video source from a
channel while it is already present in the conference
bridge.

The 'sfu_no_video_source' test has an audio only
participant join the bridge with an audio+video
participant. As video is enabled for the audio
only participant a video stream is added and
removed as the second participant joins and leaves.

The 'add_remove_sources' test has a channel
call another and once answered adds and removes
a video stream. The test confirms that the other
party is reinvited to also add and remove the stream.

ASTERISK-28733

Change-Id: I049169887d113678901a536bdf64dca2f6083b70
(cherry picked from commit 1621836fd44943b9464467035845ad2b69df7702)
---
A tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/extensions.conf
A tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/pjsip.conf
A tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_first.xml
A tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_second.xml
A tests/apps/confbridge/sfu_add_remove_sources/test-config.yaml
A tests/apps/confbridge/sfu_no_video_source/configs/ast1/extensions.conf
A tests/apps/confbridge/sfu_no_video_source/configs/ast1/pjsip.conf
A tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_first.xml
A tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_second.xml
A tests/apps/confbridge/sfu_no_video_source/test-config.yaml
A tests/apps/confbridge/sfu_nominal/configs/ast1/extensions.conf
A tests/apps/confbridge/sfu_nominal/configs/ast1/pjsip.conf
A tests/apps/confbridge/sfu_nominal/sipp/video_caller_first.xml
A tests/apps/confbridge/sfu_nominal/sipp/video_caller_second.xml
A tests/apps/confbridge/sfu_nominal/test-config.yaml
M tests/apps/confbridge/tests.yaml
A tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/extensions.conf
A tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/pjsip.conf
A tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/alice.xml
A tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/bob.xml
A tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/test-config.yaml
M tests/channels/pjsip/basic_calls/two_parties/nominal/tests.yaml
22 files changed, 1,651 insertions(+), 0 deletions(-)

Approvals:
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit



diff --git a/tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/extensions.conf b/tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/extensions.conf
new file mode 100644
index 0000000..5e48803
--- /dev/null
+++ b/tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/extensions.conf
@@ -0,0 +1,5 @@
+[default]
+exten => conference,1,Answer()
+same =>       n,Set(CONFBRIDGE(bridge,video_mode)=sfu)
+same  =>      n,ConfBridge(conference)
+same  =>      n,Hangup()
diff --git a/tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/pjsip.conf b/tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..86b6cf4
--- /dev/null
+++ b/tests/apps/confbridge/sfu_add_remove_sources/configs/ast1/pjsip.conf
@@ -0,0 +1,23 @@
+[system]
+type=system
+timer_t1=100
+timer_b=6400
+
+[local-transport-udp]
+type=transport
+bind=127.0.0.1
+protocol=udp
+
+[video-caller-first]
+type=endpoint
+context=default
+allow=!all,ulaw,h263,h264,h261
+media_address=127.0.0.1
+max_video_streams=10
+
+[video-caller-second]
+type=endpoint
+context=default
+allow=!all,ulaw,h263,h264,h261
+media_address=127.0.0.1
+max_video_streams=10
\ No newline at end of file
diff --git a/tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_first.xml b/tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_first.xml
new file mode 100644
index 0000000..857d79f
--- /dev/null
+++ b/tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_first.xml
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="INVITE to ConfBridge with SDP in initial INVITE">
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: 1 INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: 1 ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 6004 RTP/AVP 99
+      a=rtpmap:99 H264/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+   <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 31+..*"
+            search_in="body" check_it="true" assign_to="3"/>
+      <test assign_to="3" variable="3" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 6004 RTP/AVP 99
+      a=rtpmap:99 H264/90000
+      m=video 6006 RTP/AVP 31
+      a=rtpmap:31 H261/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+   <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="4"/>
+      <test assign_to="4" variable="4" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="5"/>
+      <test assign_to="5" variable="5" compare="equal" value=""/>
+      <ereg regexp="m=video 0 RTP/AVP 31+..*"
+            search_in="body" check_it="true" assign_to="6"/>
+      <test assign_to="6" variable="6" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 6004 RTP/AVP 99
+      a=rtpmap:99 H264/90000
+      m=video 0 RTP/AVP 31
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="7"/>
+      <test assign_to="7" variable="7" compare="equal" value=""/>
+      <ereg regexp="m=video 0 RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="8"/>
+      <test assign_to="8" variable="8" compare="equal" value=""/>
+      <ereg regexp="m=video 0 RTP/AVP 31+..*"
+            search_in="body" check_it="true" assign_to="9"/>
+      <test assign_to="9" variable="9" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687640 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 0 RTP/AVP 99
+      m=video 0 RTP/AVP 31
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200">
+  </recv>
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_second.xml b/tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_second.xml
new file mode 100644
index 0000000..39fba98
--- /dev/null
+++ b/tests/apps/confbridge/sfu_add_remove_sources/sipp/video_caller_second.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="INVITE to ConfBridge with SDP in initial INVITE">
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: 1 INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: 1 ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 96+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+      m=video 6004 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+      m=video 6004 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 6006 RTP/AVP 31
+      a=rtpmap:31 H261/90000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687640 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+      m=video 6004 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 0 RTP/AVP 31
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200">
+  </recv>
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/apps/confbridge/sfu_add_remove_sources/test-config.yaml b/tests/apps/confbridge/sfu_add_remove_sources/test-config.yaml
new file mode 100644
index 0000000..350d108
--- /dev/null
+++ b/tests/apps/confbridge/sfu_add_remove_sources/test-config.yaml
@@ -0,0 +1,35 @@
+testinfo:
+    summary:     'Ensure that ConfBridge and PJSIP in SFU reinvite appropriately when channels add/remove sources'
+    description: |
+        'Two SIPp scenarios call into Asterisk which drops them both into a ConfBridge conference bridge. The
+        bridge is configured with SFU video support and the calls include video streams. Upon entering each side
+        is reinvited with an additional video stream of the other participant. Once this is done the second
+        participant adds an additional video source. A reinvite is then sent to the first participant adding an
+        additional video stream for this new source. The second participant then removes the new video source
+        and a reinvite is sent to the first participant removing the just added video stream. The second
+        participant leaves and another reinvite is sent to the first participant removing the video stream for
+        the other participant that just left. The first participant then hangs up and the test ends.'
+
+test-modules:
+    test-object:
+        config-section: test-object-config
+        typename: 'sipp.SIPpTestCase'
+
+test-object-config:
+    memcheck-delay-stop: 7
+    fail-on-any: False
+    test-iterations:
+        -
+            scenarios:
+                # IPv4 & UDP
+                - { 'key-args': {'scenario': 'video_caller_first.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'video-caller-first'} }
+                - { 'key-args': {'scenario': 'video_caller_second.xml', '-i': '127.0.0.1', '-p': '5062', '-d': '5000', '-s': 'video-caller-second'} }
+
+properties:
+    dependencies:
+        - sipp :
+            version : 'v3.0'
+        - asterisk : 'app_confbridge'
+        - asterisk : 'res_pjsip'
+    tags:
+        - pjsip
diff --git a/tests/apps/confbridge/sfu_no_video_source/configs/ast1/extensions.conf b/tests/apps/confbridge/sfu_no_video_source/configs/ast1/extensions.conf
new file mode 100644
index 0000000..5e48803
--- /dev/null
+++ b/tests/apps/confbridge/sfu_no_video_source/configs/ast1/extensions.conf
@@ -0,0 +1,5 @@
+[default]
+exten => conference,1,Answer()
+same =>       n,Set(CONFBRIDGE(bridge,video_mode)=sfu)
+same  =>      n,ConfBridge(conference)
+same  =>      n,Hangup()
diff --git a/tests/apps/confbridge/sfu_no_video_source/configs/ast1/pjsip.conf b/tests/apps/confbridge/sfu_no_video_source/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..7d85e7f
--- /dev/null
+++ b/tests/apps/confbridge/sfu_no_video_source/configs/ast1/pjsip.conf
@@ -0,0 +1,16 @@
+[system]
+type=system
+timer_t1=100
+timer_b=6400
+
+[local-transport-udp]
+type=transport
+bind=127.0.0.1
+protocol=udp
+
+[video-caller]
+type=endpoint
+context=default
+allow=!all,ulaw,h263,h264
+media_address=127.0.0.1
+max_video_streams=10
diff --git a/tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_first.xml b/tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_first.xml
new file mode 100644
index 0000000..752133f
--- /dev/null
+++ b/tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_first.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="INVITE to ConfBridge with SDP in initial INVITE">
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: 1 INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: 1 ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 99
+      a=rtpmap:99 H264/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video 0 RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 0 RTP/AVP 99
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200">
+  </recv>
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_second.xml b/tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_second.xml
new file mode 100644
index 0000000..a15d56b
--- /dev/null
+++ b/tests/apps/confbridge/sfu_no_video_source/sipp/video_caller_second.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="INVITE to ConfBridge with SDP in initial INVITE">
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: 1 INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: 1 ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <pause milliseconds="5000"/>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200">
+  </recv>
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/apps/confbridge/sfu_no_video_source/test-config.yaml b/tests/apps/confbridge/sfu_no_video_source/test-config.yaml
new file mode 100644
index 0000000..2b1bc01
--- /dev/null
+++ b/tests/apps/confbridge/sfu_no_video_source/test-config.yaml
@@ -0,0 +1,33 @@
+testinfo:
+    summary:     'Ensure that ConfBridge and PJSIP in SFU reinvite with video even if participant only provides audio'
+    description: |
+        'Two SIPp scenarios call into Asterisk which drops them both into a ConfBridge conference bridge. The
+        bridge is configured with SFU video support. The first participant has only audio while the second
+        participant has both audio and video. On join the first participant is reinvited to add video of the
+        second participant while the second participant is not reinvited at all. The second participant then
+        hangs up causing the first participant to be reinvited and the video stream removed. The first
+        participant then hangs up and the test ends.'
+
+test-modules:
+    test-object:
+        config-section: test-object-config
+        typename: 'sipp.SIPpTestCase'
+
+test-object-config:
+    memcheck-delay-stop: 7
+    fail-on-any: False
+    test-iterations:
+        -
+            scenarios:
+                # IPv4 & UDP
+                - { 'key-args': {'scenario': 'video_caller_first.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'video-caller'} }
+                - { 'key-args': {'scenario': 'video_caller_second.xml', '-i': '127.0.0.1', '-p': '5062', '-d': '5000', '-s': 'video-caller'} }
+
+properties:
+    dependencies:
+        - sipp :
+            version : 'v3.0'
+        - asterisk : 'app_confbridge'
+        - asterisk : 'res_pjsip'
+    tags:
+        - pjsip
diff --git a/tests/apps/confbridge/sfu_nominal/configs/ast1/extensions.conf b/tests/apps/confbridge/sfu_nominal/configs/ast1/extensions.conf
new file mode 100644
index 0000000..5e48803
--- /dev/null
+++ b/tests/apps/confbridge/sfu_nominal/configs/ast1/extensions.conf
@@ -0,0 +1,5 @@
+[default]
+exten => conference,1,Answer()
+same =>       n,Set(CONFBRIDGE(bridge,video_mode)=sfu)
+same  =>      n,ConfBridge(conference)
+same  =>      n,Hangup()
diff --git a/tests/apps/confbridge/sfu_nominal/configs/ast1/pjsip.conf b/tests/apps/confbridge/sfu_nominal/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..7d85e7f
--- /dev/null
+++ b/tests/apps/confbridge/sfu_nominal/configs/ast1/pjsip.conf
@@ -0,0 +1,16 @@
+[system]
+type=system
+timer_t1=100
+timer_b=6400
+
+[local-transport-udp]
+type=transport
+bind=127.0.0.1
+protocol=udp
+
+[video-caller]
+type=endpoint
+context=default
+allow=!all,ulaw,h263,h264
+media_address=127.0.0.1
+max_video_streams=10
diff --git a/tests/apps/confbridge/sfu_nominal/sipp/video_caller_first.xml b/tests/apps/confbridge/sfu_nominal/sipp/video_caller_first.xml
new file mode 100644
index 0000000..47a9141
--- /dev/null
+++ b/tests/apps/confbridge/sfu_nominal/sipp/video_caller_first.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="INVITE to ConfBridge with SDP in initial INVITE">
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: 1 INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: 1 ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 6004 RTP/AVP 99
+      a=rtpmap:99 H264/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="3"/>
+      <test assign_to="3" variable="3" compare="equal" value=""/>
+      <ereg regexp="m=video 0 RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="4"/>
+      <test assign_to="4" variable="4" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+      m=video 0 RTP/AVP 99
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200">
+  </recv>
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/apps/confbridge/sfu_nominal/sipp/video_caller_second.xml b/tests/apps/confbridge/sfu_nominal/sipp/video_caller_second.xml
new file mode 100644
index 0000000..a29e418
--- /dev/null
+++ b/tests/apps/confbridge/sfu_nominal/sipp/video_caller_second.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="INVITE to ConfBridge with SDP in initial INVITE">
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: 1 INVITE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      User-Agent: Test
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+
+    ]]>
+  </send>
+
+  <recv response="100"
+        optional="true">
+  </recv>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: 1 ACK
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv request="INVITE">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 96+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 34+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=phoneA 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio 6000 RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+      m=video 6004 RTP/AVP 34
+      a=rtpmap:34 H263/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+        rtd="true"
+        crlf="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:conference@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: test1 <sip:[service]@[local_ip]:[local_port]>;tag=[call_number]
+      To: test <sip:test@[remote_ip]:[remote_port]>[peer_tag_param]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: <sip:test@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Subject: Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200">
+  </recv>
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/apps/confbridge/sfu_nominal/test-config.yaml b/tests/apps/confbridge/sfu_nominal/test-config.yaml
new file mode 100644
index 0000000..2853fff
--- /dev/null
+++ b/tests/apps/confbridge/sfu_nominal/test-config.yaml
@@ -0,0 +1,32 @@
+testinfo:
+    summary:     'Ensure that ConfBridge and PJSIP in SFU reinvite appropriately when channels join/leave'
+    description: |
+        'Two SIPp scenarios call into Asterisk which drops them both into a ConfBridge conference bridge. The
+        bridge is configured with SFU video support and the calls include video streams. Upon entering each side
+        is reinvited with an additional video stream of the other participant. Once this is done the second
+        participant leaves and another reinvite is sent to the first participant removing the video stream for
+        the other participant that just left. The first participant then hangs up and the test ends.'
+
+test-modules:
+    test-object:
+        config-section: test-object-config
+        typename: 'sipp.SIPpTestCase'
+
+test-object-config:
+    memcheck-delay-stop: 7
+    fail-on-any: False
+    test-iterations:
+        -
+            scenarios:
+                # IPv4 & UDP
+                - { 'key-args': {'scenario': 'video_caller_first.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'video-caller'} }
+                - { 'key-args': {'scenario': 'video_caller_second.xml', '-i': '127.0.0.1', '-p': '5062', '-d': '5000', '-s': 'video-caller'} }
+
+properties:
+    dependencies:
+        - sipp :
+            version : 'v3.0'
+        - asterisk : 'app_confbridge'
+        - asterisk : 'res_pjsip'
+    tags:
+        - pjsip
diff --git a/tests/apps/confbridge/tests.yaml b/tests/apps/confbridge/tests.yaml
index 2edb35a..bf8ef1f 100644
--- a/tests/apps/confbridge/tests.yaml
+++ b/tests/apps/confbridge/tests.yaml
@@ -18,3 +18,6 @@
     - test: 'confbridge_waitmarked_single'
     - test: 'muted_conference_start_muted'
     - test: 'regcontext'
+    - test: 'sfu_nominal'
+    - test: 'sfu_add_remove_sources'
+    - test: 'sfu_no_video_source'
diff --git a/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/extensions.conf b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/extensions.conf
new file mode 100644
index 0000000..aa80d3c
--- /dev/null
+++ b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/extensions.conf
@@ -0,0 +1,8 @@
+[general]
+
+[globals]
+
+[calling]
+exten => bob,1,NoOp()
+	same => n,Dial(PJSIP/bob)
+	same => n,Hangup()
diff --git a/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/pjsip.conf b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..c82ab09
--- /dev/null
+++ b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/configs/ast1/pjsip.conf
@@ -0,0 +1,34 @@
+[system]
+type=system
+timer_t1=100
+timer_b=6400
+
+[global]
+type=global
+debug=yes
+
+[local-transport]
+type=transport
+bind=127.0.0.1
+protocol=udp
+
+[alice]
+type=endpoint
+allow=g722,ulaw,alaw,h264
+context=calling
+direct_media=no
+media_address=127.0.0.1
+aors=alice
+
+[bob]
+type=endpoint
+allow=g722,ulaw,alaw,h264
+context=calling
+direct_media=no
+media_address=127.0.0.1
+aors=bob
+
+[bob]
+type=aor
+max_contacts=1
+contact=sip:bob at 127.0.0.3:5060\;transport=udp
diff --git a/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/alice.xml b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/alice.xml
new file mode 100644
index 0000000..e491e01
--- /dev/null
+++ b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/alice.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+
+<scenario name="Send Call">
+
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
+      From: <sip:alice@[local_ip]:[local_port]>;tag=[pid]SIPpTag[call_number]
+      To: <sip:[service]@[remote_ip]:[remote_port]>
+      Call-ID: [call_id]
+      CSeq: [cseq] INVITE
+      Contact: <sip:alice@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio [custom_media_port] RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+
+    ]]>
+  </send>
+
+  <recv response="100" optional="true" />
+  <recv response="180" optional="true" />
+  <recv response="183" optional="true" />
+
+  <recv response="200" rtd="true">
+    <!-- Save the To tag. We'll need it when we send REFER -->
+    <action>
+      <ereg regexp="(;tag=.*)"
+          header="To:"
+          search_in="hdr"
+          check_it="true"
+          assign_to="remote_tag"/>
+    </action>
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      Call-ID: [call_id]
+      CSeq: [cseq] ACK
+      Contact: <sip:alice@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <pause milliseconds="1000" />
+
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      [last_Via:]2
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      CSeq: [cseq] INVITE
+      Contact: <sip:alice@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio [custom_media_port] RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 6002 RTP/AVP 96
+      a=rtpmap:96 H264/90000
+
+    ]]>
+  </send>
+
+  <recv response="100" optional="true" />
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      [last_Via:]2
+      [last_From:]
+      [last_To:]
+      Call-ID: [call_id]
+      CSeq: [cseq] ACK
+      Contact: <sip:alice@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <pause milliseconds="1000" />
+
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      [last_Via:]2
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      CSeq: [cseq] INVITE
+      Contact: <sip:alice@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio [custom_media_port] RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 0 RTP/AVP 96
+
+    ]]>
+  </send>
+
+  <recv response="100" optional="true" />
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      [last_Via:]2
+      [last_From:]
+      [last_To:]
+      Call-ID: [call_id]
+      CSeq: [cseq] ACK
+      Contact: <sip:alice@[local_ip]:[local_port];transport=[transport]>
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <pause milliseconds="1000" />
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
+      [last_Via:]4
+      From: <sip:alice@[local_ip]:[local_port]>;tag=[pid]SIPpTag[call_number]
+      To: <sip:[service]@[remote_ip]:[remote_port]>[$remote_tag]
+      Call-ID: [call_id]
+      CSeq: [cseq] BYE
+      Contact: sip:alice@[local_ip]:[local_port]
+      Max-Forwards: 70
+      Subject: Performance Test
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <recv response="200" crlf="true">
+  </recv>
+
+</scenario>
diff --git a/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/bob.xml b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/bob.xml
new file mode 100644
index 0000000..6d1882e
--- /dev/null
+++ b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/sipp/bob.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<scenario name="Basic UAS responder">
+
+  <recv request="INVITE" crlf="true" />
+
+  <send>
+    <![CDATA[
+
+      SIP/2.0 180 Ringing
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:bob@[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:bob@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio [custom_media_port] RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+    rtd="true"
+    crlf="true">
+  </recv>
+
+  <recv request="INVITE" crlf="true">
+    <action>
+      <ereg regexp="m=video [0-9]{1,5} RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="1"/>
+      <test assign_to="1" variable="1" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:bob@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=user1 53655765 2353687638 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio [custom_media_port] RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 5000 RTP/AVP 99
+      a=rtpmap:99 H264/90000
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+    rtd="true"
+    crlf="true">
+  </recv>
+
+  <recv request="INVITE" crlf="true">
+    <action>
+      <ereg regexp="m=video 0 RTP/AVP 99+..*"
+            search_in="body" check_it="true" assign_to="2"/>
+      <test assign_to="2" variable="2" compare="equal" value=""/>
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:bob@[local_ip]:[local_port];transport=[transport]>
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=user1 53655765 2353687639 IN IP[local_ip_type] [local_ip]
+      s=-
+      c=IN IP[media_ip_type] [media_ip]
+      t=0 0
+      m=audio [custom_media_port] RTP/AVP 0
+      a=rtpmap:0 PCMU/8000
+      m=video 0 RTP/AVP 99
+
+    ]]>
+  </send>
+
+  <recv request="ACK"
+    rtd="true"
+    crlf="true">
+  </recv>
+
+  <recv request="BYE" />
+
+  <send>
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
diff --git a/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/test-config.yaml b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/test-config.yaml
new file mode 100644
index 0000000..d194b12
--- /dev/null
+++ b/tests/channels/pjsip/basic_calls/two_parties/nominal/add_remove_sources/test-config.yaml
@@ -0,0 +1,40 @@
+testinfo:
+    summary:     'Test adding and removing video sources while in a two party call'
+    description: |
+        'A SIPp scenario calls into Asterisk and Asterisk then dials another. Once
+        answered the channels are placed into a bridge. The calling party adds and
+        then removes a video stream. The test confirms that the called party is
+        reinvited as appropriate to add and remove the stream. Once completed the
+        calling party hangs up the call.'
+
+properties:
+    dependencies:
+        - python : 'twisted'
+        - python : 'starpy'
+        - asterisk : 'app_dial'
+        - asterisk : 'res_pjsip'
+        - sipp :
+            version : 'v3.4.1'
+    tags:
+        - pjsip
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: test-case-config
+        typename: 'sipp.SIPpTestCase'
+
+test-case-config:
+    memcheck-delay-stop: 7
+    connect-ami: 'True'
+    fail-on-any: False
+    test-iterations:
+        # First iteration
+        -
+            scenarios:
+                # Bob receives call from Alice
+                - { 'key-args': {'scenario': 'bob.xml', '-p': '5060', '-i': '127.0.0.3', '-s': 'alice', '-timeout': '20s', '-mi': '127.0.0.3'},
+                    'ordered-args': ['-timeout_error', '-key', 'custom_media_port', '6004'] }
+                # Alice calls Bob
+                - { 'key-args': {'scenario': 'alice.xml', '-p': '5060', '-i': '127.0.0.2', '-s': 'bob', '-timeout': '20s', '-mi': '127.0.0.2'},
+                    'ordered-args': ['-timeout_error', '-key', 'custom_media_port', '6004'] }
diff --git a/tests/channels/pjsip/basic_calls/two_parties/nominal/tests.yaml b/tests/channels/pjsip/basic_calls/two_parties/nominal/tests.yaml
index 29b5255..6a6fd71 100644
--- a/tests/channels/pjsip/basic_calls/two_parties/nominal/tests.yaml
+++ b/tests/channels/pjsip/basic_calls/two_parties/nominal/tests.yaml
@@ -1,3 +1,4 @@
 tests:
     - dir: 'alice_initiated'
     - test: 'two_servers'
+    - test: 'add_remove_sources'

-- 
To view, visit https://gerrit.asterisk.org/c/testsuite/+/13871
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: testsuite
Gerrit-Branch: certified/16.8
Gerrit-Change-Id: I049169887d113678901a536bdf64dca2f6083b70
Gerrit-Change-Number: 13871
Gerrit-PatchSet: 1
Gerrit-Owner: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20200304/65aaba89/attachment-0001.html>


More information about the asterisk-code-review mailing list