def create_test_controller(self): """Create the test controller. This should be called once ami_receiver and ami_sender have both been set by the test derived from this class. """ if (self.ami_receiver is not None and self.ami_sender is not None): self.test_state_controller = TestStateController( self, self.ami_receiver)
def create_test_controller(self): """Create the test controller. This should be called once ami_receiver and ami_sender have both been set by the test derived from this class. """ if (self.ami_receiver is not None and self.ami_sender is not None): self.test_state_controller = TestStateController(self, self.ami_receiver)
class VoiceMailTest(TestCase): """Base class for voice mail tests that use TestStateController""" # The formats a message can be left in formats = ["ulaw", "wav", "WAV"] # The default expected channel to be used to send info to the voicemail # server default_sender_channel = "SIP/ast1-00000000" def __init__(self): """Constructor""" super(VoiceMailTest, self).__init__() self.ami_receiver = None self.ami_sender = None self.ast_sender = None self._test_conditions = {} self._previous_audio = "" self._previous_dtmf = "" self.sender_channel = VoiceMailTest.default_sender_channel self.test_state_controller = None def create_test_controller(self): """Create the test controller. This should be called once ami_receiver and ami_sender have both been set by the test derived from this class. """ if (self.ami_receiver is not None and self.ami_sender is not None): self.test_state_controller = TestStateController(self, self.ami_receiver) def hangup(self): """Hang up the current call""" if self.ast_sender is None: msg = "Attempting to send hangup to non-existant Asterisk instance" LOGGER.error(msg) failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "hangup", 1) deferred.addErrback(handle_redirect_failure) def send_dtmf(self, dtmf_to_send): """Send a DTMF signal to the voicemail server Keyword Arguments: dtmf_to_send The DTMF code to send """ LOGGER.info("Attempting to send DTMF " + dtmf_to_send) if self.ami_sender is None: LOGGER.error("Attempting to send DTMF to non-connected caller AMI") failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return if (self._previous_dtmf != dtmf_to_send): self.ami_sender.setVar(channel="", variable="DTMF_TO_SEND", value=dtmf_to_send) self._previous_dtmf = dtmf_to_send # Redirect to the DTMF extension - note that we assume that we only have # one channel to the other asterisk instance deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "sendDTMF", 1) deferred.addErrback(handle_redirect_failure) def send_sound_file(self, audio_file): """Send a sound file to the voicemail server Keyword Arguments: audio_file The local path to the file to stream """ if self.ami_sender is None: msg = "Attempting to send sound file to non-connected caller AMI" LOGGER.error(msg) failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return if (self._previous_audio != audio_file): self.ami_sender.setVar(channel="", variable="TALK_AUDIO", value=audio_file) self._previous_audio = audio_file # Redirect to the send sound file extension - note that we assume that # we only have one channel to the other asterisk instance deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "sendAudio", 1) deferred.addErrback(handle_redirect_failure) def send_sound_file_with_dtmf(self, audio_file, dtmf_to_send): """Send a sound file to the voicemail server, then send a DTMF signal Keyword Arguments: audio_file The local path to the file to stream dtmf_to_send The DTMF signal to send Note that this is necessary so that when the audio file is finished, we close the audio recording cleanly; otherwise, Asterisk will detect the end of file as a hangup """ if self.ami_sender is None: msg = "Attempting to send sound/DTMF to non-connected caller AMI" LOGGER.error(msg) failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return if (self._previous_audio != audio_file): self.ami_sender.setVar(channel="", variable="TALK_AUDIO", value=audio_file) self._previous_audio = audio_file if (self._previous_dtmf != dtmf_to_send): self.ami_sender.setVar(channel="", variable="DTMF_TO_SEND", value=dtmf_to_send) self._previous_dtmf = dtmf_to_send # Redirect to the appropriate extension - note that we assume that # we only have one channel to the other asterisk instance deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "sendAudioWithDTMF", 1) deferred.addErrback(handle_redirect_failure) def add_test_condition(self, condition_name, condition): """Add a new test condition to track Keyword Arguments: condition_name The unique name of the condition condition The TestCondition object """ self._test_conditions[condition_name] = condition def set_test_condition(self, condition_name, value): """Set a test condition to the specified value, and evalute whether or not it has passed Keyword Arguments: condition_name The unique name of the condition value The value to pass to the evaluation checker """ if condition_name in self._test_conditions.keys(): self._test_conditions[condition_name].evaluate(value) def get_test_condition(self, condition_name): """Get the current state of a test condition Keyword Arguments: condition_name The unique name of the condition Returns: True if the condition has passed; False otherwise """ if condition_name in self._test_conditions.keys(): return self._test_conditions[condition_name].current_state return False def check_test_conditions(self): """Check all test conditions Returns: True if all have passed; False if any have not """ ret_val = True for key, value in self._test_conditions.items(): if not value.current_state: LOGGER.warn("Test Condition [" + key + "] has not passed") ret_val = False return ret_val
class VoiceMailTest(TestCase): """Base class for voice mail tests that use TestStateController""" # The formats a message can be left in formats = ["ulaw", "wav", "WAV"] # The default expected channel to be used to send info to the voicemail # server default_sender_channel = "SIP/ast1-00000000" def __init__(self): """Constructor""" super(VoiceMailTest, self).__init__() self.ami_receiver = None self.ami_sender = None self.ast_sender = None self._test_conditions = {} self._previous_audio = "" self._previous_dtmf = "" self.sender_channel = VoiceMailTest.default_sender_channel self.test_state_controller = None def create_test_controller(self): """Create the test controller. This should be called once ami_receiver and ami_sender have both been set by the test derived from this class. """ if (self.ami_receiver is not None and self.ami_sender is not None): self.test_state_controller = TestStateController( self, self.ami_receiver) def hangup(self): """Hang up the current call""" if self.ast_sender is None: msg = "Attempting to send hangup to non-existant Asterisk instance" LOGGER.error(msg) failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "hangup", 1) deferred.addErrback(handle_redirect_failure) def send_dtmf(self, dtmf_to_send): """Send a DTMF signal to the voicemail server Keyword Arguments: dtmf_to_send The DTMF code to send """ LOGGER.info("Attempting to send DTMF " + dtmf_to_send) if self.ami_sender is None: LOGGER.error("Attempting to send DTMF to non-connected caller AMI") failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return if (self._previous_dtmf != dtmf_to_send): self.ami_sender.setVar(channel="", variable="DTMF_TO_SEND", value=dtmf_to_send) self._previous_dtmf = dtmf_to_send # Redirect to the DTMF extension - note that we assume that we only have # one channel to the other asterisk instance deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "sendDTMF", 1) deferred.addErrback(handle_redirect_failure) def send_sound_file(self, audio_file): """Send a sound file to the voicemail server Keyword Arguments: audio_file The local path to the file to stream """ if self.ami_sender is None: msg = "Attempting to send sound file to non-connected caller AMI" LOGGER.error(msg) failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return if (self._previous_audio != audio_file): self.ami_sender.setVar(channel="", variable="TALK_AUDIO", value=audio_file) self._previous_audio = audio_file # Redirect to the send sound file extension - note that we assume that # we only have one channel to the other asterisk instance deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "sendAudio", 1) deferred.addErrback(handle_redirect_failure) def send_sound_file_with_dtmf(self, audio_file, dtmf_to_send): """Send a sound file to the voicemail server, then send a DTMF signal Keyword Arguments: audio_file The local path to the file to stream dtmf_to_send The DTMF signal to send Note that this is necessary so that when the audio file is finished, we close the audio recording cleanly; otherwise, Asterisk will detect the end of file as a hangup """ if self.ami_sender is None: msg = "Attempting to send sound/DTMF to non-connected caller AMI" LOGGER.error(msg) failure = FailureTestState(self.condition_controller) self.test_state_controller.change_state(failure) return if (self._previous_audio != audio_file): self.ami_sender.setVar(channel="", variable="TALK_AUDIO", value=audio_file) self._previous_audio = audio_file if (self._previous_dtmf != dtmf_to_send): self.ami_sender.setVar(channel="", variable="DTMF_TO_SEND", value=dtmf_to_send) self._previous_dtmf = dtmf_to_send # Redirect to the appropriate extension - note that we assume that # we only have one channel to the other asterisk instance deferred = self.ami_sender.redirect(self.sender_channel, "voicemailCaller", "sendAudioWithDTMF", 1) deferred.addErrback(handle_redirect_failure) def add_test_condition(self, condition_name, condition): """Add a new test condition to track Keyword Arguments: condition_name The unique name of the condition condition The TestCondition object """ self._test_conditions[condition_name] = condition def set_test_condition(self, condition_name, value): """Set a test condition to the specified value, and evalute whether or not it has passed Keyword Arguments: condition_name The unique name of the condition value The value to pass to the evaluation checker """ if condition_name in self._test_conditions.keys(): self._test_conditions[condition_name].evaluate(value) def get_test_condition(self, condition_name): """Get the current state of a test condition Keyword Arguments: condition_name The unique name of the condition Returns: True if the condition has passed; False otherwise """ if condition_name in self._test_conditions.keys(): return self._test_conditions[condition_name].current_state return False def check_test_conditions(self): """Check all test conditions Returns: True if all have passed; False if any have not """ ret_val = True for key, value in self._test_conditions.items(): if not value.current_state: LOGGER.warn("Test Condition [" + key + "] has not passed") ret_val = False return ret_val