<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/testsuite/+/20000">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span></span><br></pre><div style="white-space:pre-wrap">Approvals:
George Joseph: Looks good to me, approved
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_mixmonitor: test for MixMonitorMute by MixMonitor ID<br><br>Test the ability to retrieve the mixmonitor ID from dialplan<br>then use it to mute and stop individual mixmonitor instances<br><br>Also test that sending a mute action without specifying<br>the mixmonitor ID results in the action happening on<br>all instances.<br><br>Requires coresponding Asterisk change to pass.<br><br>ASTERISK-30464<br><br>Change-Id: I05cf277d2905a9024020aedf0ab389b528237fa3<br>---<br>R tests/manager/mixmonitor/mixmonitor_basic/configs/ast1/extensions.conf<br>R tests/manager/mixmonitor/mixmonitor_basic/test-config.yaml<br>A tests/manager/mixmonitor/mixmonitor_id/configs/ast1/extensions.conf<br>A tests/manager/mixmonitor/mixmonitor_id/run-test<br>A tests/manager/mixmonitor/mixmonitor_id/test-config.yaml<br>A tests/manager/mixmonitor/tests.yaml<br>M tests/manager/tests.yaml<br>7 files changed, 222 insertions(+), 2 deletions(-)<br><br></pre>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/tests/manager/mixmonitor/configs/ast1/extensions.conf b/tests/manager/mixmonitor/mixmonitor_basic/configs/ast1/extensions.conf</span><br><span>similarity index 100%</span><br><span>rename from tests/manager/mixmonitor/configs/ast1/extensions.conf</span><br><span>rename to tests/manager/mixmonitor/mixmonitor_basic/configs/ast1/extensions.conf</span><br><span>diff --git a/tests/manager/mixmonitor/test-config.yaml b/tests/manager/mixmonitor/mixmonitor_basic/test-config.yaml</span><br><span>similarity index 98%</span><br><span>rename from tests/manager/mixmonitor/test-config.yaml</span><br><span>rename to tests/manager/mixmonitor/mixmonitor_basic/test-config.yaml</span><br><span>index 2ee5b6c..03b986c 100644</span><br><span>--- a/tests/manager/mixmonitor/test-config.yaml</span><br><span>+++ b/tests/manager/mixmonitor/mixmonitor_basic/test-config.yaml</span><br><span>@@ -49,7 +49,7 @@</span><br><span> Action: 'MixMonitor'</span><br><span> Channel: '{channel}'</span><br><span> File: 'theRecording.wav'</span><br><span style="color: hsl(0, 100%, 40%);">- Options: 'r'</span><br><span style="color: hsl(120, 100%, 40%);">+ Options: 'ri(monty)'</span><br><span> -</span><br><span> ami-events:</span><br><span> conditions:</span><br><span>diff --git a/tests/manager/mixmonitor/mixmonitor_id/configs/ast1/extensions.conf b/tests/manager/mixmonitor/mixmonitor_id/configs/ast1/extensions.conf</span><br><span>new file mode 100644</span><br><span>index 0000000..abd0555</span><br><span>--- /dev/null</span><br><span>+++ b/tests/manager/mixmonitor/mixmonitor_id/configs/ast1/extensions.conf</span><br><span>@@ -0,0 +1,21 @@</span><br><span style="color: hsl(120, 100%, 40%);">+[default]</span><br><span style="color: hsl(120, 100%, 40%);">+exten => talk,1,Answer()</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(startone)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(1)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(starttwo)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(1)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(muteone)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(1)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(mutetwo)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(1)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(unmute)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(1)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(stopone)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(1)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,UserEvent(stoptwo)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Wait(5)</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Hangup()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+exten => echo,1,Answer()</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Echo()</span><br><span style="color: hsl(120, 100%, 40%);">+ same => n,Hangup()</span><br><span>\ No newline at end of file</span><br><span>diff --git a/tests/manager/mixmonitor/mixmonitor_id/run-test b/tests/manager/mixmonitor/mixmonitor_id/run-test</span><br><span>new file mode 100755</span><br><span>index 0000000..ef8a01e</span><br><span>--- /dev/null</span><br><span>+++ b/tests/manager/mixmonitor/mixmonitor_id/run-test</span><br><span>@@ -0,0 +1,159 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#!/usr/bin/env python</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+Copyright (C) 2023, Sangoma Technologies.</span><br><span style="color: hsl(120, 100%, 40%);">+Michael Bradeen <mbradeen@sangoma.com></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+the GNU General Public License Version 2.</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import sys</span><br><span style="color: hsl(120, 100%, 40%);">+import logging</span><br><span style="color: hsl(120, 100%, 40%);">+from twisted.internet import reactor</span><br><span style="color: hsl(120, 100%, 40%);">+from asterisk.test_case import TestCase</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+LOGGER = logging.getLogger(__name__)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class MixMonitorTest(TestCase):</span><br><span style="color: hsl(120, 100%, 40%);">+ def __init__(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ super(MixMonitorTest, self).__init__()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passed = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.startCount = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedStart = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.muteCount = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedMute = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedUnMute = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.stopCount = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedStop = False</span><br><span style="color: hsl(120, 100%, 40%);">+ self.mixmonid1 = ""</span><br><span style="color: hsl(120, 100%, 40%);">+ self.mixmonid2 = ""</span><br><span style="color: hsl(120, 100%, 40%);">+ self.create_asterisk()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def __checkPass(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passed = self.passedStart and self.passedMute and self.passedUnMute and self.passedStop</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking Test Pass/Fail")</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Passed Start: " + str(self.passedStart))</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Passed Mute: " + str(self.passedMute))</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Passed UnMute: " + str(self.passedUnMute))</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Passed Stop: " + str(self.passedStop))</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Passed All: " + str(self.passed))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def launch_test(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Placing call to local talking extension")</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.originate(channel="Local/talk@default",</span><br><span style="color: hsl(120, 100%, 40%);">+ context="default",</span><br><span style="color: hsl(120, 100%, 40%);">+ exten="echo",</span><br><span style="color: hsl(120, 100%, 40%);">+ priority="1")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def check_teststate(self, ami, event):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def switchState(teststate, channel):</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'None', }</span><br><span style="color: hsl(120, 100%, 40%);">+ if teststate == "startone":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'MixMonitor', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'File': 'oneRecording.wav', 'Options': 'ri(idone)'}</span><br><span style="color: hsl(120, 100%, 40%);">+ elif teststate == "starttwo":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'MixMonitor', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'File': 'twoRecording.wav', 'Options': 'ri(idtwo)'}</span><br><span style="color: hsl(120, 100%, 40%);">+ elif teststate == "muteone":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'MixMonitorMute', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'Direction': 'both', 'State': '1', 'MixMonitorID': self.mixmonid1}</span><br><span style="color: hsl(120, 100%, 40%);">+ elif teststate == "mutetwo":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'MixMonitorMute', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'Direction': 'both', 'State': '1', 'MixMonitorID': self.mixmonid2}</span><br><span style="color: hsl(120, 100%, 40%);">+ elif teststate == "unmute":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'MixMonitorMute', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'Direction': 'both', 'State': '0'}</span><br><span style="color: hsl(120, 100%, 40%);">+ elif teststate == "stopone":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'StopMixMonitor', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'MixMonitorID': self.mixmonid1}</span><br><span style="color: hsl(120, 100%, 40%);">+ elif teststate == "stoptwo":</span><br><span style="color: hsl(120, 100%, 40%);">+ message = {'Action': 'StopMixMonitor', 'Channel': channel,</span><br><span style="color: hsl(120, 100%, 40%);">+ 'MixMonitorID': self.mixmonid2}</span><br><span style="color: hsl(120, 100%, 40%);">+ return message</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking UserEvent")</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.sendMessage(switchState(event.get("userevent").lower(), event.get("channel")))</span><br><span style="color: hsl(120, 100%, 40%);">+ return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def check_start_mixmonitor(self, ami, event):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ self.startCount+=1</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking MixMonitorStart " + str(self.startCount))</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.startCount == 2 :</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedStart = True</span><br><span style="color: hsl(120, 100%, 40%);">+ return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def check_chanvar(self, ami, event):</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def switchState(event):</span><br><span style="color: hsl(120, 100%, 40%);">+ VarName = event.get("variable").lower()</span><br><span style="color: hsl(120, 100%, 40%);">+ VarVal = event.get("value")</span><br><span style="color: hsl(120, 100%, 40%);">+ if VarName == "idone":</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Setting idone:" + VarVal)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.mixmonid1 = VarVal</span><br><span style="color: hsl(120, 100%, 40%);">+ elif VarName == "idtwo":</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Setting idtwo:" + VarVal)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.mixmonid2 = VarVal</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking VarSet")</span><br><span style="color: hsl(120, 100%, 40%);">+ switchState(event)</span><br><span style="color: hsl(120, 100%, 40%);">+ return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def check_mute_mixmonitor(self, ami, event):</span><br><span style="color: hsl(120, 100%, 40%);">+ self.muteCount+=1</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking MixMonitorMute " + str(self.muteCount))</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.muteCount == 2 :</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedMute = True</span><br><span style="color: hsl(120, 100%, 40%);">+ return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def check_testevent(self, ami, event):</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking TestEvent")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ # only look for source and count for a mute toggle</span><br><span style="color: hsl(120, 100%, 40%);">+ if event.get("state") == "AUDIOHOOK_GROUP_MUTE_TOGGLE":</span><br><span style="color: hsl(120, 100%, 40%);">+ if event.get("source") == "MixMonitor" and event.get("count") == "2" :</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedUnMute = True</span><br><span style="color: hsl(120, 100%, 40%);">+ return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def check_stop_mixmonitor(self, ami, event):</span><br><span style="color: hsl(120, 100%, 40%);">+ self.stopCount+=1</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGGER.info("Checking MixMonitorStop " + str(self.stopCount))</span><br><span style="color: hsl(120, 100%, 40%);">+ if self.stopCount == 2 :</span><br><span style="color: hsl(120, 100%, 40%);">+ self.passedStop = True</span><br><span style="color: hsl(120, 100%, 40%);">+ self.__checkPass()</span><br><span style="color: hsl(120, 100%, 40%);">+ # stop reactor at final MixMonitorStop</span><br><span style="color: hsl(120, 100%, 40%);">+ reactor.stop()</span><br><span style="color: hsl(120, 100%, 40%);">+ return</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def ami_connect(self, ami):</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami = ami</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.registerEvent("UserEvent", self.check_teststate)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.registerEvent("TestEvent", self.check_testevent)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.registerEvent("MixMonitorStart", self.check_start_mixmonitor)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.registerEvent("MixMonitorMute", self.check_mute_mixmonitor)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.registerEvent("MixMonitorStop", self.check_stop_mixmonitor)</span><br><span style="color: hsl(120, 100%, 40%);">+ self.ami.registerEvent("VarSet", self.check_chanvar)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ self.launch_test()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ def run(self):</span><br><span style="color: hsl(120, 100%, 40%);">+ self.create_ami_factory()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def main():</span><br><span style="color: hsl(120, 100%, 40%);">+ test = MixMonitorTest()</span><br><span style="color: hsl(120, 100%, 40%);">+ reactor.run()</span><br><span style="color: hsl(120, 100%, 40%);">+ if test.passed:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == "__main__":</span><br><span style="color: hsl(120, 100%, 40%);">+ sys.exit(main() or 0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# vim:sw=4:ts=4:expandtab:textwidth=79</span><br><span>diff --git a/tests/manager/mixmonitor/mixmonitor_id/test-config.yaml b/tests/manager/mixmonitor/mixmonitor_id/test-config.yaml</span><br><span>new file mode 100644</span><br><span>index 0000000..5a903d2</span><br><span>--- /dev/null</span><br><span>+++ b/tests/manager/mixmonitor/mixmonitor_id/test-config.yaml</span><br><span>@@ -0,0 +1,15 @@</span><br><span style="color: hsl(120, 100%, 40%);">+testinfo:</span><br><span style="color: hsl(120, 100%, 40%);">+ summary: 'Tests that the MixMonitor id channel variable'</span><br><span style="color: hsl(120, 100%, 40%);">+ description: |</span><br><span style="color: hsl(120, 100%, 40%);">+ 'This test verifies that the MixMonitor id channel variable can be used to</span><br><span style="color: hsl(120, 100%, 40%);">+ stop and mute individually running MixMonitor instances.'</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+properties:</span><br><span style="color: hsl(120, 100%, 40%);">+ dependencies:</span><br><span style="color: hsl(120, 100%, 40%);">+ - python : 'twisted'</span><br><span style="color: hsl(120, 100%, 40%);">+ - python : 'starpy'</span><br><span style="color: hsl(120, 100%, 40%);">+ - asterisk : 'app_echo'</span><br><span style="color: hsl(120, 100%, 40%);">+ - asterisk : 'app_mixmonitor'</span><br><span style="color: hsl(120, 100%, 40%);">+ - asterisk : 'app_userevent'</span><br><span style="color: hsl(120, 100%, 40%);">+ tags:</span><br><span style="color: hsl(120, 100%, 40%);">+ - mixmonitor</span><br><span>diff --git a/tests/manager/mixmonitor/tests.yaml b/tests/manager/mixmonitor/tests.yaml</span><br><span>new file mode 100644</span><br><span>index 0000000..18d4900</span><br><span>--- /dev/null</span><br><span>+++ b/tests/manager/mixmonitor/tests.yaml</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+# Enter tests here in the order they should be considered for execution:</span><br><span style="color: hsl(120, 100%, 40%);">+tests:</span><br><span style="color: hsl(120, 100%, 40%);">+ - test: 'mixmonitor_basic'</span><br><span style="color: hsl(120, 100%, 40%);">+ - test: 'mixmonitor_id'</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/tests/manager/tests.yaml b/tests/manager/tests.yaml</span><br><span>index 1f0dccf..993b966 100644</span><br><span>--- a/tests/manager/tests.yaml</span><br><span>+++ b/tests/manager/tests.yaml</span><br><span>@@ -14,7 +14,7 @@</span><br><span> - test: 'exten_state_list'</span><br><span> - test: 'presence_state_changed'</span><br><span> - test: 'presence_state_list'</span><br><span style="color: hsl(0, 100%, 40%);">- - test: 'mixmonitor'</span><br><span style="color: hsl(120, 100%, 40%);">+ - dir: 'mixmonitor'</span><br><span> - test: 'manager_vars'</span><br><span> - test: 'status'</span><br><span> - test: 'status_all_vars'</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/testsuite/+/20000">change 20000</a>. To unsubscribe, or for help writing mail filters, 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/c/testsuite/+/20000"/><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-Change-Id: I05cf277d2905a9024020aedf0ab389b528237fa3 </div>
<div style="display:none"> Gerrit-Change-Number: 20000 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Michael Bradeen <mbradeen@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>