def setUp(self): """Execute steps before each tests.""" self.napp = NApp(username='******', name='napp', version='1.0', repository='any') self.napp.description = 'desc' self.napp.tags = ['tag1', 'tag2']
def enable(self, napp_uri): """Enable a NApp if not already enabled. Raises: FileNotFoundError: If NApp is not installed. PermissionError: No filesystem permission to enable NApp. """ napp = NApp.create_from_uri(napp_uri) enabled = self._enabled / napp.username / napp.name installed = self._installed / napp.username / napp.name if not installed.is_dir(): log.error("Failed to enable NApp %s. NApp not installed.", napp.id) elif not enabled.exists(): self._create_module(enabled.parent) try: # Create symlink enabled.symlink_to(installed) if self._controller is not None: self._controller.load_napp(napp.username, napp.name) log.info("NApp enabled: %s", napp.id) except FileExistsError: pass # OK, NApp was already enabled except PermissionError: log.error("Failed to enable NApp %s. Permission denied.", napp.id)
def get_napps_from_path(path: Path): """List all NApps found in ``napps_dir``.""" if not path.exists(): LOG.warning("NApps dir (%s) doesn't exist.", path) return [] jsons = path.glob('*/*/kytos.json') return [NApp.create_from_json(j) for j in jsons]
def _list_all(napps_dir): """List all NApps found in ``napps_dir``.""" if not napps_dir.exists(): log.warning("NApps dir (%s) doesn't exist.", napps_dir) return [] jsons = napps_dir.glob('*/*/kytos.json') return [NApp.create_from_json(j) for j in jsons]
def test_create_from_uri(self): """Test create_from_uri method.""" napp = NApp.create_from_uri('file://any/kytos/napp:1.0') self.assertEqual(napp.username, 'kytos') self.assertEqual(napp.name, 'napp') self.assertEqual(napp.version, '1.0') self.assertEqual(napp.repository, 'file://any')
def disable(self, napp_uri): """Disable a NApp if it is enabled.""" napp = NApp.create_from_uri(napp_uri) enabled = self._enabled / napp.username / napp.name try: enabled.unlink() log.info("NApp disabled: %s", napp.id) if self._controller is not None: self._controller.unload_napp(napp.username, napp.name) except FileNotFoundError: pass # OK, it was already disabled
def test_create_from_dict(self): """Test create_from_dict method.""" data = { 'username': '******', 'name': 'napp', 'version': '1.0', 'repository': 'any' } napp = NApp.create_from_dict(data) self.assertEqual(napp.username, 'kytos') self.assertEqual(napp.name, 'napp') self.assertEqual(napp.version, '1.0') self.assertEqual(napp.repository, 'any')
def search(self, pattern, use_cache=False): """Search for NApps in NApp repositories matching a pattern.""" # ISSUE #347, we need to loop here over all repositories repo = eval(self._config.napps_repositories)[0] # noqa if use_cache: # ISSUE #346, we should use cache here pass result = urllib.request.urlretrieve("{}/.database".format(repo))[0] with open(result, 'r') as fp: napps_json = json.load(fp) napps = [NApp.create_from_dict(napp_json) for napp_json in napps_json] return [napp for napp in napps if napp.match(pattern)]
def install(self, napp_uri, enable=True): """Install and enable a NApp from its repository. By default, install procedure will also enable the NApp. If you only want to install and keep NApp disabled, please use enable=False. """ napp = NApp.create_from_uri(napp_uri) if napp in self.get_all_napps(): LOG.warning("Unable to install NApp %s. Already installed.", napp) return False if not napp.repository: napp.repository = self._controller.options.napps_repositories[0] pkg_folder = None try: pkg_folder = napp.download() napp_folder = self._find_napp(napp, pkg_folder) dst = self._installed_path / napp.username / napp.name self._create_module(dst.parent) shutil.move(str(napp_folder), str(dst)) finally: if pkg_folder and pkg_folder.exists(): shutil.rmtree(str(pkg_folder)) LOG.info("New NApp installed: %s", napp) napp = NApp.create_from_json(dst/'kytos.json') for uri in napp.napp_dependencies: self.install(uri, enable) if enable: return self.enable(napp.username, napp.name) return True
def test_create_from_json(self, mock_open): """Test create_from_json method.""" data_file = MagicMock() data_file.read.return_value = '{"username": "******", \ "name": "napp", \ "version": "1.0", \ "repository": "any"}' mock_open.return_value.__enter__.return_value = data_file napp = NApp.create_from_json('filename') self.assertEqual(napp.username, 'kytos') self.assertEqual(napp.name, 'napp') self.assertEqual(napp.version, '1.0') self.assertEqual(napp.repository, 'any')
def install(self, napp_uri, enable=True): """Install and enable a NApp from its repository. By default, install procedure will also enable the NApp. If you only want to install and keep NApp disabled, please use enable=False. """ napp = NApp.create_from_uri(napp_uri) if napp in self.get_all_napps(): LOG.warning("Unable to install NApp %s. Already installed.", napp) return False if not napp.repository: napp.repository = self._controller.options.napps_repositories[0] pkg_folder = None try: pkg_folder = napp.download() napp_folder = self._find_napp(napp, pkg_folder) dst = self._installed_path / napp.username / napp.name self._create_module(dst.parent) shutil.move(str(napp_folder), str(dst)) finally: if pkg_folder and pkg_folder.exists(): shutil.rmtree(str(pkg_folder)) LOG.info("New NApp installed: %s", napp) napp = NApp.create_from_json(dst / 'kytos.json') for uri in napp.napp_dependencies: self.install(uri, enable) if enable: return self.enable(napp.username, napp.name) return True
def uninstall(self, napp_uri): """Remove a NApp from filesystem, if existent.""" napp = NApp.create_from_uri(napp_uri) if self.is_enabled(napp_uri): log.warning("Unable to uninstall NApp %s. NApp currently in use.", napp) return False if self.is_installed(napp_uri): installed = self._installed / napp.username / napp.name if installed.is_symlink(): installed.unlink() else: shutil.rmtree(str(installed)) log.info("NApp uninstalled: %s", napp) else: log.warning("Unable to uninstall NApp %s. Already uninstalled.", napp) return True
def is_installed(self, username, napp_name): """Whether a NApp is installed or not on this controller.""" napp_id = "{}/{}".format(username, napp_name) napp = NApp.create_from_uri(napp_id) return napp in self.get_all_napps()
def is_installed(self, napp_uri): """Whether a NApp is installed or not on this controller.""" napp = NApp.create_from_uri(napp_uri) return napp in self.list()
def test_create_from_uri__not(self): """Test create_from_uri method when uri does not match.""" napp = NApp.create_from_uri('') self.assertIsNone(napp)
class TestNapp(unittest.TestCase): """NApp tests.""" def setUp(self): """Execute steps before each tests.""" self.napp = NApp(username='******', name='napp', version='1.0', repository='any') self.napp.description = 'desc' self.napp.tags = ['tag1', 'tag2'] def test__str__(self): """Test __str__ method.""" self.assertEqual(str(self.napp), 'kytos/napp') def test__repr__(self): """Test __repr__ method.""" self.assertEqual(repr(self.napp), f'NApp(kytos/napp)') def test_id(self): """Test id property.""" self.assertEqual(self.napp.id, 'kytos/napp') @patch('kytos.core.napps.NApp._has_valid_repository', return_value=True) def test_uri(self, _): """Test uri property.""" self.assertEqual(self.napp.uri, 'any/kytos/napp-1.0') @patch('kytos.core.napps.NApp._has_valid_repository', return_value=False) def test_uri__false(self, _): """Test uri property when repository is invalid.""" self.assertEqual(self.napp.uri, '') def test_package_url(self): """Test package_url property.""" self.assertEqual(self.napp.package_url, 'any/kytos/napp-1.0.napp') @patch('kytos.core.napps.NApp._has_valid_repository', return_value=False) def test_package_url__none(self, _): """Test package_url property when uri does not exist.""" self.assertEqual(self.napp.package_url, '') def test_create_from_uri(self): """Test create_from_uri method.""" napp = NApp.create_from_uri('file://any/kytos/napp:1.0') self.assertEqual(napp.username, 'kytos') self.assertEqual(napp.name, 'napp') self.assertEqual(napp.version, '1.0') self.assertEqual(napp.repository, 'file://any') def test_create_from_uri__not(self): """Test create_from_uri method when uri does not match.""" napp = NApp.create_from_uri('') self.assertIsNone(napp) @patch('builtins.open') def test_create_from_json(self, mock_open): """Test create_from_json method.""" data_file = MagicMock() data_file.read.return_value = '{"username": "******", \ "name": "napp", \ "version": "1.0", \ "repository": "any"}' mock_open.return_value.__enter__.return_value = data_file napp = NApp.create_from_json('filename') self.assertEqual(napp.username, 'kytos') self.assertEqual(napp.name, 'napp') self.assertEqual(napp.version, '1.0') self.assertEqual(napp.repository, 'any') def test_create_from_dict(self): """Test create_from_dict method.""" data = { 'username': '******', 'name': 'napp', 'version': '1.0', 'repository': 'any' } napp = NApp.create_from_dict(data) self.assertEqual(napp.username, 'kytos') self.assertEqual(napp.name, 'napp') self.assertEqual(napp.version, '1.0') self.assertEqual(napp.repository, 'any') def test_match(self): """Test match method.""" for pattern in ['kytos/napp', 'desc', 'tag1', 'tag2']: self.assertTrue(self.napp.match(pattern)) @patch('os.mkdir') @patch('tarfile.open') @patch('builtins.open') @patch('urllib.request.urlretrieve', return_value=['filename']) @patch('kytos.core.napps.base.randint', return_value=123) @patch('kytos.core.napps.base.Path.unlink') @patch('kytos.core.napps.base.Path.stem', 'stem') def test_download(self, *args): """Test download method.""" (_, _, _, mock_open, mock_tarfile_open, mock_mkdir) = args tar = MagicMock() repo_file = MagicMock() mock_open.return_value.__enter__.return_value = repo_file mock_tarfile_open.return_value.__enter__.return_value = tar extracted = self.napp.download() mock_mkdir.assert_called_with('/tmp/kytos-napp-stem-123') tar.extractall.assert_called_with('/tmp/kytos-napp-stem-123') repo_file.write.assert_called_with('any\n') self.assertEqual(str(extracted), '/tmp/kytos-napp-stem-123') @patch('kytos.core.napps.NApp._has_valid_repository', return_value=False) def test_download__none(self, _): """Test download method when package_url does not exist.""" extracted = self.napp.download() self.assertIsNone(extracted)