[Asterisk-code-review] voicemail: Add test for passwordlocation=spooldir (testsuite[master])

Anonymous Coward asteriskteam at digium.com
Fri May 6 05:25:25 CDT 2016


Anonymous Coward #1000019 has submitted this change and it was merged.

Change subject: voicemail: Add test for passwordlocation=spooldir
......................................................................


voicemail: Add test for passwordlocation=spooldir

Adds a test that changes a voicemail password when the option
passwordlocation=spooldir is set. The password verifies that
audio prompts are given for the options as expected and then
on shutdown the presence of secret.conf in the user's voicemail
box folder is checked and verified to contain the expected
password.

The patch also adds a small improvement to
check_voicemail_options_change_password so that it can be ran
stand-alone without the user having to create
/tmp/asterisk-testsuite prior to running the test.

ASTERISK-25917
Reported-by: Jonathan Rose

Change-Id: I996c279e98efffe18bc6df55a395490256d560b1
---
M tests/apps/voicemail/check_voicemail_options_change_password/run-test
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/extensions.conf
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/sip.conf
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/voicemail.conf
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/extensions.conf
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/sip.conf
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/run-test
A tests/apps/voicemail/check_voicemail_options_change_password_spooldir/test-config.yaml
M tests/apps/voicemail/tests.yaml
9 files changed, 425 insertions(+), 0 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, approved



diff --git a/tests/apps/voicemail/check_voicemail_options_change_password/run-test b/tests/apps/voicemail/check_voicemail_options_change_password/run-test
index 058e262..1cf5d82 100755
--- a/tests/apps/voicemail/check_voicemail_options_change_password/run-test
+++ b/tests/apps/voicemail/check_voicemail_options_change_password/run-test
@@ -277,6 +277,10 @@
     """ Attempt to copy the test scripts over """
     scriptFileCheck = os.path.join(os.getcwd(), CheckVoicemailChangePassword.testParentDir + "/check_voicemail_options_change_password/voicemailpwcheck.py")
     scriptFileNotify = scriptFile = os.path.join(os.getcwd(), CheckVoicemailChangePassword.testParentDir + "/check_voicemail_options_change_password/voicemailpwnotify.py")
+
+    if not os.path.exists('/tmp/asterisk-testsuite'):
+        os.makedirs('/tmp/asterisk-testsuite')
+
     shutil.copy(scriptFileCheck, "/tmp/asterisk-testsuite/voicemailpwcheck.py")
     shutil.copy(scriptFileNotify, "/tmp/asterisk-testsuite/voicemailpwnotify.py")
 
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/extensions.conf b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/extensions.conf
new file mode 100644
index 0000000..724d755
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/extensions.conf
@@ -0,0 +1,21 @@
+; Voicemail contexts and extensions.
+
+[voicemail]
+
+;
+; Entry point to the VoiceMailMain application
+;
+exten => 8052,1,NoOp()
+	same => n,VoiceMailMain()
+	same => n,UserEvent(TestResult,result: pass,status: successfully exited VoiceMailMain)
+	same => n,Hangup()
+
+exten => o,1,UserEvent(TestResult,result: fail,status: failed to exit successfully through '#' key)
+
+exten => i,1,UserEvent(TestResult,result: fail,status: failed to exit successfully through '#' key)
+
+exten => e,1,UserEvent(TestResult,result: fail,status: failed to exit successfully through '#' key)
+
+exten => a,1,UserEvent(TestResult,result: fail,status: failed to exit successfully through '#' key)
+
+exten => t,1,UserEvent(TestResult,result: fail,status: failed to exit successfully through '#' key)
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/sip.conf b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/sip.conf
new file mode 100644
index 0000000..1d6df41
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/sip.conf
@@ -0,0 +1,13 @@
+[general]
+bindaddr = 127.0.0.1
+
+[ast2]
+type = friend
+context = voicemail
+fromuser = ast1
+host = 127.0.0.2
+disallow = all
+allow = ulaw
+qualify = no
+insecure = invite
+
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/voicemail.conf b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/voicemail.conf
new file mode 100644
index 0000000..07245b8
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast1/voicemail.conf
@@ -0,0 +1,21 @@
+; Voicemail Configuration
+
+[general]
+format = ulaw|wav49|wav
+skipms = 3000
+maxsilence = 0
+silencethreshold = 128
+maxlogins = 3
+minsecs = 0
+
+passwordlocation=spooldir
+
+[zonemessages]
+eastern = America/New_York|'vm-received' Q 'digits/at' IMp
+central = America/Chicago|'vm-received' Q 'digits/at' IMp
+central24 = America/Chicago|'vm-received' q 'digits/at' H N 'hours'
+military = Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'
+european = Europe/Copenhagen|'vm-received' a d b 'digits/at' HM
+
+[default]
+1234 => 1234,Mark Spencer
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/extensions.conf b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/extensions.conf
new file mode 100644
index 0000000..65e4422
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/extensions.conf
@@ -0,0 +1,27 @@
+; Various extensions that perform actions against the voicemail main application
+
+[voicemailCaller]
+
+exten => sendDTMF,1,NoOp()
+	same => n,Verbose(1, Sending DTMF Signal ${DTMF_TO_SEND})
+	same => n,SendDTMF(${DTMF_TO_SEND})
+	same => n,Goto(voicemailCaller,wait,1)
+
+exten => sendAudio,1,NoOp()
+	same => n,Verbose(1, Sending audio file ${TALK_AUDIO})
+	same => n,Playback(${TALK_AUDIO})
+	same => n,Goto(voicemailCaller,wait,1)
+
+exten => sendAudioWithDTMF,1,NoOp()
+	same => n,Verbose(1, Sending audio file ${TALK_AUDIO})
+	same => n,Playback(${TALK_AUDIO})
+	same => n,Verbose(1, Sending DTMF Signal ${DTMF_TO_SEND})
+	same => n,SendDTMF(${DTMF_TO_SEND})
+	same => n,Goto(voicemailCaller,wait,1)
+
+exten => hangup,1,NoOp()
+	same => n,Verbose(1, Hanging up)
+	same => n,Hangup()
+
+exten => wait,1,NoOp()
+	same => n,Wait(10000)
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/sip.conf b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/sip.conf
new file mode 100644
index 0000000..b0d2cd0
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/configs/ast2/sip.conf
@@ -0,0 +1,12 @@
+[general]
+bindaddr = 127.0.0.2
+
+[ast1]
+type = friend
+context = voicemailCaller
+fromuser = ast2
+host = 127.0.0.1
+disallow = all
+allow = ulaw
+qualify = no
+insecure = invite
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/run-test b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/run-test
new file mode 100755
index 0000000..a691945
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/run-test
@@ -0,0 +1,304 @@
+#!/usr/bin/env python
+# vim: sw=3 et:
+'''
+Copyright (C) 2016, Motorola Solution Inc.
+Jonathan Rose <jonathan.rose at motorolasolutions.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import sys
+import logging
+
+from twisted.internet import reactor
+
+sys.path.append("lib/python")
+
+from asterisk.asterisk import Asterisk
+from asterisk.test_case import TestCase
+from asterisk.test_state import TestStateController
+from asterisk.test_state import TestState
+from asterisk.test_state import FailureTestState
+from asterisk.voicemail import TestCondition
+from asterisk.voicemail import VoiceMailTest
+from asterisk.voicemail import VoiceMailState
+from asterisk.voicemail import VoiceMailMailboxManagement
+from asterisk.config import ConfigFile
+
+
+logger = logging.getLogger(__name__)
+
+MAILBOX = "1234"
+ORIGINAL_PASS = "1234"
+NEW_PASS = "555666"
+
+
+class StartVoiceMailState(VoiceMailState):
+    """
+    TestState that is the entry point for the VoiceMailMain application
+    """
+    userMailbox = MAILBOX + "#"
+    userPassword = ORIGINAL_PASS + "#"
+
+    def __init__(self, controller, voiceMailTest):
+        VoiceMailState.__init__(self, controller, voiceMailTest)
+
+    def handle_state_change(self, ami, event):
+        state = event['state']
+
+        if state == 'PLAYBACK':
+            message = event.get('message')
+            if message == 'vm-login':
+                self.voice_mail_test.send_dtmf(self.userMailbox)
+            elif message == 'vm-password':
+                self.voice_mail_test.send_dtmf(self.userPassword)
+        elif state == 'AUTHENTICATED':
+            self.change_state(AuthenticatedTestState(self.controller,
+                                                     self.voice_mail_test))
+        else:
+            self.handle_default_state(event)
+
+    def get_state_name(self):
+        return "START"
+
+
+class AuthenticatedTestState(VoiceMailState):
+    """
+    TestState that occurs after a user has been authenticated
+    """
+    def __init__(self, controller, voiceMailTest):
+        VoiceMailState.__init__(self, controller, voiceMailTest)
+
+    def handle_state_change(self, ami, event):
+        state = event['state']
+
+        if state == 'AUTHENTICATED':
+            logger.error("Received two authenticated events?")
+            self.change_state(FailureTestState(self.controller))
+        elif state == 'NEWUSER':
+            logger.error("New user state received; user credentials must "
+                         "have failed")
+            self.change_state(FailureTestState(self.controller))
+        elif state == 'INTRO':
+            self.change_state(IntroTestState(self.controller,
+                              self.voice_mail_test))
+        else:
+            self.handle_default_state(event)
+
+    def get_state_name(self):
+        return "AUTHENTICATED"
+
+
+class IntroTestState(VoiceMailState):
+    """
+    TestState that occurs after when the user is being presented with the
+    initial message counts and the main voicemail menu
+    """
+    def __init__(self, controller, voiceMailTest):
+        VoiceMailState.__init__(self, controller, voiceMailTest)
+
+    def handle_state_change(self, ami, event):
+        state = event['state']
+
+        if state == 'PLAYBACK':
+            message = event.get('message')
+
+            if message == 'instructions':
+                if (self.voice_mail_test.get_test_condition(
+                        "passwordChanged")):
+                    """ Exit """
+                    self.voice_mail_test.send_dtmf("#")
+                else:
+                    """ Tell it to go to the voicemail options """
+                    self.voice_mail_test.send_dtmf("0")
+        elif state == 'VMOPTIONS':
+            self.change_state(VoicemailOptionsTestState(self.controller,
+                              self.voice_mail_test))
+        else:
+            self.handle_default_state(event)
+
+    def get_state_name(self):
+        return "INTRO"
+
+
+class VoicemailOptionsTestState(VoiceMailState):
+    """
+    TestState that occurs when the user can change their options
+    """
+    def __init__(self, controller, voiceMailTest):
+        VoiceMailState.__init__(self, controller, voiceMailTest)
+        self.password = NEW_PASS + "#"
+
+    def handle_state_change(self, ami, event):
+        state = event['state']
+
+        logger.info("handle_state_change: %s" % state)
+
+        if state == 'AUTHENTICATED':
+            logger.error("Received authentication event after NEWUSER?")
+            self.change_state(FailureTestState(self.controller))
+        elif state == 'INTRO':
+            self.change_state(IntroTestState(self.controller,
+                              self.voice_mail_test))
+        elif state == 'PASSWORDCHANGED':
+            message = event.get('message')
+            if (message == "secret.conf updated with new password"):
+                self.voice_mail_test.set_test_condition("passwordChanged",
+                                                        True)
+        elif state == 'PLAYBACK':
+            message = event.get('message')
+            logger.info("playback: %s" % message)
+
+            if message == 'vm-options':
+                if (self.voice_mail_test.get_test_condition(
+                        "passwordChanged")):
+                    """ Exit the menu """
+                    self.change_state(IntroTestState(
+                        self.controller, self.voice_mail_test))
+                    self.voice_mail_test.send_dtmf("*")
+                else:
+                    """ Tell it we want to change our password (5) """
+                    self.voice_mail_test.send_dtmf("5")
+            elif message == 'instructions':
+                """ Back at main menu; exit """
+                self.voice_mail_test.send_dtmf("#")
+            elif message == 'vm-newpassword':
+                self.voice_mail_test.send_dtmf(self.password)
+            elif message == 'vm-reenterpassword':
+                self.voice_mail_test.send_dtmf(self.password)
+            else:
+                self.handle_default_state(event)
+        else:
+            self.handle_default_state(event)
+
+    def get_state_name(self):
+        return "VMOPTIONS"
+
+
+class CheckVoicemailChangePassword(VoiceMailTest):
+    """
+    The TestCase class that executes the test
+    """
+
+    testParentDir = "tests/apps/voicemail"  # parent directory the test is in
+    channel = "sip/ast1/8052"  # channel to connect to that acts as vm server
+
+    def __init__(self):
+        super(CheckVoicemailChangePassword, self).__init__()
+
+        def checkTrueCondition(value, testCondition):
+            """
+            This merely passes back the value to the test condition, for
+            conditions that are merely true / false
+            """
+            return value
+
+        self.add_test_condition("passwordChanged",
+                                TestCondition(checkTrueCondition, False))
+
+        self.register_stop_observer(self.__check_voicemail_pw_settings)
+
+        self.reactor_timeout = 60
+        self.create_asterisk(2)
+
+    def __check_voicemail_pw_settings(self, result):
+        """ Checks conditions and voicemail password settings file prior to
+        shutting donw the reactor.
+
+        Keyword Arguments:
+        result              -- A twistd deferred object
+
+        Returns:
+        A twisted deferred object.
+        """
+        if not self.check_test_conditions():
+            logger.error("Test failed condition checks")
+            self.set_passed(False)
+
+        """ Verify that the password was changed """
+        config_file = ConfigFile("{0}{1}{2}".format(
+                                 self.ast[0].base,
+                                 "/var/spool/asterisk/voicemail",
+                                 "/default/{0}/secret.conf".format(MAILBOX)))
+
+        for category in config_file.categories:
+            if category.name != "general":
+                continue
+
+            for option in category.options:
+                if option[0] == "password":
+                    if option[1] == NEW_PASS:
+                        password_set = True
+                    else:
+                        logger.error("Wrong password found: Expected {0} "
+                                     "and received {1}.".format(NEW_PASS,
+                                                                option[1]))
+
+        if not password_set:
+            self.set_passed(False)
+
+    def ami_connect(self, ami):
+        super(CheckVoicemailChangePassword, self).ami_connect(ami)
+
+        """Record which AMI instance we've received and attempt to set up the
+           test controller"""
+        if (ami.id == 0):
+            self.ami_receiver = ami
+        elif (ami.id == 1):
+            self.ami_sender = ami
+            self.ast_sender = self.ast[self.ami_sender.id]
+
+        self.create_test_controller()
+        if (self.test_state_controller is not None):
+            startObject = StartVoiceMailState(self.test_state_controller, self)
+            self.test_state_controller.change_state(startObject)
+            self.test_state_controller.add_assert_handler(self.handleAssert)
+
+        """Now do specific processing on the AMI instances"""
+        if (ami.id == 0):
+
+            ami.registerEvent('UserEvent', self.user_event)
+
+        else:
+            logger.debug("Originating call to " + self.channel)
+            df = ami.originate(self.channel, "voicemailCaller", "wait", 1)
+            df.addErrback(self.handle_originate_failure)
+
+    def handleAssert(self, event):
+        """Error handler for assertions to the test state controller"""
+        self.passed = False
+        logger.error("Test Failed - Assert received")
+        logger.error("\t\t AppFunction: " + event['appfunction'])
+        logger.error("\t\t AppLine: " + event['appline'])
+        logger.error("\t\t Expression: " + event['expression'])
+
+        self.stop_reactor()
+
+    def user_event(self, ami, event):
+        """Handle user event from dialplan"""
+        if event['userevent'] == 'TestResult':
+            if event['result'] == "pass":
+                self.passed = True
+                logger.info("VoiceMail successfully exited")
+            else:
+                logger.warn("VoiceMail did not successfully exit:")
+                logger.warn("result: %s" % (event['result'],))
+                logger.warn("error: %s" % (event['error'],))
+            self.stop_reactor()
+        else:
+            return
+
+    def run(self):
+        super(CheckVoicemailChangePassword, self).run()
+        self.create_ami_factory(2)
+
+
+def main():
+    """Main entry point for test."""
+    test = CheckVoicemailChangePassword()
+    reactor.run()
+    return not test.passed
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/test-config.yaml b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/test-config.yaml
new file mode 100644
index 0000000..c110191
--- /dev/null
+++ b/tests/apps/voicemail/check_voicemail_options_change_password_spooldir/test-config.yaml
@@ -0,0 +1,22 @@
+testinfo:
+        summary: 'Test changing a password w/ passwordlocation=spooldir'
+        description: |
+            A voicemail user logs into their mailbox using voicemailmain and
+            then changes their password via DTMF menu commands. This test
+            confirms that playback of menu dialog occurs as expected for this
+            operation and also that changes to the password are stored in the
+            appropriate location in the Asterisk voicemail spool directory.
+
+properties:
+    minversion: '11.23.0'
+    dependencies:
+        - buildoption: 'TEST_FRAMEWORK'
+        - python : 'twisted'
+        - python : 'starpy'
+        - asterisk : 'app_voicemail'
+        - asterisk : 'app_senddtmf'
+        - asterisk : 'app_playback'
+        - asterisk : 'chan_sip'
+    tags:
+        - voicemail
+        - apps
diff --git a/tests/apps/voicemail/tests.yaml b/tests/apps/voicemail/tests.yaml
index ab8c116..0435f18 100644
--- a/tests/apps/voicemail/tests.yaml
+++ b/tests/apps/voicemail/tests.yaml
@@ -21,6 +21,7 @@
     - test: 'check_voicemail_options_record_name'
     - test: 'check_voicemail_options_record_temp'
     - test: 'check_voicemail_options_change_password'
+    - test: 'check_voicemail_options_change_password_spooldir'
     - test: 'check_voicemail_forward'
     - test: 'check_voicemail_forward_hangup'
     - test: 'check_voicemail_forward_with_prepend'

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I996c279e98efffe18bc6df55a395490256d560b1
Gerrit-PatchSet: 3
Gerrit-Project: testsuite
Gerrit-Branch: master
Gerrit-Owner: Jonathan R. Rose <jonathan.rose at motorolasolutions.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>



More information about the asterisk-code-review mailing list