[asterisk-commits] chan pjsip: Creating Channel Causes Asterisk to Crash When D... (testsuite[master])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat May 2 10:18:18 CDT 2015


Matt Jordan has submitted this change and it was merged.

Change subject: chan_pjsip: Creating Channel Causes Asterisk to Crash When Duplicate AOR             Sections Exist in pjsip.conf
......................................................................


chan_pjsip: Creating Channel Causes Asterisk to Crash When Duplicate AOR
            Sections Exist in pjsip.conf

This test contains two tests: [duplicate_sections] and [happy_config].

For the [duplicate_sections] test:
This test ensures Asterisk gracefully handles the situation where
duplicate sections are defined in pjsip.conf. Seven (7) test scenarios
are utilized to confirm configuring pjsip.conf with sections containing an
identical id/type combination as another section in the file, results in
Asterisk rejecting the configuration for the given object type. Each test
scenario uses its own Asterisk instance to exercise a different id/type
combination.

The test scenarios:
Scenario [1] -> ast1: Tests duplicate [id=siptrunk, type=aor] sections
Scenario [2] -> ast2: Tests duplicate [id=siptrunk, type=auth] sections
Scenario [3] -> ast3: Tests duplicate [id=siptrunk, type=contact] sections
Scenario [4] -> ast4: Tests duplicate [id=siptrunk, type=endpoint] sections
Scenario [5] -> ast5: Tests duplicate [id=siptrunk, type=identify] sections
Scenario [6] -> ast6: Tests duplicate [id=siptrunk, type=registration] sections
Scenario [7] -> ast7: Tests duplicate [id=siptrunk, type=transport] sections

For the [happy_config] test:
This test uses a pjsip.conf that represents the unique sections from the
base configuration for the [duplicate_sections] test, to ensure Asterisk
does not misidentify and reject a correct configuration.

ASTERISK-24996
Reported By: Ashley Sanders

Change-Id: I36078aae985050cff323ace3ccfd7464fe1de35f
---
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast1/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast2/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast3/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast4/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast5/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast6/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/configs/ast7/pjsip.conf
A tests/channels/pjsip/configuration/duplicate_sections/test-config.yaml
A tests/channels/pjsip/configuration/happy_config/configs/ast1/pjsip.conf
A tests/channels/pjsip/configuration/happy_config/test-config.yaml
A tests/channels/pjsip/configuration/test_harness.py
A tests/channels/pjsip/configuration/test_scenario.py
A tests/channels/pjsip/configuration/tests.yaml
M tests/channels/pjsip/tests.yaml
14 files changed, 1,374 insertions(+), 0 deletions(-)

Approvals:
  Mark Michelson: Looks good to me, but someone else must approve
  Matt Jordan: Looks good to me, approved; Verified



diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast1/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..d50fbab
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast1/pjsip.conf
@@ -0,0 +1,119 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.1
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.1:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.1
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.1:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.1:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast2/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast2/pjsip.conf
new file mode 100644
index 0000000..38733a6
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast2/pjsip.conf
@@ -0,0 +1,119 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.2
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.2:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.2
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.2:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.2:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](auth-template)
+username=foo
+password=bar
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast3/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast3/pjsip.conf
new file mode 100644
index 0000000..98ab555
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast3/pjsip.conf
@@ -0,0 +1,119 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.3
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.3:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.3
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.3:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.3:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.3:5062
+
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast4/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast4/pjsip.conf
new file mode 100644
index 0000000..f8f726d
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast4/pjsip.conf
@@ -0,0 +1,121 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.4
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.4:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.4
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.4:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.4:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast5/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast5/pjsip.conf
new file mode 100644
index 0000000..4e465e1
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast5/pjsip.conf
@@ -0,0 +1,119 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.5
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.5:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.5
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.5:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.5:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.5
\ No newline at end of file
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast6/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast6/pjsip.conf
new file mode 100644
index 0000000..e24d736
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast6/pjsip.conf
@@ -0,0 +1,122 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.6
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.6:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.6
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.6:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.6:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.6:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
\ No newline at end of file
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/configs/ast7/pjsip.conf b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast7/pjsip.conf
new file mode 100644
index 0000000..6429711
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/configs/ast7/pjsip.conf
@@ -0,0 +1,118 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.7
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.7:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.7
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.7:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.7:5061
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; duplicate entry
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](transport-template)
+bind=127.0.0.7:5061
\ No newline at end of file
diff --git a/tests/channels/pjsip/configuration/duplicate_sections/test-config.yaml b/tests/channels/pjsip/configuration/duplicate_sections/test-config.yaml
new file mode 100644
index 0000000..856c4b2
--- /dev/null
+++ b/tests/channels/pjsip/configuration/duplicate_sections/test-config.yaml
@@ -0,0 +1,72 @@
+testinfo:
+    summary: |
+        Ensures Asterisk correctly handles the situation where duplicate
+        entries are defined in pjsip.conf.
+    description: |
+        This test ensures Asterisk gracefully handles the situation where
+        duplicate sections are defined in pjsip.conf. Seven (7) test
+        scenarios are utilized to confirm configuring pjsip.conf with sections
+        containing an identical id/type combination as another section in the
+        file, results in Asterisk rejecting the configuration. Each test
+        scenario uses its own Asterisk instance to exercise a different id/type
+        combination. The test scenarios:
+        Scenario [1] -> ast1: Tests duplicate [id=siptrunk, type=aor] sections
+        Scenario [2] -> ast2: Tests duplicate [id=siptrunk, type=auth] sections
+        Scenario [3] -> ast3: Tests duplicate [id=siptrunk, type=contact] sections
+        Scenario [4] -> ast4: Tests duplicate [id=siptrunk, type=endpoint] sections
+        Scenario [5] -> ast5: Tests duplicate [id=siptrunk, type=identify] sections
+        Scenario [6] -> ast6: Tests duplicate [id=siptrunk, type=registration] sections
+        Scenario [7] -> ast7: Tests duplicate [id=siptrunk, type=transport] sections
+
+properties:
+    minversion: '13.4.0'
+    dependencies:
+        - asterisk: 'res_pjsip'
+        - python: 'autobahn.websocket'
+        - python: 'starpy'
+        - python: 'twisted'
+        - sipp:
+            version: 'v3.0'
+    tags:
+        - pjsip
+    issues:
+        - jira: 'ASTERISK-24996'
+
+test-modules:
+    add-test-to-search-path: 'True'
+    add-relative-to-search-path: ['..']
+    test-object:
+        config-section: 'test-object-config'
+        typename: 'test_case.TestCaseModule'
+    modules:
+        -
+            config-section: 'duplicate-sections'
+            typename: 'test_harness.TestHarness'
+
+test-object-config:
+    asterisk-instances: 7
+    connect-ami: 'True'
+
+duplicate-sections:
+    test-scenarios:
+        -
+            cli_command: 'pjsip show aors'
+            output_query: 'No\sobjects\sfound\.'
+        -
+            cli_command: 'pjsip show auths'
+            output_query: 'No\sobjects\sfound\.'
+        -
+            cli_command: 'pjsip show contacts'
+            output_query: 'No\sobjects\sfound\.'
+        -
+            cli_command: 'pjsip show endpoints'
+            output_query: 'No\sobjects\sfound\.'
+        -
+            cli_command: 'pjsip show identifies'
+            output_query: 'No\sobjects\sfound\.'
+        -
+            cli_command: 'pjsip show registrations'
+            output_query: 'No\sobjects\sfound\.'
+        -
+            cli_command: 'pjsip show transports'
+            output_query: 'No\sobjects\sfound\.'
diff --git a/tests/channels/pjsip/configuration/happy_config/configs/ast1/pjsip.conf b/tests/channels/pjsip/configuration/happy_config/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..2141657
--- /dev/null
+++ b/tests/channels/pjsip/configuration/happy_config/configs/ast1/pjsip.conf
@@ -0,0 +1,112 @@
+[global]
+type=global
+debug=yes
+
+[acl-template](!)
+type=acl
+contactdeny=0.0.0.0/0.0.0.0
+
+[aor-template](!)
+type=aor
+default_expiration=240
+max_contacts=5
+minimum_expiration=240
+maximum_expiration=3600
+qualify_frequency=900
+
+[auth-template](!)
+type=auth
+auth_type=userpass
+realm=asterisk
+
+[contact-template](!)
+type=contact
+qualify_frequency=0
+
+[domain-alias-template](!)
+type=domain_alias
+
+[endpoint-template](!)
+type=endpoint
+transport=trans
+disallow=all
+allow=ulaw
+allow_subscribe=yes
+allow_transfer=yes
+callerid=uut_callerid_name <uut_callerid_num>
+callerid_privacy=allowed
+connected_line_method=invite
+context=local
+device_state_busy_at=0
+direct_media=no
+fax_detect=no
+force_rport=yes
+from_domain=
+from_user=
+rewrite_contact=no
+t38_udptl=no
+t38_udptl_ec=none
+t38_udptl_ipv6=no
+t38_udptl_maxdatagram=0
+t38_udptl_nat=no
+trust_id_inbound=no
+trust_id_outbound=no
+
+[identify-template](!)
+type=identify
+
+[registration-template](!)
+type=registration
+auth_rejection_permanent=no
+expiration=3600
+forbidden_retry_interval=0
+max_retries=10
+outbound_proxy=
+retry_interval=60
+
+[system-template](!)
+type=system
+
+[transport-template](!)
+type=transport
+protocol=udp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+[siptrunk](acl-template)
+contactpermit=127.0.0.1
+
+[siptrunk](aor-template)
+contact=siptrunk
+mailboxes=4000 at default
+
+[siptrunk](auth-template)
+username=foo
+password=bar
+
+[siptrunk](contact-template)
+contact=sip:siptrunk at 127.0.0.1:5062
+
+[siptrunk](domain-alias-template)
+domain=foo.com
+
+[siptrunk](endpoint-template)
+aors=siptrunk
+auth=siptrunk
+from_user=siptrunk
+outbound_auth=siptrunk
+
+[siptrunk](identify-template)
+endpoint=siptrunk
+match=127.0.0.1
+
+[siptrunk](registration-template)
+client_uri=sip:siptrunk at 127.0.0.1:5061
+server_uri=siptrunk
+contact_user=siptrunk
+outbound_auth=siptrunk
+transport=siptrunk
+
+[siptrunk](transport-template)
+bind=127.0.0.1:5061
+
diff --git a/tests/channels/pjsip/configuration/happy_config/test-config.yaml b/tests/channels/pjsip/configuration/happy_config/test-config.yaml
new file mode 100644
index 0000000..4386a72
--- /dev/null
+++ b/tests/channels/pjsip/configuration/happy_config/test-config.yaml
@@ -0,0 +1,42 @@
+testinfo:
+    summary: |
+        Ensures Asterisk does not reject a correct pjsip configuration.
+    description: |
+        This test uses a pjsip.conf that represents the unique sections from
+        the base configuration for the [duplicate_sections] test, to ensure
+        Asterisk does not misidentify and reject a correct configuration.
+
+properties:
+    minversion: '13.4.0'
+    dependencies:
+        - asterisk: 'res_pjsip'
+        - python: 'autobahn.websocket'
+        - python: 'starpy'
+        - python: 'twisted'
+        - sipp:
+            version: 'v3.0'
+    tags:
+        - pjsip
+    issues:
+        - jira: 'ASTERISK-24996'
+
+test-modules:
+    add-test-to-search-path: 'True'
+    add-relative-to-search-path: ['..']
+    test-object:
+        config-section: 'test-object-config'
+        typename: 'test_case.TestCaseModule'
+    modules:
+        -
+            config-section: 'happy-config'
+            typename: 'test_harness.TestHarness'
+
+test-object-config:
+    asterisk-instances: 1
+    connect-ami: 'True'
+
+happy-config:
+    test-scenarios:
+        -
+            cli_command: 'module show like res_pjsip.so'
+            output_query: 'res_pjsip\.so[^\n]+\n[1-9][0-9]*\smodules\sloaded'
\ No newline at end of file
diff --git a/tests/channels/pjsip/configuration/test_harness.py b/tests/channels/pjsip/configuration/test_harness.py
new file mode 100755
index 0000000..4b1ad70
--- /dev/null
+++ b/tests/channels/pjsip/configuration/test_harness.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python
+"""
+Copyright (C) 2015, Digium, Inc.
+Ashley Sanders <asanders at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+"""
+
+import sys
+import logging
+
+sys.path.append("lib/python")
+sys.path.append("tests/channels/pjsip/configuration")
+
+from test_scenario import TestScenario
+
+LOGGER = logging.getLogger(__name__)
+
+
+class TestHarness(object):
+    """The test harness.
+
+    This class creates and manages the life-cycle of the the objects needed to
+    execute the test plan.
+    """
+
+    def __init__(self, config, test_object):
+        """Constructor.
+
+        Keyword Arguments:
+        config                 -- The YAML configuration for this test.
+        test_object            -- The TestCaseModule instance for this test.
+        """
+
+        LOGGER.debug('{0} Initializing test harness.'.format(self))
+
+        self.test_object = test_object
+
+        self.__scenarios = self.__build_scenarios(self.__load_config(config))
+
+        self.test_object.register_stop_observer(self.__on_asterisk_stop)
+        self.test_object.register_ami_observer(self.__on_ami_connect)
+
+        return
+
+    def __format__(self, format_spec):
+        """Overrides default format handling for 'self'."""
+
+        return self.__class__.__name__ + ':'
+
+    def __build_scenarios(self, config_scenarios):
+        """Builds the scenarios.
+
+        Keyword Arguments:
+        config_scenarios       -- The test-scenarios section from the YAML
+                                  configuration.
+
+        Returns:
+        A list of scenarios.
+        """
+
+        LOGGER.debug('{0} Building test scenarios.'.format(self))
+        scenarios = list()
+        LOGGER.info('config_scenarios=%r' % config_scenarios)
+
+        for i in range(0, self.test_object.asterisk_instances):
+            config_scenario = config_scenarios[i]
+            scenario = TestScenario(config_scenario['cli_command'],
+                                    config_scenario['output_query'],
+                                    self.__on_scenario_complete)
+            scenarios.append(scenario)
+        return scenarios
+
+    def __load_config(self, config):
+        """Loads the module configuration.
+
+        Keyword Arguments:
+        config                 -- The YAML configuration for this test.
+
+        Returns a list of cli_command/output_query objects to use as test
+        conditions for running the scenario.
+        """
+
+        if not self.__validate_config(config):
+            msg = '{0} Aborting test. Configuration contains errors.'
+            LOGGER.error(msg.format(self))
+            self.test_object.stop_reactor()
+
+        LOGGER.debug('{0} Loading module configuration.'.format(self))
+
+        return config['test-scenarios']
+
+    def __on_ami_connect(self, ami):
+        """Handler for the AMI connect event.
+
+        Keyword Arguments:
+        ami                    -- The AMI instance that raised this event.
+        """
+
+        index = ami.id
+        msg = '{0} Starting execution for scenario[{1}]'
+        LOGGER.info(msg.format(self, index))
+        scenario = self.__scenarios[index]
+        scenario.run(self.test_object.ast[index])
+        return
+
+    def __on_asterisk_stop(self, result):
+        """Determines the overall pass/fail state for the test prior to
+        shutting down the reactor.
+
+        Keyword Arguments:
+        result                 -- A twisted deferred object
+
+        Returns:
+        A twisted deferred object.
+        """
+
+        LOGGER.debug('{0} Calculating test results.'.format(self))
+        for scenario in self.__scenarios:
+            self.test_object.set_passed(scenario.passed)
+        return result
+
+    def __on_scenario_complete(self, message):
+        """Queries the scenarios to determine if the test is complete.
+
+        Keyword Arguments:
+        message                -- The event payload.
+        """
+
+        LOGGER.debug('{0} Querying test scenarios.'.format(self))
+
+        for scenario in self.__scenarios:
+            if not scenario.finished:
+                return
+
+        LOGGER.debug('{0} Test case execution is complete.'.format(self))
+        self.test_object.stop_reactor()
+
+    def __validate_config(self, config):
+        """Validates the module configuration for this test.
+
+        Keyword Arguments:
+        config                 -- The YAML configuration for this test.
+
+        Returns:
+        True if the configuration is valid, False otherwise.
+        """
+
+        LOGGER.debug('{0} Validating module configuration.'.format(self))
+
+        if not config:
+            LOGGER.error('{0} No configuration provided.'.format(self))
+            return False
+
+        if 'test-scenarios' not in config:
+            msg = '{0} {1} is missing required attribute \'{2}\'.'
+            LOGGER.error(msg.format(self,
+                                    'Configuration',
+                                    'test-scenarios'))
+            return False
+
+        valid = None
+
+        for scenario in config['test-scenarios']:
+            if 'cli_command' not in scenario:
+                msg = '{0} {1} is missing required attribute \'{2}\'.'
+                LOGGER.error(msg.format(self,
+                                        '\'test-scenario\' attribute',
+                                        'cli_command'))
+                valid = False
+
+            if 'output_query' not in scenario:
+                msg = '{0} {1} is missing required attribute \'{2}\'.'
+                LOGGER.error(msg.format(self,
+                                        '\'test-scenario\' attribute',
+                                        'output_query'))
+                valid = False
+
+            for key in scenario.keys():
+                k = key.lower()
+                if k != 'cli_command' and k != 'output_query':
+                    msg = '{0} Unsupported attribute \'{1}\' specified.'
+                    LOGGER.error(msg.format(self, key))
+                    valid = False
+
+        return valid if valid is not None else True
diff --git a/tests/channels/pjsip/configuration/test_scenario.py b/tests/channels/pjsip/configuration/test_scenario.py
new file mode 100755
index 0000000..ecc4238
--- /dev/null
+++ b/tests/channels/pjsip/configuration/test_scenario.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+"""
+Copyright (C) 2015, Digium, Inc.
+Ashley Sanders <asanders at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+"""
+
+import sys
+import logging
+import re
+
+sys.path.append("lib/python")
+sys.path.append("tests/channels/pjsip/configuration")
+
+LOGGER = logging.getLogger(__name__)
+
+
+class TestScenario(object):
+    """The test scenario.
+
+    This class is responsible for executing the test strategy and reporting
+    the test results.
+    """
+
+    def __init__(self, cli_command, output_query, on_complete=None):
+        """Constructor.
+
+        Keyword Arguments:
+        cli_command            -- The CLI command to execute.
+        output_query           -- The regex query to use to search the output
+                                  of the CLI command.
+        on_complete            -- The callback to invoke when the scenario has
+                                  completed executing (optional) (default None).
+        """
+
+        LOGGER.debug('{0} Initializing test scenario'.format(self))
+        self.__cli_command = cli_command
+        self.__output_query = output_query
+        self.__on_complete = on_complete
+        self.__passed = None
+
+    def __format__(self, format_spec):
+        """Overrides default format handling for 'self'."""
+
+        return self.__class__.__name__ + ':'
+
+    def __parse_cli_output(self, cli):
+        """Parses the CLI command output to determine if the res_pjsip.so
+        module is loaded.
+
+        Keyword Arguments:
+        cli                    -- The AsteriskCliCommand instance containing
+                                  the CLI executed command and its output.
+
+        Returns:
+        An AsteriskCliCommand instance.
+        """
+
+        command = cli.cli_cmd
+        output = cli.output
+
+        LOGGER.debug('{0} Parsing CLI Command Output.'.format(self))
+        LOGGER.debug('{0} CLI Command: {1}'.format(self, command))
+        LOGGER.debug('{0} CLI Output: {1}'.format(self, output))
+
+        query_results = re.search(self.__output_query, output)
+        self.passed = query_results is not None
+        return cli
+
+    def run(self, ast):
+        """Runs the scenario.
+
+        Keyword Arguments:
+        ast                    -- The Asterisk instance for this scenario.
+
+        Returns:
+        A twisted deferred instance.
+        """
+
+        LOGGER.debug('{0} Running test scenario.'.format(self))
+
+        cli_deferred = ast.cli_exec(self.__cli_command)
+        cli_deferred.addCallback(self.__parse_cli_output)
+        if self.__on_complete is not None:
+            cli_deferred.addCallback(self.__on_complete)
+        return cli_deferred
+
+    @property
+    def finished(self):
+        """Whether or not the this scenario has finished execution.
+
+        Returns:
+        True if the scenario has finished execution, False otherwise.
+        """
+
+        return self.__passed is not None
+
+    @property
+    def passed(self):
+        """The results of the scenario.
+
+        Returns:
+        False if the scenario has not finished execution. Else, True if the
+        scenario was successful, False otherwise.
+        """
+
+        return False if not self.finished else self.__passed
+
+    @passed.setter
+    def passed(self, value):
+        """Safely set the passed variable for this scenario."""
+
+        if self.__passed is False:
+            return
+
+        self.__passed = value
+        return
diff --git a/tests/channels/pjsip/configuration/tests.yaml b/tests/channels/pjsip/configuration/tests.yaml
new file mode 100644
index 0000000..6f26d7f
--- /dev/null
+++ b/tests/channels/pjsip/configuration/tests.yaml
@@ -0,0 +1,4 @@
+# Enter tests here in the order they should be considered for execution:
+tests:
+    - test: 'duplicate_sections'
+    - test: 'happy_config'
diff --git a/tests/channels/pjsip/tests.yaml b/tests/channels/pjsip/tests.yaml
index d806233..b9af685 100644
--- a/tests/channels/pjsip/tests.yaml
+++ b/tests/channels/pjsip/tests.yaml
@@ -38,3 +38,4 @@
     - test: 'in_dialog_options'
     - dir: 'resolver'
     - test: 'forward_loop'
+    - dir: 'configuration'
\ No newline at end of file

-- 
To view, visit https://gerrit.asterisk.org/241
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I36078aae985050cff323ace3ccfd7464fe1de35f
Gerrit-PatchSet: 8
Gerrit-Project: testsuite
Gerrit-Branch: master
Gerrit-Owner: Ashley Sanders <asanders at digium.com>
Gerrit-Reviewer: Ashley Sanders <asanders at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Matt Jordan <mjordan at digium.com>



More information about the asterisk-commits mailing list