def test_update(self): """Remove a skill Test that the remove method was called on the skill being installed and that the new skill was removed from the device's skill state. """ skill_to_update = self.skill_entry_mock() skill_to_update.name = 'skill-foo' skill_to_update.is_beta = False pre_install_hash = device_skill_state_hash(self.msm.device_skill_state) with patch('msm.mycroft_skills_manager.time') as time_mock: time_mock.time.return_value = 100 self.msm.update(skill_to_update) with open(self.skills_json_path) as skills_json: device_skill_state = json.load(skills_json) skill_names = [skill['name'] for skill in device_skill_state['skills']] self.assertIn('skill-foo', skill_names) for skill in self.msm.device_skill_state['skills']: if skill['name'] == 'skill-foo': self.assertEqual(100, skill['updated']) self.assertListEqual([call.update()], skill_to_update.method_calls) self.assertNotIn('all_skills', self.msm._cache) self.assertIsNone(self.msm._local_skills) post_install_hash = device_skill_state_hash( self.msm.device_skill_state) self.assertNotEqual(pre_install_hash, post_install_hash)
def test_remove(self): """Remove a skill Test that the remove method was called on the skill being installed and that the new skill was removed from the device's skill state. """ skill_to_remove = self.skill_entry_mock() skill_to_remove.name = 'skill-foo' pre_install_hash = device_skill_state_hash(self.msm.device_skill_state) with patch('msm.mycroft_skills_manager.isinstance') as isinstance_mock: isinstance_mock.return_value = True self.msm.remove(skill_to_remove) with open(self.skills_json_path) as skills_json: device_skill_state = json.load(skills_json) skill_names = [skill['name'] for skill in device_skill_state['skills']] self.assertNotIn('skill_foo', skill_names) skill_names = [ skill['name'] for skill in self.msm.device_skill_state['skills'] ] self.assertNotIn('skill_foo', skill_names) self.assertListEqual([call.remove()], skill_to_remove.method_calls) self.assertNotIn('all_skills', self.msm._cache) self.assertIsNone(self.msm._local_skills) post_install_hash = device_skill_state_hash( self.msm.device_skill_state) self.assertNotEqual(pre_install_hash, post_install_hash)
def test_device_skill_state(self): """Contents of skills.json are loaded into memory""" state = self.msm.device_skill_state initial_state = [ dict(name='skill-foo', origin='default', beta=False, status='active', installed=12345, updated=0, installation='installed', skill_gid='@|skill-foo'), dict(name='skill-bar', origin='default', beta=False, status='active', installed=23456, updated=0, installation='installed', skill_gid='@|skill-bar') ] self.assertListEqual(initial_state, state['skills']) self.assertListEqual([], state['blacklist']) self.assertEqual(2, state['version']) new_hash = device_skill_state_hash(self.msm.device_skill_state) self.assertEqual(new_hash, self.msm.device_skill_state_hash)
def test_already_removed(self): """Attempt removal of skill already removed from the device. When this happens, an AlreadyRemoved exception is raised and the device skill state is not modified. """ skill_to_remove = self.skill_entry_mock() skill_to_remove.name = 'skill-foo' skill_to_remove.remove = Mock(side_effect=AlreadyRemoved()) pre_install_hash = device_skill_state_hash(self.msm.device_skill_state) with patch('msm.mycroft_skills_manager.isinstance') as isinstance_mock: isinstance_mock.return_value = True self.msm.remove(skill_to_remove) self.assertListEqual([call.remove()], skill_to_remove.method_calls) self.assertIsNotNone(self.msm._local_skills) self.assertIn('all_skills', self.msm._cache) post_install_hash = device_skill_state_hash( self.msm.device_skill_state) self.assertEqual(pre_install_hash, post_install_hash)
def test_remove_failure(self): """Skill removal attempt fails for whatever reason When n removal fails, a MsmException is raised. The removal will not be saved to the device skill state. """ skill_to_remove = self.skill_entry_mock() skill_to_remove.name = 'skill-test' skill_to_remove.remove = Mock(side_effect=MsmException('RED ALERT!')) pre_install_hash = device_skill_state_hash(self.msm.device_skill_state) with patch('msm.mycroft_skills_manager.isinstance') as isinstance_mock: isinstance_mock.return_value = True with self.assertRaises(MsmException): self.msm.remove(skill_to_remove) self.assertListEqual([call.remove()], skill_to_remove.method_calls) self.assertIsNotNone(self.msm._local_skills) self.assertIn('all_skills', self.msm._cache) post_install_hash = device_skill_state_hash( self.msm.device_skill_state) self.assertEqual(pre_install_hash, post_install_hash)
def _init_skills_data(self): """Initial load of the skill state that occurs upon instantiation. If the skills state was upgraded after it was loaded, write the updated skills state to disk. """ try: del (self.device_skill_state['upgraded']) except KeyError: self.device_skill_state_hash = device_skill_state_hash( self.device_skill_state) else: self.write_device_skill_state()
def test_already_installed(self): """Attempt install of skill already on the device. When this happens, an AlreadyInstalled exception is raised and the device skill state is not modified. """ skill_to_install = self.skill_entry_mock() skill_to_install.name = 'skill-foo' skill_to_install.skill_gid = 'skill-foo|99.99' skill_to_install.is_beta = False skill_to_install.install = Mock(side_effect=AlreadyInstalled()) pre_install_hash = device_skill_state_hash(self.msm.device_skill_state) with patch('msm.mycroft_skills_manager.isinstance') as isinstance_mock: isinstance_mock.return_value = True with self.assertRaises(AlreadyInstalled): self.msm.install(skill_to_install) self.assertIsNotNone(self.msm._local_skills) self.assertIn('all_skills', self.msm._cache) post_install_hash = device_skill_state_hash( self.msm.device_skill_state) self.assertEqual(pre_install_hash, post_install_hash)
def test_build_device_skill_state(self): """No skill.json file so build one.""" os.remove(str(self.skills_json_path)) self.msm._device_skill_state = None self.msm._init_skills_data() state = self.msm.device_skill_state initial_state = [ dict(name='skill-bar', origin='non-msm', beta=False, status='active', installed=0, updated=0, installation='installed', skill_gid='@|skill-bar'), dict(name='skill-foo', origin='non-msm', beta=False, status='active', installed=0, updated=0, installation='installed', skill_gid='@|skill-foo') ] self.assertTrue(self.skills_json_path.exists()) with open(str(self.skills_json_path)) as skills_json: device_skill_state = json.load(skills_json) self.assertListEqual( sorted(initial_state, key=lambda x: x['name']), sorted(device_skill_state['skills'], key=lambda x: x['name'])) self.assertListEqual( sorted(initial_state, key=lambda x: x['name']), sorted(device_skill_state['skills'], key=lambda x: x['name'])) self.assertListEqual([], state['blacklist']) self.assertListEqual([], device_skill_state['blacklist']) self.assertEqual(2, state['version']) self.assertEqual(2, device_skill_state['version']) new_hash = device_skill_state_hash(self.msm.device_skill_state) self.assertEqual(new_hash, self.msm.device_skill_state_hash)
def write_device_skill_state(self, data=None): """Write device's skill state to disk if it has been modified.""" data = data or self.device_skill_state if device_skill_state_hash(data) != self.device_skill_state_hash: write_device_skill_state(data) self.device_skill_state_hash = device_skill_state_hash(data)