Эх сурвалжийг харах

Merge pull request #122 from kalliope-project/tests_monf

Tests monf
Nicolas Marcq 8 жил өмнө
parent
commit
d490a585d4

+ 4 - 0
.travis.yml

@@ -12,3 +12,7 @@ before_install:
 install: "pip install -r install/files/python_requirements.txt"
 # command to run tests
 script: pytest
+# CodeCLimate for test coveragek
+addons:
+    code_climate:
+        repo_token: 8d4355b7655d8a91daa72132c587a03cee644e78dfcdd86562551b4ea992b61e

+ 115 - 0
Tests/test_launchers.py

@@ -0,0 +1,115 @@
+import unittest
+import mock
+import os
+
+from kalliope.core.NeuronLauncher import NeuronLauncher
+from kalliope.core.SynapseLauncher import SynapseLauncher, SynapseNameNotFound
+from kalliope.core.TriggerLauncher import TriggerLauncher
+
+from kalliope.core.Models.Trigger import Trigger
+from kalliope.core.Models.Neuron import Neuron
+from kalliope.core.Models.Order import Order
+from kalliope.core.Models.Brain import Brain
+from kalliope.core.Models.Synapse import Synapse
+
+
+class TestLaunchers(unittest.TestCase):
+    """
+    Class to test Launchers Classes (TriggerLauncher, SynapseLauncher, NeuronLauncher) and methods
+    """
+
+    def setUp(self):
+        pass
+
+    ####
+    # Trigger Launcher
+    def test_get_trigger(self):
+        """
+        Test the Trigger Launcher trying to run the trigger
+        """
+        trigger = Trigger("Trigger", {})
+        with mock.patch("kalliope.core.Utils.get_dynamic_class_instantiation") as mock_get_class_instantiation:
+            TriggerLauncher.get_trigger(trigger=trigger,
+                                        callback=None)
+
+            mock_get_class_instantiation.assert_called_once_with("trigger",
+                                                                 trigger.name.capitalize(),
+                                                                 trigger.parameters)
+            mock_get_class_instantiation.reset_mock()
+
+    ####
+    # Synapse Launcher
+    def test_start_synapse(self):
+        """
+        Test the Synapse launcher trying to start synapse
+        """
+        # Init
+        neuron1 = Neuron(name='neurone1', parameters={'var1': 'val1'})
+        neuron2 = Neuron(name='neurone2', parameters={'var2': 'val2'})
+        neuron3 = Neuron(name='neurone3', parameters={'var3': 'val3'})
+        neuron4 = Neuron(name='neurone4', parameters={'var4': 'val4'})
+
+        signal1 = Order(sentence="this is the sentence")
+        signal2 = Order(sentence="this is the second sentence")
+        signal3 = Order(sentence="that is part of the third sentence")
+
+        synapse1 = Synapse(name="Synapse1", neurons=[neuron1, neuron2], signals=[signal1])
+        synapse2 = Synapse(name="Synapse2", neurons=[neuron3, neuron4], signals=[signal2])
+        synapse3 = Synapse(name="Synapse3", neurons=[neuron2, neuron4], signals=[signal3])
+
+        all_synapse_list = [synapse1,
+                            synapse2,
+                            synapse3]
+
+        br = Brain(synapses=all_synapse_list)
+
+        with mock.patch("kalliope.core.Utils.get_dynamic_class_instantiation") as mock_get_class_instantiation:
+            # Success
+            SynapseLauncher.start_synapse("Synapse1", brain=br)
+
+            calls = [mock.call("neurons", neuron1.name.capitalize(), neuron1.parameters),
+                     mock.call("neurons", neuron2.name.capitalize(), neuron2.parameters)]
+            mock_get_class_instantiation.assert_has_calls(calls=calls)
+            mock_get_class_instantiation.reset_mock()
+
+            # Fail
+            with self.assertRaises(SynapseNameNotFound):
+                SynapseLauncher.start_synapse("Synapse4", brain=br)
+
+    def test_run_synapse(self):
+        """
+        Test to run a Synapse
+        """
+        neuron1 = Neuron(name='neurone1', parameters={'var1': 'val1'})
+        neuron2 = Neuron(name='neurone2', parameters={'var2': 'val2'})
+        signal1 = Order(sentence="this is the sentence")
+        synapse1 = Synapse(name="Synapse1", neurons=[neuron1, neuron2], signals=[signal1])
+        synapse_empty = Synapse(name="Synapse_empty", neurons=[], signals=[signal1])
+        with mock.patch("kalliope.core.Utils.get_dynamic_class_instantiation") as mock_get_class_instantiation:
+            SynapseLauncher._run_synapse(synapse=synapse1)
+
+            calls = [mock.call("neurons",neuron1.name.capitalize(),neuron1.parameters),
+                     mock.call("neurons",neuron2.name.capitalize(),neuron2.parameters)]
+            mock_get_class_instantiation.assert_has_calls(calls=calls)
+            mock_get_class_instantiation.reset_mock()
+
+            # Do not any Neurons
+            SynapseLauncher._run_synapse(synapse=synapse_empty)
+            mock_get_class_instantiation.assert_not_called()
+            mock_get_class_instantiation.reset_mock()
+
+    ####
+    # Neurons Launcher
+    def test_start_neuron(self):
+        """
+        Test the Neuron Launcher trying to start a Neuron
+        """
+        neuron = Neuron(name='neurone1', parameters={'var1': 'val1'})
+        with mock.patch("kalliope.core.Utils.get_dynamic_class_instantiation") as mock_get_class_instantiation:
+            NeuronLauncher.start_neuron(neuron=neuron)
+
+            mock_get_class_instantiation.assert_called_once_with("neurons",
+                                                                 neuron.name.capitalize(),
+                                                                 neuron.parameters)
+            mock_get_class_instantiation.reset_mock()
+

+ 0 - 2
Tests/test_rest_api.py

@@ -1,8 +1,6 @@
-import json
 import os
 import unittest
 
-import requests
 from flask import Flask
 from flask_testing import LiveServerTestCase
 

+ 2 - 2
Tests/test_tts_module.py

@@ -59,7 +59,7 @@ class TestTTSModule(unittest.TestCase):
 
             # test missing callback
             with self.assertRaises(TtsGenerateAudioFunctionNotFound):
-                self.assertRaises(self.TTSMod.generate_and_play(words=words))
+                self.TTSMod.generate_and_play(words=words)
 
             # Assert Callback is called
             # no Cache
@@ -124,4 +124,4 @@ class TestTTSModule(unittest.TestCase):
                          "Fail asserting that the file does not exist.")
 
 if __name__ == '__main__':
-    unittest.main()
+    unittest.main()

+ 131 - 0
Tests/test_utils.py

@@ -0,0 +1,131 @@
+import unittest
+import os
+
+from kalliope.core.Models.Neuron import Neuron
+from kalliope.neurons.say.say import Say
+from kalliope.core.Utils.Utils import Utils
+
+
+class TestUtils(unittest.TestCase):
+    """
+    Class to test Utils methods
+    """
+
+    def setUp(self):
+        pass
+
+    def test_get_current_file_parent_path(self):
+        """
+        Expect to get back the parent path file
+        """
+        path_to_test = "../kalliope/core/Utils"
+        expected_result = os.path.normpath("../kalliope/core")
+
+        self.assertEquals(Utils.get_current_file_parent_path(path_to_test),
+                          expected_result,
+                          "fail getting the parent parent path from the given path")
+
+    def test_get_current_file_parent_parent_path(self):
+        """
+        Expect to get back the parent parent path file
+        """
+        path_to_test = "../kalliope/core/Utils"
+        expected_result = os.path.normpath("../kalliope")
+
+        self.assertEquals(Utils.get_current_file_parent_parent_path(path_to_test),
+                          expected_result,
+                          "fail getting the parent parent path from the given path")
+
+    def test_get_real_file_path(self):
+        """
+        Expect to load the proper file following the order :
+            - Provided absolute path
+            - Current user path + file_name
+            - /etc/kalliope + file_name
+            - /path/to/kalliope/ +file_name
+        """
+        ###
+        # Test the absolute path
+        dir_path = "/tmp/kalliope/tests/"
+        file_name = "test_real_file_path"
+        absolute_path_to_test = os.path.join(dir_path,file_name)
+        expected_result = absolute_path_to_test
+        if not os.path.exists(dir_path):
+            os.makedirs(dir_path)
+
+        # touch the file
+        open(absolute_path_to_test, 'a').close()
+
+        self.assertEquals(Utils.get_real_file_path(absolute_path_to_test),
+                          expected_result,
+                          "Fail to match the given absolute path ")
+        # Clean up
+        if os.path.exists(absolute_path_to_test):
+            os.remove(absolute_path_to_test)
+
+        ###
+        # test the Current path
+        file_name = "test_real_file_path"
+        expected_result = os.getcwd() + os.sep + file_name
+
+        # touch the file
+        open(file_name, 'a').close()
+
+        self.assertEquals(Utils.get_real_file_path(file_name),
+                          expected_result,
+                          "Fail to match the Current path ")
+        # Clean up
+        if os.path.exists(file_name):
+            os.remove(file_name)
+
+        ###
+        # test /etc/kalliope
+        # /!\ need permissions
+        # dir_path = "/etc/kalliope/"
+        # file_name = "test_real_file_path"
+        # path_to_test = os.path.join(dir_path,file_name)
+        # expected_result = "/etc/kalliope" + os.sep + file_name
+        # if not os.path.exists(dir_path):
+        #     os.makedirs(dir_path)
+        #
+        # # touch the file
+        # open(path_to_test, 'a').close()
+        #
+        # self.assertEquals(Utils.get_real_file_path(file_name),
+        #                   expected_result,
+        #                   "Fail to match the /etc/kalliope path")
+        # # Clean up
+        # if os.path.exists(file_name):
+        #     os.remove(file_name)
+
+        ###
+        # /an/unknown/path/kalliope/
+        dir_path = "../kalliope/"
+        file_name = "test_real_file_path"
+        path_to_test = os.path.join(dir_path, file_name)
+        expected_result = os.path.normpath(os.getcwd() + os.sep + os.pardir + os.sep +"kalliope" + os.sep + file_name)
+        if not os.path.exists(dir_path):
+            os.makedirs(dir_path)
+
+        # touch the file
+        open(path_to_test, 'a').close()
+
+        self.assertEquals(Utils.get_real_file_path(file_name),
+                          expected_result,
+                          "Fail to match the /an/unknown/path/kalliope path")
+        # Clean up
+        if os.path.exists(file_name):
+            os.remove(file_name)
+
+    def test_get_dynamic_class_instantiation(self):
+        """
+        Test that an instance as been instantiate properly.
+        """
+
+        neuron = Neuron(name='Say', parameters={'message': 'test dynamic class instantiate'})
+        self.assertTrue(isinstance(Utils.get_dynamic_class_instantiation("neurons",
+                                                                         neuron.name.capitalize(),
+                                                                         neuron.parameters),
+                                   Say),
+                        "Fail instantiate a class")
+

+ 3 - 3
kalliope/core/ConfigurationManager/BrainLoader.py

@@ -3,7 +3,7 @@ import logging
 import os
 
 from YAMLLoader import YAMLLoader
-from kalliope.core.ConfigurationManager import utils
+from kalliope.core.Utils import Utils
 from kalliope.core.ConfigurationManager.ConfigurationChecker import ConfigurationChecker
 from kalliope.core.Models import Singleton
 from kalliope.core.Models.Brain import Brain
@@ -31,9 +31,9 @@ class BrainLoader(object):
     def __init__(self, file_path=None):
         self.file_path = file_path
         if self.file_path is None:  # we don't provide a file path, so search for the default one
-            self.file_path = utils.get_real_file_path(FILE_NAME)
+            self.file_path = Utils.get_real_file_path(FILE_NAME)
         else:
-            self.file_path = utils.get_real_file_path(file_path)
+            self.file_path = Utils.get_real_file_path(file_path)
         # if the returned file path is none, the file doesn't exist
         if self.file_path is None:
             raise BrainNotFound("brain file not found")

+ 3 - 3
kalliope/core/ConfigurationManager/SettingLoader.py

@@ -1,7 +1,7 @@
 import logging
 
 from YAMLLoader import YAMLLoader
-from kalliope.core.ConfigurationManager import utils
+from kalliope.core.Utils import Utils
 from kalliope.core.Models import Singleton
 from kalliope.core.Models.RestAPI import RestAPI
 from kalliope.core.Models.Settings import Settings
@@ -52,9 +52,9 @@ class SettingLoader(object):
     def __init__(self, file_path=None):
         self.file_path = file_path
         if self.file_path is None:
-            self.file_path = utils.get_real_file_path(FILE_NAME)
+            self.file_path = Utils.get_real_file_path(FILE_NAME)
         else:
-            self.file_path = utils.get_real_file_path(file_path)
+            self.file_path = Utils.get_real_file_path(file_path)
         # if the returned file path is none, the file doesn't exist
         if self.file_path is None:
             raise SettingNotFound("Settings.yml file not found")

+ 0 - 51
kalliope/core/ConfigurationManager/utils.py

@@ -1,51 +0,0 @@
-import inspect
-import logging
-import os
-
-logging.basicConfig()
-logger = logging.getLogger("kalliope")
-
-
-def get_root_kalliope_path():
-    # here we are in /an/unknown/path/kalliope/core/ConfigurationManager
-    current_script_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
-    # get parent dir. Now we are in /an/unknown/path/kalliope
-    kalliope_root_path = os.path.normpath(current_script_path + os.sep + os.pardir + os.sep + os.pardir)
-    return kalliope_root_path
-
-
-def get_real_file_path(file_path_to_test):
-    """
-    Try to return a full path from a given <file_path_to_test>
-    If the path is an absolute on, we return it directly.
-
-    If the path is relative, we try to get the full path in this order:
-    - from the current directory where kalliope has been called + the file_path_to_test.
-    Eg: /home/me/Documents/kalliope_config
-    - from /etc/kalliope + file_path_to_test
-    - from the default file passed as <file_name> at the root of the project
-
-    :param file_path_to_test file path to test
-    :type file_path_to_test: str
-    :return: absolute path to the file file_path_to_test or None if is doen't exist
-    """
-
-    if not os.path.isabs(file_path_to_test):
-        path_order = {
-            1: os.getcwd() + os.sep + file_path_to_test,
-            2: "/etc/kalliope" + os.sep + file_path_to_test,
-            3: get_root_kalliope_path() + os.sep + file_path_to_test
-        }
-
-        for key in sorted(path_order):
-            new_file_path_to_test = path_order[key]
-            logger.debug("Try to load file from %s: %s" % (key, new_file_path_to_test))
-            if os.path.isfile(new_file_path_to_test):
-                logger.debug("File found in %s" % new_file_path_to_test)
-                return new_file_path_to_test
-
-    else:
-        if os.path.isfile(file_path_to_test):
-            return file_path_to_test
-        else:
-            return None

+ 3 - 1
kalliope/core/NeuronLauncher.py

@@ -20,4 +20,6 @@ class NeuronLauncher:
         :return:
         """
         logger.debug("Run plugin \"%s\" with parameters %s" % (neuron.name, neuron.parameters))
-        return Utils.get_dynamic_class_instantiation("neurons", neuron.name.capitalize(), neuron.parameters)
+        return Utils.get_dynamic_class_instantiation("neurons",
+                                                     neuron.name.capitalize(),
+                                                     neuron.parameters)

+ 2 - 1
kalliope/core/TriggerLauncher.py

@@ -23,5 +23,6 @@ class TriggerLauncher(object):
         # add the callback method to parameters
         trigger.parameters["callback"] = callback
         logger.debug("TriggerLauncher: Start trigger %s with parameters: %s" % (trigger.name, trigger.parameters))
-        return Utils.get_dynamic_class_instantiation("trigger", trigger.name.capitalize(),
+        return Utils.get_dynamic_class_instantiation("trigger",
+                                                     trigger.name.capitalize(),
                                                      trigger.parameters)

+ 2 - 4
kalliope/core/TriggerModule.py

@@ -1,8 +1,6 @@
-import os
-
 import logging
 
-from kalliope.core.ConfigurationManager import utils
+from kalliope.core.Utils import Utils
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
@@ -29,4 +27,4 @@ class TriggerModule(object):
 
         :return: absolute path
         """
-        return utils.get_real_file_path(file_path)
+        return Utils.get_real_file_path(file_path)

+ 75 - 8
kalliope/core/Utils/Utils.py

@@ -1,4 +1,6 @@
 import logging
+import os
+import inspect
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
@@ -26,6 +28,11 @@ class Utils(object):
         UNDERLINE='\033[4m'
     )
 
+    ##################
+    #
+    # Shell properly displayed
+    #
+    #########
     @classmethod
     def print_info(cls, text_to_print):
         print cls.color_list["BLUE"] + text_to_print + cls.color_list["ENDLINE"]
@@ -58,8 +65,23 @@ class Utils(object):
     def print_underline(cls, text_to_print):
         print cls.color_list["UNDERLINE"] + text_to_print + cls.color_list["ENDLINE"]
 
-    @classmethod
-    def get_dynamic_class_instantiation(cls, package_name, module_name, parameters=None):
+    @staticmethod
+    def print_yaml_nicely(to_print):
+        """
+        Used for debug
+        :param to_print: Dict to print nicely
+        :return:
+        """
+        import json
+        print json.dumps(to_print, indent=2)
+
+    ##################
+    #
+    # Dynamic loading
+    #
+    #########
+    @staticmethod
+    def get_dynamic_class_instantiation(package_name, module_name, parameters=None):
         """
         Load a python class dynamically
 
@@ -91,12 +113,57 @@ class Utils(object):
                 return klass(parameters)
         return None
 
+    ##################
+    #
+    # Paths management
+    #
+    #########
+    @staticmethod
+    def get_current_file_parent_parent_path(current_script_path):
+        parent_parent_path = os.path.normpath(current_script_path + os.sep + os.pardir + os.sep + os.pardir)
+        return parent_parent_path
+
+    @staticmethod
+    def get_current_file_parent_path(current_script_path):
+        parent_path = os.path.normpath(current_script_path + os.sep + os.pardir)
+        return parent_path
+
     @classmethod
-    def print_yaml_nicely(cls, to_print):
+    def get_real_file_path(cls, file_path_to_test):
         """
-        Used for debug
-        :param to_print: Dict to print nicely
-        :return:
+        Try to return a full path from a given <file_path_to_test>
+        If the path is an absolute on, we return it directly.
+
+        If the path is relative, we try to get the full path in this order:
+        - from the current directory where kalliope has been called + the file_path_to_test.
+        Eg: /home/me/Documents/kalliope_config
+        - from /etc/kalliope + file_path_to_test
+        - from the default file passed as <file_name> at the root of the project
+
+        :param file_path_to_test file path to test
+        :type file_path_to_test: str
+        :return: absolute path to the file file_path_to_test or None if is doen't exist
         """
-        import json
-        print json.dumps(to_print, indent=2)
+
+        if not os.path.isabs(file_path_to_test):
+            current_script_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+            path_order = {
+                1: os.getcwd() + os.sep + file_path_to_test,
+                2: "/etc/kalliope" + os.sep + file_path_to_test,
+                # In this case 'get_current_file_parent_parent_path' is corresponding to kalliope root path
+                # from /an/unknown/path/kalliope/kalliope/core/Utils to /an/unknown/path/kalliope/kalliope
+                3: cls.get_current_file_parent_parent_path(current_script_path) + os.sep + file_path_to_test
+            }
+
+            for key in sorted(path_order):
+                new_file_path_to_test = path_order[key]
+                logger.debug("Try to load file from %s: %s" % (key, new_file_path_to_test))
+                if os.path.isfile(new_file_path_to_test):
+                    logger.debug("File found in %s" % new_file_path_to_test)
+                    return new_file_path_to_test
+
+        else:
+            if os.path.isfile(file_path_to_test):
+                return file_path_to_test
+            else:
+                return None

+ 2 - 2
kalliope/neurons/twitter/twitter.py

@@ -1,6 +1,6 @@
 import twitter
 
-from kalliope.core.NeuronModule import NeuronModule, InvalidParameterException, MissingParameterException
+from kalliope.core.NeuronModule import NeuronModule, MissingParameterException
 
 
 class Twitter(NeuronModule):
@@ -33,7 +33,7 @@ class Twitter(NeuronModule):
         Check if received parameters are ok to perform operations in the neuron
         :return: true if parameters are ok, raise an exception otherwise
 
-        .. raises:: InvalidParameterException
+        .. raises:: MissingParameterException
         """
         if self.consumer_key is None:
             raise MissingParameterException("Twitter needs a consumer_key")