<p>Yasuhiko Kamata has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7705">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">A testsuite test for 3PCC patch for AMI "SIPnotify" (ASTERISK-27461).<br><br>This test is somewhat complicated than other tests in AMI;<br>because the value of "Call-ID" is needed to send "SIPnotify" AMI action.<br><br>Change-Id: Idccbf32ed6670a5205ee99bd7413c7fe0804efb1<br>---<br>A tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/extensions.conf<br>A tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/manager.conf<br>A tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/sip.conf<br>A tests/channels/SIP/ami/sip_notify/call_id/run-test<br>A tests/channels/SIP/ami/sip_notify/call_id/sipp/callee.xml<br>A tests/channels/SIP/ami/sip_notify/call_id/sipp/caller.xml<br>A tests/channels/SIP/ami/sip_notify/call_id/test-config.yaml<br>M tests/channels/SIP/ami/sip_notify/tests.yaml<br>8 files changed, 360 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/testsuite refs/changes/05/7705/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/extensions.conf b/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/extensions.conf<br>new file mode 100644<br>index 0000000..106b4ff<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/extensions.conf<br>@@ -0,0 +1,3 @@<br>+[default]<br>+exten => callee,1,Dial(SIP/callee)<br>+<br>diff --git a/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/manager.conf b/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/manager.conf<br>new file mode 100644<br>index 0000000..c6deda4<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/manager.conf<br>@@ -0,0 +1,10 @@<br>+[general]<br>+enabled = yes<br>+port = 5038<br>+<br>+[user]<br>+secret = mysecret<br>+permit = 127.0.0.1/255.255.255.255<br>+read = all<br>+write = all<br>+<br>diff --git a/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/sip.conf b/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/sip.conf<br>new file mode 100644<br>index 0000000..d782b39<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/configs/ast1/sip.conf<br>@@ -0,0 +1,21 @@<br>+[general]<br>+udpbindaddr=0.0.0.0:5060<br>+<br>+[caller]<br>+type=friend<br>+host=127.0.0.1<br>+port=5062<br>+directmedia=no<br>+disallow=all<br>+allow=ulaw<br>+context=default<br>+<br>+[callee]<br>+type=friend<br>+host=127.0.0.1<br>+port=5063<br>+directmedia=no<br>+disallow=all<br>+allow=ulaw<br>+context=default<br>+<br>diff --git a/tests/channels/SIP/ami/sip_notify/call_id/run-test b/tests/channels/SIP/ami/sip_notify/call_id/run-test<br>new file mode 100755<br>index 0000000..12e8d82<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/run-test<br>@@ -0,0 +1,199 @@<br>+#!/usr/bin/env python<br>+<br>+import sys<br>+import os<br>+import logging<br>+import time<br>+import socket<br>+import threading<br>+import errno<br>+<br>+sys.path.append("lib/python")<br>+sys.path.append("utils")<br>+<br>+from tempfile import NamedTemporaryFile<br>+from twisted.internet import reactor<br>+from asterisk.sipp import SIPpTest<br>+<br>+WORKING_DIR = os.path.abspath(os.path.dirname(__file__))<br>+TEST_DIR = os.path.dirname(os.path.realpath(__file__))<br>+<br>+logger = logging.getLogger(__name__)<br>+<br>+class DupDict(dict):<br>+    def __setitem__(self, key, value):<br>+        try:<br>+            self[key]<br>+        except KeyError:<br>+            super(DupDict, self).__setitem__(key, [])<br>+        self[key].append(value)<br>+<br>+class AmiTestClientThread(threading.Thread):<br>+    """ AMI test client thread """<br>+<br>+    def __init__(self):<br>+        super(AmiTestClientThread, self).__init__()<br>+<br>+    def set_amihost(self, host, port):<br>+        self.host = host<br>+        self.port = port<br>+<br>+    def connect(self):<br>+        self.ami_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>+<br>+        while True:<br>+            try:<br>+                self.ami_client.connect((self.host, self.port))<br>+                break<br>+            except socket.error as serr:<br>+                if serr.errno != errno.ECONNREFUSED:<br>+                    raise serr<br>+                time.sleep(0.5) # retry wait<br>+<br>+        self.ami_client_file = self.ami_client.makefile()<br>+<br>+    def close(self):<br>+        self.ami_client_file.close()<br>+        self.ami_client.close()<br>+<br>+    def receive_message(self):<br>+        message = DupDict()<br>+<br>+        while True:<br>+            linedata = self.ami_client_file.readline()<br>+<br>+            linedata = linedata.replace("\r", "")<br>+            linedata = linedata.replace("\n", "")<br>+<br>+            if len(linedata) < 1:<br>+                break<br>+<br>+            keyvalues = linedata.split(":", 1)<br>+            if len(keyvalues) > 1:<br>+                message[keyvalues[0].strip()] = keyvalues[1].strip()<br>+            else:<br>+                message[linedata.strip()] = ""<br>+<br>+        return message<br>+<br>+    def send_message(self, message):<br>+        messagetext = ""<br>+<br>+        for key, value in message.iteritems():<br>+            messagetext += key + ": " + value + "\r\n"<br>+        messagetext += "\r\n"<br>+<br>+        self.ami_client.send(messagetext)<br>+<br>+    def run(self):<br>+        # connect and receive banner<br>+        self.connect()<br>+        self.banner = self.ami_client_file.readline()<br>+<br>+        # login<br>+        message = { "Action": "Login", "Username": "user", "Secret": "mysecret" }<br>+        self.send_message(message)<br>+<br>+        # wait for "Response: Success"<br>+        while True:<br>+            message = self.receive_message()<br>+            if message.has_key("Response"):<br>+                if message["Response"][0] == "Success":<br>+                    break<br>+                else:<br>+                    print "Response is " + str(message["Response"])<br>+                    raise<br>+<br>+        # wait for "Event: Newchannel", "Channel: SIP/callee..."<br>+        while True:<br>+            message = self.receive_message()<br>+            if message.has_key("Event"):<br>+                if message["Event"][0] == "Newchannel":<br>+                    if message["Channel"][0][0:10] == "SIP/callee":<br>+                        break<br>+        channel = message["Channel"][0]<br>+<br>+        # send "Action: Status"<br>+        message = { "Action": "Status", "Channel": channel, "AllVariables": "true" }<br>+        self.send_message(message)<br>+<br>+        # wait for "Event: Status"<br>+        call_id = ""<br>+        while True:<br>+            message = self.receive_message()<br>+            if message.has_key("Event"):<br>+                if message["Event"][0] == "Status":<br>+                    if message.has_key("Variable"):<br>+                        for value in message["Variable"]:<br>+                            if value[0:10] == "SIPCALLID=":<br>+                              call_id = value[10:]<br>+                    break<br>+        if len(call_id) < 1:<br>+            raise<br>+<br>+        # send "Action: SIPnotify"<br>+        message = { "Action": "SIPnotify", "Channel": channel, "Variable": "Event=talk", "Call-ID": call_id }<br>+        self.send_message(message)<br>+<br>+        # wait for "Response: Success"<br>+        while True:<br>+            message = self.receive_message()<br>+            if message.has_key("Response"):<br>+                if message["Response"][0] == "Success":<br>+                    break<br>+                else:<br>+                    print "Response is " + str(message["Response"])<br>+                    raise<br>+<br>+        self.close()<br>+<br>+def main():<br>+    sipplog = NamedTemporaryFile(delete=True)<br>+<br>+    SIPP_SCENARIOS = [<br>+        {<br>+            'scenario': 'caller.xml',<br>+            '-i': '127.0.0.1',<br>+            '-p': '5062',<br>+            '-s': '3200000000',<br>+            '-message_file': '/tmp/caller.log', # sipplog.name,<br>+            # Cheat and pass two argumentless options as key and value<br>+            # because the SIPpTest doesn't allow us to pass ordered-args.<br>+            # We use -pause_msg_ign to ignore messages while being paused<br>+            # and then check the log (from -trace_msg) for those messages.<br>+            '-trace_msg': '-pause_msg_ign',<br>+        },<br>+        {<br>+            'scenario': 'callee.xml',<br>+            '-i': '127.0.0.1',<br>+            '-p': '5063',<br>+            '-s': '3200000000',<br>+            '-message_file': '/tmp/callee.log', # sipplog.name,<br>+            # Cheat and pass two argumentless options as key and value<br>+            # because the SIPpTest doesn't allow us to pass ordered-args.<br>+            # We use -pause_msg_ign to ignore messages while being paused<br>+            # and then check the log (from -trace_msg) for those messages.<br>+            '-trace_msg': '-pause_msg_ign',<br>+        }<br>+    ]<br>+<br>+    test = SIPpTest(WORKING_DIR, TEST_DIR, SIPP_SCENARIOS)<br>+    test.reactor_timeout = 10<br>+<br>+    ami_client = AmiTestClientThread()<br>+    ami_client.set_amihost("localhost", 5038)<br>+    ami_client.start()<br>+<br>+    reactor.run()<br>+<br>+    # If it failed, bail.<br>+    if not test.passed:<br>+        return 1<br>+<br>+    return 0<br>+<br>+<br>+if __name__ == "__main__":<br>+    sys.exit(main())<br>+<br>+# vim:sw=4:ts=4:expandtab:textwidth=79<br>diff --git a/tests/channels/SIP/ami/sip_notify/call_id/sipp/callee.xml b/tests/channels/SIP/ami/sip_notify/call_id/sipp/callee.xml<br>new file mode 100755<br>index 0000000..d3bff3c<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/sipp/callee.xml<br>@@ -0,0 +1,76 @@<br>+<?xml version="1.0" encoding="ISO-8859-1" ?><br>+<!DOCTYPE scenario SYSTEM "sipp.dtd"><br>+<br>+<scenario name="Notify Request with Call-ID"><br>+<br>+    <recv request="INVITE"><br>+        <action><br>+            <ereg regexp=": .*"<br>+                search_in="hdr"<br>+                header="Call-ID"<br>+                check_it="true"<br>+                assign_to="1"/><br>+            <ereg regexp=": .*"<br>+                search_in="hdr"<br>+                header="CSeq"<br>+                check_it="true"<br>+                assign_to="2"/><br>+            <log message="Received INVITE with Call-ID [$1] and CSeq [$2]." /><br>+        </action><br>+    </recv><br>+<br>+    <send><br>+      <![CDATA[<br>+<br>+      SIP/2.0 180 Ringing<br>+      [last_Via:]<br>+      [last_From:]<br>+      [last_To:];tag=[pid]SIPpTag[call_number]<br>+      Call-ID: [call_id]<br>+      [last_CSeq:]<br>+      Contact: <sip:user1@[local_ip]:[local_port];transport=[transport]><br>+      Content-Length: 0<br>+      ]]><br>+    </send><br>+<br>+    <recv request="NOTIFY"><br>+        <action><br>+            <ereg regexp=": .*$"<br>+                search_in="hdr"<br>+                header="Call-ID"<br>+                check_it="true"<br>+                assign_to="3"/><br>+            <log message="Received NOTIFY with Call-ID [$3]." /><br>+        </action><br>+    </recv><br>+<br>+    <send><br>+      <![CDATA[<br>+<br>+      SIP/2.0 200 OK<br>+      [last_Via:]<br>+      [last_From:]<br>+      [last_To:];tag=[pid]SIPpTag[call_number]<br>+      Call-ID: [call_id]<br>+      [last_CSeq:]<br>+      Contact: <sip:user1@[local_ip]:[local_port];transport=[transport]><br>+      Content-Length: 0<br>+      ]]><br>+    </send><br>+<br>+    <send><br>+      <![CDATA[<br>+<br>+      SIP/2.0 200 OK<br>+      [last_Via:]<br>+      [last_From:]<br>+      [last_To:];tag=[pid]SIPpTag[call_number]<br>+      Call-ID: [call_id]<br>+      CSeq[$2]<br>+      Contact: <sip:user1@[local_ip]:[local_port];transport=[transport]><br>+      Content-Type: application/sdp<br>+      Content-Length: [len]<br>+      ]]><br>+    </send><br>+<br>+</scenario><br>diff --git a/tests/channels/SIP/ami/sip_notify/call_id/sipp/caller.xml b/tests/channels/SIP/ami/sip_notify/call_id/sipp/caller.xml<br>new file mode 100644<br>index 0000000..373d361<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/sipp/caller.xml<br>@@ -0,0 +1,35 @@<br>+<?xml version="1.0" encoding="ISO-8859-1" ?><br>+<!DOCTYPE scenario SYSTEM "sipp.dtd"><br>+<br>+<scenario name="Notify Request with Call-ID"><br>+<br>+  <send retrans="500"><br>+    <![CDATA[<br>+      INVITE sip:callee@voxbone.com SIP/2.0<br>+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]<br>+      From: caller <sip:caller@voxbone.com>;tag=[call_number]<br>+      To: callee <sip:callee@voxbone.com:[remote_port]><br>+      Call-ID: [call_id]<br>+      CSeq: 1 INVITE<br>+      Contact: sip:sipp@[local_ip]:[local_port]<br>+      Content-Type: application/sdp<br>+      Content-Length: [len]<br>+      v=0<br>+      o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]<br>+      s=-<br>+      c=IN IP[local_ip_type] [local_ip]<br>+      t=0 0<br>+      m=audio 9000 RTP/AVP 8<br>+      a=rtpmap:8 PCMU/8000<br>+    ]]><br>+  </send><br>+<br>+  <recv response="100" optional="true"><br>+  </recv><br>+<br>+  <recv response="180" optional="true"><br>+  </recv><br>+<br>+  <recv response="200"><br>+  </recv><br>+</scenario><br>diff --git a/tests/channels/SIP/ami/sip_notify/call_id/test-config.yaml b/tests/channels/SIP/ami/sip_notify/call_id/test-config.yaml<br>new file mode 100644<br>index 0000000..47c9199<br>--- /dev/null<br>+++ b/tests/channels/SIP/ami/sip_notify/call_id/test-config.yaml<br>@@ -0,0 +1,15 @@<br>+info:<br>+    summary: 'Test SIPNotify AMI Action for Call-ID'<br>+    description: |<br>+        This Tests the AMI Action SIPNotify in order to make sure<br>+        that Call-ID header can be specified.<br>+<br>+properties:<br>+    minversion: '12.0.0'<br>+    dependencies:<br>+        - sipp :<br>+            version : 'v3.0'<br>+        - asterisk : 'chan_sip'<br>+    tags:<br>+        - SIP<br>+<br>diff --git a/tests/channels/SIP/ami/sip_notify/tests.yaml b/tests/channels/SIP/ami/sip_notify/tests.yaml<br>index b1a3008..750f6d6 100644<br>--- a/tests/channels/SIP/ami/sip_notify/tests.yaml<br>+++ b/tests/channels/SIP/ami/sip_notify/tests.yaml<br>@@ -2,3 +2,4 @@<br> tests:<br>     - test: 'custom_headers'<br>     - test: 'content'<br>+    - test: 'call_id'<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7705">change 7705</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/7705"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: testsuite </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Idccbf32ed6670a5205ee99bd7413c7fe0804efb1 </div>
<div style="display:none"> Gerrit-Change-Number: 7705 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Yasuhiko Kamata <yasuhiko.kamata@nxtg.co.jp> </div>