From 7dc4f3022d1843063dce621ca09c80bb64cdb8c1 Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 1 Oct 2014 18:48:09 +0200 Subject: Improve diagnose.py reusability --- client/diagnose.py | 240 +++++++++++++++++++++++++++-------------------------- client/test.py | 10 +-- jasper.py | 6 +- 3 files changed, 130 insertions(+), 126 deletions(-) diff --git a/client/diagnose.py b/client/diagnose.py index fb19294..0483c22 100755 --- a/client/diagnose.py +++ b/client/diagnose.py @@ -1,139 +1,145 @@ -#!/usr/bin/env python2 +# -*- coding: utf-8-*- +import os +import sys import time -import re import socket -import os -import jasperpath import subprocess +import pkgutil import logging -import sys -from distutils.spawn import find_executable +if sys.version_info < (3, 3): + from distutils.spawn import find_executable +else: + from shutil import which as find_executable + +import pip.req import pip.util +import jasperpath logger = logging.getLogger(__name__) -class Diagnostics: - - """ - Set of diagnostics to be run for determining the health of the - host running Jasper - - To add new checks, add a boolean returning method with a name that starts - with `check_` - """ - - @classmethod - def check_network_connection(cls): - try: - # see if we can resolve the host name -- tells us if there is - # a DNS listening - host = socket.gethostbyname("www.google.com") - # connect to the host -- tells us if the host is actually - # reachable - socket.create_connection((host, 80), 2) - except Exception: - return False - else: - return True - - @classmethod - def check_phonetisaurus_dictionary_file(cls): - return os.path.isfile(os.path.join(jasperpath.APP_PATH, "..", - "phonetisaurus/g014b2b.fst")) - - @classmethod - def check_phonetisaurus_program(cls): - return cls.do_check_program('phonetisaurus-g2p') - - @classmethod - def check_espeak_program(cls): - return cls.do_check_program('espeak') - - @classmethod - def check_say_program(cls): - return cls.do_check_program('say') - - @classmethod - def do_check_program(cls, program): - return find_executable(program) is not None - - @classmethod - def check_all_pip_requirements_installed(cls): - distributions = pip.util.get_installed_distributions() - requirements_lines = [line.strip() for line in - open('requirements.txt').readlines()] - requirements = [name.split('==')[0] for name in - list(filter(None, requirements_lines))] - installed_packages = [pkg.project_name for pkg in list(distributions)] - missing_packages = [pkg for pkg in requirements - if pkg not in installed_packages] - if missing_packages: - logger.info("Missing packages: "+', '.join(missing_packages)) - return False - else: - return True - - @classmethod - def info_git_revision(cls): - return subprocess.check_output(['git', 'rev-parse', 'HEAD']) - - -class DiagnosticRunner: - +def check_network_connection(server="www.google.com"): + logger = logging.getLogger(__name__) + logger.debug("Checking network connection to server '%s'...", server) + try: + # see if we can resolve the host name -- tells us if there is + # a DNS listening + host = socket.gethostbyname(server) + # connect to the host -- tells us if the host is actually + # reachable + socket.create_connection((host, 80), 2) + except Exception: + logger.debug("Network connection not working") + return False + else: + logger.debug("Network connection working") + return True + + +def check_executable(executable): + logger = logging.getLogger(__name__) + logger.debug("Checking executable '%s'...", executable) + executable_path = find_executable(executable) + found = executable_path is not None + if found: + logger.debug("Executable '%s' found: '%s'", executable, + executable_path) + else: + logger.debug("Executable '%s' not found", executable) + return found + + +def check_python_import(package_or_module): + logger = logging.getLogger(__name__) + logger.debug("Checking python import '%s'...", package_or_module) + loader = pkgutil.get_loader(package_or_module) + found = loader is not None + if found: + logger.debug("Python %s '%s' found: %r", + "package" if loader.is_package(package_or_module) + else "module", package_or_module, loader.get_filename()) + else: + logger.debug("Python import '%s' not found", package_or_module) + return found + + +def get_pip_requirements(fname=os.path.join(jasperpath.LIB_PATH, + 'requirements.txt')): + logger = logging.getLogger(__name__) + if os.access(fname, os.R_OK): + reqs = list(pip.req.parse_requirements(fname)) + logger.debug("Found %d PIP requirements in file '%s'", len(reqs), + fname) + return reqs + else: + logger.debug("PIP requirements file '%s' not found or not readable", + fname) + + +def get_git_revision(): + logger = logging.getLogger(__name__) + if not check_executable('git'): + logger.warning("'git' command not found, git revision not detectable") + return None + output = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip() + if not output: + logger.warning("Couldn't detect git revision (not a git repository?)") + return None + return output + + +class DiagnosticRunner(object): """ Performs a series of checks against the system, printing the results to the console and also saving them to diagnostic.log """ - def __init__(self, diagnostics): - self.diagnostics = diagnostics + def __init__(self): + self._logger = logging.getLogger(__name__) def run(self): - self.initialize_log() - self.perform_checks() - - def perform_checks(self): - self.failed_checks = 0 - for check in self.select_methods('check'): - self.do_check(check) - for info in self.select_methods('info'): - self.get_info(info) - if self.failed_checks == 0: + self._logger.info("Starting jasper diagnostic at %s", + time.strftime("%c")) + self._logger.info("Git revision: %r", get_git_revision()) + + failed_checks = 0 + + if not check_network_connection(): + failed_checks += 1 + + for executable in ['phonetisaurus-g2p', 'espeak', 'say']: + if not check_executable(executable): + self._logger.warning("Executable '%s' is missing in $PATH", + executable) + failed_checks += 1 + + for req in get_pip_requirements(): + self._logger.debug("Checking PIP package '%s'...", req.name) + if not req.check_if_exists(): + self._logger.warning("PIP package '%s' is missing", req.name) + failed_checks += 1 + else: + self._logger.debug("PIP package '%s' found", req.name) + + for fname in [os.path.join(jasperpath.APP_PATH, os.pardir, + "phonetisaurus", "g014b2b.fst")]: + self._logger.debug("Checking file '%s'...", fname) + if not os.access(fname, os.R_OK): + self._logger.warning("File '%s' is missing", fname) + failed_checks += 1 + else: + self._logger.debug("File '%s' found", fname) + + if not failed_checks: logger.info("All checks passed") else: - logger.info("%d checks failed" % self.failed_checks) - - def select_methods(self, prefix): - def is_match(method_name): - return (callable(getattr(self.diagnostics, method_name)) and - re.match(r"\A" + prefix + "_", method_name)) - - return [method_name for method_name in dir(self.diagnostics) - if is_match(method_name)] - - def initialize_log(self): - logger.info("Starting jasper diagnostic at %s" % time.strftime("%c")) - - def get_info(self, info_name): - message = info_name.replace("info_", "").replace("_", " ") - info_method = getattr(self.diagnostics, info_name) - info = info_method() - logger.info("%s: %s" % (message, info)) - - def do_check(self, check_name): - message = check_name.replace("check_", "").replace("_", " ") - check = getattr(self.diagnostics, check_name) - if check(): - result = "OK" - else: - self.failed_checks += 1 - result = "FAILED" + logger.info("%d checks failed" % failed_checks) - logger.info("Checking %s... %s" % (message, result)) + return failed_checks if __name__ == '__main__': - logging.basicConfig(stream=sys.stdout, level=logging.INFO) - - DiagnosticRunner(Diagnostics).run() + logging.basicConfig(stream=sys.stdout) + logger = logging.getLogger() + logger.setLevel(logging.DEBUG if '--debug' in sys.argv else logging.INFO) + DiagnosticRunner().run() diff --git a/client/test.py b/client/test.py index d9ca8f5..d774eb7 100644 --- a/client/test.py +++ b/client/test.py @@ -13,8 +13,8 @@ import g2p import brain import jasperpath import tts +import diagnose from stt import TranscriptionMode -from diagnose import Diagnostics DEFAULT_PROFILE = { 'prefers_email': False, @@ -154,7 +154,7 @@ class TestModules(unittest.TestCase): inputs = [] self.runConversation(query, inputs, Time) - @unittest.skipIf(not Diagnostics.check_network_connection(), + @unittest.skipIf(not diagnose.check_network_connection(), "No internet connection") def testGmail(self): key = 'gmail_password' @@ -167,7 +167,7 @@ class TestModules(unittest.TestCase): inputs = [] self.runConversation(query, inputs, Gmail) - @unittest.skipIf(not Diagnostics.check_network_connection(), + @unittest.skipIf(not diagnose.check_network_connection(), "No internet connection") def testHN(self): from modules import HN @@ -180,7 +180,7 @@ class TestModules(unittest.TestCase): outputs = self.runConversation(query, inputs, HN) self.assertTrue("front-page articles" in outputs[1]) - @unittest.skipIf(not Diagnostics.check_network_connection(), + @unittest.skipIf(not diagnose.check_network_connection(), "No internet connection") def testNews(self): from modules import News @@ -193,7 +193,7 @@ class TestModules(unittest.TestCase): outputs = self.runConversation(query, inputs, News) self.assertTrue("top headlines" in outputs[1]) - @unittest.skipIf(not Diagnostics.check_network_connection(), + @unittest.skipIf(not diagnose.check_network_connection(), "No internet connection") def testWeather(self): from modules import Weather diff --git a/jasper.py b/jasper.py index 27a8de8..5061510 100755 --- a/jasper.py +++ b/jasper.py @@ -8,8 +8,7 @@ import logging import yaml import argparse -from client.diagnose import Diagnostics -from client import vocabcompiler, tts, stt, jasperpath +from client import vocabcompiler, tts, stt, jasperpath, diagnose # Add jasperpath.LIB_PATH to sys.path sys.path.append(jasperpath.LIB_PATH) @@ -132,8 +131,7 @@ if __name__ == "__main__": if args.debug: logger.setLevel(logging.DEBUG) - if (not args.no_network_check and - not Diagnostics.check_network_connection()): + if not args.no_network_check and not diagnose.check_network_connection(): logger.warning("Network not connected. This may prevent Jasper from " + "running properly.") -- cgit v1.3.1 From 304420fe97fe0d377e7afcb525fffecc619f7c02 Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 1 Oct 2014 19:10:45 +0200 Subject: Use diagnose module in stt.py and tts.py --- client/stt.py | 6 +++--- client/tts.py | 27 +++++++++++++++------------ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/client/stt.py b/client/stt.py index cfaced6..485f5d9 100644 --- a/client/stt.py +++ b/client/stt.py @@ -5,12 +5,12 @@ import traceback import wave import json import tempfile -import pkgutil import logging from abc import ABCMeta, abstractmethod import requests import yaml import jasperpath +import diagnose """ The default Speech-to-Text implementation which relies on PocketSphinx. @@ -171,7 +171,7 @@ class PocketSphinxSTT(AbstractSTTEngine): @classmethod def is_available(cls): - return (pkgutil.get_loader('pocketsphinx') is not None) + return diagnose.check_python_import('pocketsphinx') """ Speech-To-Text implementation which relies on the Google Speech API. @@ -274,7 +274,7 @@ class GoogleSTT(AbstractSTTEngine): @classmethod def is_available(cls): - return True + return diagnose.check_network_connection() """ Returns a Speech-To-Text engine. diff --git a/client/tts.py b/client/tts.py index 244c0f4..d570b26 100644 --- a/client/tts.py +++ b/client/tts.py @@ -15,18 +15,19 @@ import tempfile import subprocess import pipes import logging +import wave from abc import ABCMeta, abstractmethod -from distutils.spawn import find_executable import argparse - -import wave +import yaml try: import mad import gtts except ImportError: pass +import diagnose + class AbstractTTSEngine(object): """ @@ -37,7 +38,7 @@ class AbstractTTSEngine(object): @classmethod @abstractmethod def is_available(cls): - return (find_executable('aplay') is not None) + return diagnose.check_executable('aplay') def __init__(self, **kwargs): self._logger = logging.getLogger(__name__) @@ -67,7 +68,7 @@ class AbstractMp3TTSEngine(AbstractTTSEngine): @classmethod def is_available(cls): return (super(AbstractMp3TTSEngine, cls).is_available() and - 'mad' in sys.modules.keys()) + diagnose.check_python_import('mad')) def play_mp3(self, filename): mf = mad.MadFile(filename) @@ -123,7 +124,7 @@ class EspeakTTS(AbstractTTSEngine): @classmethod def is_available(cls): return (super(cls, cls).is_available() and - find_executable('espeak') is not None) + diagnose.check_executable('espeak')) def say(self, phrase): self._logger.debug("Saying '%s' with '%s'", phrase, self.SLUG) @@ -158,8 +159,9 @@ class FestivalTTS(AbstractTTSEngine): @classmethod def is_available(cls): if (super(cls, cls).is_available() and - find_executable('text2wave') is not None and - find_executable('festival') is not None): + diagnose.check_executable('text2wave') and + diagnose.check_executable('festival')): + logger = logging.getLogger(__name__) cmd = ['festival', '--pipe'] with tempfile.SpooledTemporaryFile() as out_f: @@ -205,8 +207,8 @@ class MacOSXTTS(AbstractTTSEngine): @classmethod def is_available(cls): return (platform.system() == 'darwin' and - find_executable('say') is not None and - find_executable('afplay') is not None) + diagnose.check_executable('say') and + diagnose.check_executable('afplay')) def say(self, phrase): self._logger.debug("Saying '%s' with '%s'", phrase, self.SLUG) @@ -247,7 +249,7 @@ class PicoTTS(AbstractTTSEngine): @classmethod def is_available(cls): return (super(cls, cls).is_available() and - find_executable('pico2wave') is not None) + diagnose.check_executable('pico2wave')) @property def languages(self): @@ -303,7 +305,8 @@ class GoogleTTS(AbstractMp3TTSEngine): @classmethod def is_available(cls): return (super(cls, cls).is_available() and - 'gtts' in sys.modules.keys()) + diagnose.check_python_import('gtts') and + diagnose.check_network_connection()) @property def languages(self): -- cgit v1.3.1 From fc68f5323584c8307872b02a75b76fe671f26cd4 Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 1 Oct 2014 19:22:58 +0200 Subject: Set loglevel at least to info during diagnose run and add '--diagnose' argument to jasper.py --- client/diagnose.py | 8 +++++++- jasper.py | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/client/diagnose.py b/client/diagnose.py index 0483c22..acbec5e 100755 --- a/client/diagnose.py +++ b/client/diagnose.py @@ -98,6 +98,11 @@ class DiagnosticRunner(object): self._logger = logging.getLogger(__name__) def run(self): + # Set loglevel of this module least to info + loglvl = self._logger.getEffectiveLevel() + if loglvl == logging.NOTSET or loglvl > logging.INFO: + self._logger.setLevel(logging.INFO) + self._logger.info("Starting jasper diagnostic at %s", time.strftime("%c")) self._logger.info("Git revision: %r", get_git_revision()) @@ -141,5 +146,6 @@ class DiagnosticRunner(object): if __name__ == '__main__': logging.basicConfig(stream=sys.stdout) logger = logging.getLogger() - logger.setLevel(logging.DEBUG if '--debug' in sys.argv else logging.INFO) + if '--debug' in sys.argv: + logger.setLevel(logging.DEBUG) DiagnosticRunner().run() diff --git a/jasper.py b/jasper.py index 5061510..1e3484b 100755 --- a/jasper.py +++ b/jasper.py @@ -20,6 +20,8 @@ parser.add_argument('--local', action='store_true', help='Use text input instead of a real microphone') parser.add_argument('--no-network-check', action='store_true', help='Disable the network connection check') +parser.add_argument('--diagnose', action='store_true', + help='Run diagnose and exit') parser.add_argument('--debug', action='store_true', help='Show debug messages') args = parser.parse_args() @@ -135,6 +137,11 @@ if __name__ == "__main__": logger.warning("Network not connected. This may prevent Jasper from " + "running properly.") + if args.diagnose: + diag = diagnose.DiagnosticRunner() + failed_checks = diag.run() + sys.exit(0 if not failed_checks else 1) + try: app = Jasper() except Exception: -- cgit v1.3.1 From 20ab84c617256a969a8b81ca72470d3ff871e554 Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 1 Oct 2014 19:25:09 +0200 Subject: Remove executable flag from diagnose --- client/diagnose.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 client/diagnose.py diff --git a/client/diagnose.py b/client/diagnose.py old mode 100755 new mode 100644 -- cgit v1.3.1 From c182a08f3e1578f83d9c024a9c5b404d04afec4b Mon Sep 17 00:00:00 2001 From: schneefux Date: Thu, 2 Oct 2014 15:08:23 +0200 Subject: Transform DiagnosticRunner.run() into a single function --- client/diagnose.py | 82 +++++++++++++++++++++++++----------------------------- jasper.py | 3 +- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/client/diagnose.py b/client/diagnose.py index acbec5e..b51ffc4 100644 --- a/client/diagnose.py +++ b/client/diagnose.py @@ -87,60 +87,54 @@ def get_git_revision(): return None return output - -class DiagnosticRunner(object): +def run(): """ - Performs a series of checks against the system, printing the results to the - console and also saving them to diagnostic.log + Performs a series of checks against the system and writes the results to + the logging system. """ + logger = logging.getLogger(__name__) - def __init__(self): - self._logger = logging.getLogger(__name__) + # Set loglevel of this module least to info + loglvl = logger.getEffectiveLevel() + if loglvl == logging.NOTSET or loglvl > logging.INFO: + logger.setLevel(logging.INFO) - def run(self): - # Set loglevel of this module least to info - loglvl = self._logger.getEffectiveLevel() - if loglvl == logging.NOTSET or loglvl > logging.INFO: - self._logger.setLevel(logging.INFO) + logger.info("Starting jasper diagnostic at %s" % time.strftime("%c")) + logger.info("Git revision: %r", get_git_revision()) - self._logger.info("Starting jasper diagnostic at %s", - time.strftime("%c")) - self._logger.info("Git revision: %r", get_git_revision()) + failed_checks = 0 - failed_checks = 0 + if not check_network_connection(): + failed_checks += 1 + + for executable in ['phonetisaurus-g2p', 'espeak', 'say']: + if not check_executable(executable): + logger.warning("Executable '%s' is missing in $PATH", executable) + failed_checks += 1 - if not check_network_connection(): + for req in get_pip_requirements(): + logger.debug("Checking PIP package '%s'...", req.name) + if not req.check_if_exists(): + logger.warning("PIP package '%s' is missing", req.name) failed_checks += 1 + else: + logger.debug("PIP package '%s' found", req.name) - for executable in ['phonetisaurus-g2p', 'espeak', 'say']: - if not check_executable(executable): - self._logger.warning("Executable '%s' is missing in $PATH", - executable) - failed_checks += 1 - - for req in get_pip_requirements(): - self._logger.debug("Checking PIP package '%s'...", req.name) - if not req.check_if_exists(): - self._logger.warning("PIP package '%s' is missing", req.name) - failed_checks += 1 - else: - self._logger.debug("PIP package '%s' found", req.name) - - for fname in [os.path.join(jasperpath.APP_PATH, os.pardir, - "phonetisaurus", "g014b2b.fst")]: - self._logger.debug("Checking file '%s'...", fname) - if not os.access(fname, os.R_OK): - self._logger.warning("File '%s' is missing", fname) - failed_checks += 1 - else: - self._logger.debug("File '%s' found", fname) - - if not failed_checks: - logger.info("All checks passed") + for fname in [os.path.join(jasperpath.APP_PATH, os.pardir, "phonetisaurus", + "g014b2b.fst")]: + logger.debug("Checking file '%s'...", fname) + if not os.access(fname, os.R_OK): + logger.warning("File '%s' is missing", fname) + failed_checks += 1 else: - logger.info("%d checks failed" % failed_checks) + logger.debug("File '%s' found", fname) + + if not failed_checks: + logger.info("All checks passed") + else: + logger.info("%d checks failed" % failed_checks) - return failed_checks + return failed_checks if __name__ == '__main__': @@ -148,4 +142,4 @@ if __name__ == '__main__': logger = logging.getLogger() if '--debug' in sys.argv: logger.setLevel(logging.DEBUG) - DiagnosticRunner().run() + run() diff --git a/jasper.py b/jasper.py index 1e3484b..d116ce9 100755 --- a/jasper.py +++ b/jasper.py @@ -138,8 +138,7 @@ if __name__ == "__main__": "running properly.") if args.diagnose: - diag = diagnose.DiagnosticRunner() - failed_checks = diag.run() + failed_checks = diagnose.run() sys.exit(0 if not failed_checks else 1) try: -- cgit v1.3.1 From 89d76f2a2a14e8dd7d574a2dba608b92a43210ee Mon Sep 17 00:00:00 2001 From: schneefux Date: Thu, 2 Oct 2014 15:18:21 +0200 Subject: Added docstrings to diagnose functions --- client/diagnose.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/client/diagnose.py b/client/diagnose.py index b51ffc4..df12df7 100644 --- a/client/diagnose.py +++ b/client/diagnose.py @@ -19,6 +19,16 @@ logger = logging.getLogger(__name__) def check_network_connection(server="www.google.com"): + """ + Checks if jasper can connect a network server. + + Arguments: + server -- (optional) the server to connect with (Default: + "www.google.com") + + Returns: + True or False + """ logger = logging.getLogger(__name__) logger.debug("Checking network connection to server '%s'...", server) try: @@ -37,6 +47,15 @@ def check_network_connection(server="www.google.com"): def check_executable(executable): + """ + Checks if an executable exists in $PATH. + + Arguments: + executable -- the name of the executable (e.g. "echo") + + Returns: + True or False + """ logger = logging.getLogger(__name__) logger.debug("Checking executable '%s'...", executable) executable_path = find_executable(executable) @@ -50,6 +69,15 @@ def check_executable(executable): def check_python_import(package_or_module): + """ + Checks if a python package or module is importable. + + Arguments: + package_or_module -- the package or module name to check + + Returns: + True or False + """ logger = logging.getLogger(__name__) logger.debug("Checking python import '%s'...", package_or_module) loader = pkgutil.get_loader(package_or_module) @@ -65,6 +93,17 @@ def check_python_import(package_or_module): def get_pip_requirements(fname=os.path.join(jasperpath.LIB_PATH, 'requirements.txt')): + """ + Gets the PIP requirements from a text file. If the files does not exists + or is not readable, it returns None + + Arguments: + fname -- (optional) the requirement text file (Default: + "client/requirements.txt") + + Returns: + A list of pip requirement objects or None + """ logger = logging.getLogger(__name__) if os.access(fname, os.R_OK): reqs = list(pip.req.parse_requirements(fname)) @@ -77,6 +116,13 @@ def get_pip_requirements(fname=os.path.join(jasperpath.LIB_PATH, def get_git_revision(): + """ + Gets the current git revision hash as hex string. If the git executable is + missing or git is unable to get the revision, None is returned + + Returns: + A hex string or None + """ logger = logging.getLogger(__name__) if not check_executable('git'): logger.warning("'git' command not found, git revision not detectable") @@ -87,10 +133,14 @@ def get_git_revision(): return None return output + def run(): """ Performs a series of checks against the system and writes the results to the logging system. + + Returns: + The number of failed checks as integer """ logger = logging.getLogger(__name__) -- cgit v1.3.1 From 2915c50df177767ad222db1101a9e20f76deaf01 Mon Sep 17 00:00:00 2001 From: schneefux Date: Mon, 6 Oct 2014 18:01:58 +0200 Subject: Remove unused imports from client/tts.py --- client/tts.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/tts.py b/client/tts.py index d570b26..55c33b0 100644 --- a/client/tts.py +++ b/client/tts.py @@ -10,7 +10,6 @@ Speaker methods: import os import platform import re -import sys import tempfile import subprocess import pipes @@ -19,7 +18,6 @@ import wave from abc import ABCMeta, abstractmethod import argparse -import yaml try: import mad import gtts -- cgit v1.3.1 From 68704f36d7c05e06ffdf65e2593aa296ffd3a64d Mon Sep 17 00:00:00 2001 From: schneefux Date: Mon, 6 Oct 2014 18:41:50 +0200 Subject: Add testcase for diagnose.py's python import check --- client/test.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/client/test.py b/client/test.py index d774eb7..6858700 100644 --- a/client/test.py +++ b/client/test.py @@ -107,6 +107,14 @@ class TestG2P(unittest.TestCase): self.assertEqual(g2p.translateWords(words), translations) +class TestDiagnose(unittest.TestCase): + def testPythonImportCheck(self): + # This a python stdlib module that definitely exists + self.assertTrue(diagnose.check_python_import("os")) + # I sincerly hope nobody will ever create a package with that name + self.assertFalse(diagnose.check_python_import("nonexistant_package")) + + class TestModules(unittest.TestCase): def setUp(self): @@ -267,7 +275,8 @@ if __name__ == '__main__': # Change CWD to jasperpath.LIB_PATH os.chdir(jasperpath.LIB_PATH) - test_cases = [TestBrain, TestModules, TestVocabCompiler, TestTTS] + test_cases = [TestBrain, TestModules, TestVocabCompiler, TestTTS, + TestDiagnose] if not args.light: test_cases.append(TestG2P) test_cases.append(TestMic) -- cgit v1.3.1