Пример #1
0
    def __init__(self, bus, watchdog=None):
        """Constructor

        Arguments:
            bus (event emitter): Mycroft messagebus connection
            watchdog (callable): optional watchdog function
        """
        super(SkillManager, self).__init__()
        self.bus = bus
        # Set watchdog to argument or function returning None
        self._watchdog = watchdog or (lambda: None)
        self._stop_event = Event()
        self._connected_event = Event()
        self.config = Configuration.get()
        self.upload_queue = UploadQueue()

        self.skill_loaders = {}
        self.enclosure = EnclosureAPI(bus)
        self.initial_load_complete = False
        self.num_install_retries = 0
        self.settings_downloader = SkillSettingsDownloader(self.bus)

        self.empty_skill_dirs = set()  # Save a record of empty skill dirs.

        # Statuses
        self._alive_status = False  # True after priority skills has loaded
        self._loaded_status = False  # True after all skills has loaded

        self.skill_updater = SkillUpdater()
        self._define_message_bus_events()
        self.daemon = True

        self.lang_code = self.config.get("lang", 'en-us')
        load_languages([self.lang_code, 'en-us'])
Пример #2
0
 def test_schedule_retry(self):
     """Test scheduling a retry of a failed install."""
     updater = SkillUpdater(self.message_bus_mock)
     updater._schedule_retry()
     self.assertEqual(1, updater.install_retries)
     self.assertEqual(400, updater.next_download)
     self.assertFalse(updater.default_skill_install_error)
 def test_installed_skills_path_not_virtual_env(self):
     """Test the property representing the installed skill file path."""
     with patch(self.mock_package + 'os.access') as os_patch:
         os_patch.return_value = False
         updater = SkillUpdater(self.message_bus_mock)
         self.assertEqual(path.expanduser('~/.mycroft/.mycroft-skills'),
                          updater.installed_skills_file_path)
Пример #4
0
 def test_update_download_time(self):
     """Test updating the next time a download will occur."""
     dot_msm_path = self.temp_dir.joinpath('.msm')
     dot_msm_path.touch()
     dot_msm_mtime_before = dot_msm_path.stat().st_mtime
     sleep(0.5)
     SkillUpdater(self.message_bus_mock)._update_download_time()
     dot_msm_mtime_after = dot_msm_path.stat().st_mtime
     self.assertLess(dot_msm_mtime_before, dot_msm_mtime_after)
Пример #5
0
 def test_install_or_update_local(self):
     """Test calling install_or_update with a local skill"""
     skill = self._build_mock_msm_skill_list()
     updater = SkillUpdater(self.message_bus_mock)
     updater.install_or_update(skill)
     self.assertIn('foobar', updater.installed_skills)
     skill.update.assert_called_once_with()
     skill.update_deps.assert_called_once_with()
     self.msm_mock.install.assert_not_called()
Пример #6
0
 def test_install_or_update_beta(self):
     """Test calling install_or_update with a beta skill."""
     self.msm_mock.device_skill_state['skills'][0]['beta'] = True
     skill = self._build_mock_msm_skill_list()
     skill.is_local = False
     updater = SkillUpdater(self.message_bus_mock)
     updater.install_or_update(skill)
     self.assertIn('foobar', updater.installed_skills)
     self.assertIsNone(skill.sha)
 def test_installed_skills_path_virtual_env(self):
     """Test the property representing the installed skill file path."""
     with patch(self.mock_package + 'sys', spec=True) as sys_mock:
         sys_mock.executable = 'path/to/the/virtual_env/bin/python'
         with patch(self.mock_package + 'os.access') as os_patch:
             os_patch.return_value = True
             updater = SkillUpdater(self.message_bus_mock)
             self.assertEqual('path/to/the/virtual_env/.mycroft-skills',
                              updater.installed_skills_file_path)
Пример #8
0
 def test_install_or_update_default(self):
     """Test calling install_or_update with a default skill"""
     skill = self._build_mock_msm_skill_list()
     skill.name = 'test_skill'
     skill.is_local = False
     updater = SkillUpdater(self.message_bus_mock)
     updater.install_or_update(skill)
     self.assertIn('test_skill', updater.installed_skills)
     self.assertTrue(not skill.update.called)
     self.msm_mock.install.assert_called_once_with(skill, origin='default')
Пример #9
0
 def test_post_manifest_allowed(self):
     """Test calling the skill manifest API endpoint"""
     self.msm_mock.device_skill_state = 'foo'
     with patch(self.mock_package + 'is_paired') as paired_mock:
         paired_mock.return_value = True
         with patch(self.mock_package + 'DeviceApi', spec=True) as api_mock:
             SkillUpdater(self.message_bus_mock).post_manifest()
             api_instance = api_mock.return_value
             api_instance.upload_skills_data.assert_called_once_with('foo')
         paired_mock.assert_called_once_with()
Пример #10
0
 def test_installed_skills_path_not_virtual_env(self):
     """Test the property representing the installed skill file path."""
     with patch(self.mock_package + 'os.access') as os_patch:
         os_patch.return_value = False
         updater = SkillUpdater(self.message_bus_mock)
         self.assertEqual(
             os.path.join(BaseDirectory.save_data_path('mycroft'),
                          '.mycroft-skills'),
             updater.installed_skills_file_path
         )
    def test_apply_install_or_update_quick(self):
        """Test invoking MSM to install or update skills quickly"""
        skill = self._build_mock_msm_skill_list()
        self.msm_mock.list_all_defaults.return_value = [skill]
        updater = SkillUpdater(self.message_bus_mock)
        updater._apply_install_or_update(quick=True)

        self.msm_mock.apply.assert_called_once_with(updater.install_or_update,
                                                    self.msm_mock.list(),
                                                    max_threads=20)
Пример #12
0
    def test_download_skills_not_connected(self):
        """Test the error that occurs when the device is not connected."""
        with patch(self.mock_package + 'connected') as connected_mock:
            connected_mock.return_value = False
            with patch(self.mock_package + 'time', spec=True) as time_mock:
                time_mock.return_value = 100
                updater = SkillUpdater(self.message_bus_mock)
                result = updater.update_skills()

        self.assertFalse(result)
        self.assertEqual(400, updater.next_download)
Пример #13
0
 def test_install_or_update_default_fail(self):
     """Test calling install_or_update with a failed install result"""
     skill = self._build_mock_msm_skill_list()
     skill.name = 'test_skill'
     skill.is_local = False
     self.msm_mock.install.side_effect = ValueError
     updater = SkillUpdater(self.message_bus_mock)
     with self.assertRaises(ValueError):
         updater.install_or_update(skill)
     self.assertNotIn('test_skill', updater.installed_skills)
     self.assertTrue(not skill.update.called)
     self.msm_mock.install.assert_called_once_with(skill, origin='default')
     self.assertTrue(updater.default_skill_install_error)
    def test_load_installed_skills(self):
        """Test loading a set of installed skills into an instance attribute"""
        skill_file_path = str(self.temp_dir.joinpath('.mycroft_skills'))
        with open(skill_file_path, 'w') as skill_file:
            skill_file.write('FooSkill\n')
            skill_file.write('BarSkill\n')

        patch_path = (self.mock_package +
                      'SkillUpdater.installed_skills_file_path')
        with patch(patch_path, new_callable=PropertyMock) as mock_file_path:
            mock_file_path.return_value = skill_file_path
            updater = SkillUpdater(self.message_bus_mock)
            updater._load_installed_skills()

        self.assertEqual({'FooSkill', 'BarSkill'}, updater.installed_skills)
    def test_save_installed_skills(self):
        """Test saving list of installed skills to a file."""
        skill_file_path = str(self.temp_dir.joinpath('.mycroft_skills'))
        patch_path = (self.mock_package +
                      'SkillUpdater.installed_skills_file_path')
        with patch(patch_path, new_callable=PropertyMock) as mock_file:
            mock_file.return_value = skill_file_path
            updater = SkillUpdater(self.message_bus_mock)
            updater.installed_skills = ['FooSkill', 'BarSkill']
            updater._save_installed_skills()

        with open(skill_file_path) as skill_file:
            skills = skill_file.readlines()

        self.assertListEqual(['FooSkill\n', 'BarSkill\n'], skills)
Пример #16
0
 def test_default_skill_names(self):
     """Test the property representing the list of default skills."""
     updater = SkillUpdater(self.message_bus_mock)
     self.assertIn('time', updater.default_skill_names)
     self.assertIn('weather', updater.default_skill_names)
     self.assertIn('test_skill', updater.default_skill_names)