def test_create_dirs(self, m_makedirs): """ Verify if the workspace directory structure is being well created. """ # Create a new workspace ws = Workspace("workspace/root/dir", ws_name="workspace_name", log_level='log_level') # Assure directory structure is well created m_makedirs.return_value = None ws.create_dirs() for call in m_makedirs.call_args_list: assert '\'workspace/root/dir' in str(call)
def test_load_example_project(self, capsys, workspace): ws = Workspace.load_workspace(workspace) project = Project.load_project('example-project', workspace=ws) project.status() # assert that the status is printed correctly stdout = capsys.readouterr().out assert all(x in stdout for x in ['Project:', 'Vendor:', 'Version:']) assert all(x in stdout for x in ['MIME type', 'Quantity'])
def dispatch(args): if args is None: args = parse_args() # use specified workspace or default if args.workspace: ws_root = os.path.expanduser(args.workspace) else: ws_root = Workspace.DEFAULT_WORKSPACE_DIR ws = Workspace.load_workspace(ws_root) if not ws: log.error( "Could not find a 5GTANGO workspace at the specified location") exit(1) prj_root = os.path.expanduser(args.project) if args.add: # load project and add file to project.yml log.debug("Attempting to add file {}".format(args.add)) proj = Project.load_project(prj_root, ws) proj.add_file(args.add, type=args.type) elif args.remove: # load project and remove file from project.yml log.debug("Attempting to remove file {}".format(args.remove)) proj = Project.load_project(prj_root, ws) proj.remove_file(args.remove) elif args.status: # load project and show status log.debug("Attempting to show project status") proj = Project.load_project(prj_root, ws) proj.status() elif args.translate: proj = Project.load_project(prj_root, ws, translate=True) proj.translate() else: # create project log.debug("Attempting to create a new project") if args.vnfs != len(args.image_names): log.info("Number of VNFs and VNF image names don't match." " Using default image names if necessary.") if args.vnfs != len(args.image_types): log.info("Number of VNFs and VNF image types don't match." " Using default image types if necessary.") proj = Project(ws, prj_root) proj.create_prj(args) log.debug("Project created.") return proj
def test_example_project_descriptors(self, workspace): ws = Workspace.load_workspace(workspace) example_project = Project.load_project('example-project', workspace=ws) example_project.status() vnfds = example_project.get_vnfds() assert vnfds == ['tango_vnfd0.yml'] nsds = example_project.get_nsds() assert nsds == ['tango_nsd.yml']
def test_create_ws_descriptor(self, m_open, m_yaml, m_path): """ Tests the function that generates the workspace configuration file. Verify that a workspace can be created using the file generated by this function. """ # Create a new workspace ws = Workspace("workspace/root/dir", ws_name="workspace_name", log_level='log_level') # Patch file handling functions m_open.return_value = None m_open.write.return_value = None m_yaml.dump.return_value = None # Call function # ws.create_dirs() cfg_d = ws.create_files() # Assure that config file would be writen with the correct location configfile = os.path.join(ws.workspace_root, Workspace.__descriptor_name__) self.assertEqual(m_open.call_args, mock.call(configfile, 'w')) # Make sure the workspace root dir and # config file exist by patching os.path m_path.isdir.return_value = True m_path.isfile.return_value = True # Patch yaml.load to return the previously obtained configuration m_yaml.load.return_value = cfg_d # Call function new_ws = Workspace.load_workspace(ws.workspace_root) # Assert returned workspace configuration is equal to the previous self.assertEqual(ws, new_ws)
def test___init__(self): """ Verify variable assignments in init function :return: """ # Create a new workspace ws = Workspace("workspace/root/dir", ws_name="workspace_name", log_level='log_level') # Verify its properties self.assertEqual(ws.workspace_root, "workspace/root/dir") self.assertEqual(ws.workspace_name, "workspace_name") self.assertEqual(ws.log_level, "log_level")
def __init__(self, workspace, prj_root, config=None): # be able to hanlde different workspace inputs if workspace is None or isinstance(workspace, str): # workspace is a string # treat it as path and auto-load workspace = Workspace.load_workspace(workspace) self._prj_root = prj_root self._workspace = workspace self.error_msg = None if config: self._prj_config = config else: self.load_default_config() # get config from workspace for URL->MIME mapping with open(workspace.config["projects_config"], 'r') as config_file: self.type_mapping = yaml.load(config_file, Loader=yaml.FullLoader)
def __init__(self, workspace=None): # by default all the tests are performed self._workspace = workspace self._syntax = True self._integrity = True self._topology = True self._custom = False # Variable to delete, only to check custom rules errors self._customErrors = [] # create "virtual" workspace if not provided (don't actually create # file structure) if not self._workspace: self._workspace = Workspace('.', log_level='info') # load configurations from workspace self._dext = self._workspace.default_descriptor_extension self._dpath = '.' self._log_level = self._workspace.log_level self._cfile = '.' self._workspace_path = os.path.expanduser('~/.tng-workspace/') # # for package signature validation # self._pkg_signature = None # self._pkg_pubkey = None # # # configure logs # coloredlogs.install(level=self._log_level) # descriptors storage self._storage = DescriptorStorage() # syntax validation self._schema_validator = SchemaValidator(self._workspace, preload=True) # reset event logger evtlog.reset() # ANTON: what's this? self.source_id = None # forwarding graphs of the NS which is going to be validated self._fwgraphs = dict() pass
def load_project(prj_root, workspace=None, translate=False): # load default workspace if none specified if workspace is None: workspace = Workspace.load_workspace( Workspace.DEFAULT_WORKSPACE_DIR) # check if project manifest exists prj_filename = os.path.join(prj_root, Project.__descriptor_name__) if not os.path.isdir(prj_root) or not os.path.isfile(prj_filename): log.error( "Unable to load project manifest '{}'".format(prj_filename)) return None # load project manifest log.info("Loading project '{}'".format(prj_filename)) with open(prj_filename, 'r') as prj_file: try: prj_config = yaml.load(prj_file, Loader=yaml.FullLoader) except yaml.YAMLError as exc: log.error("Error parsing descriptor file: {0}".format(exc)) return if not prj_config: log.error( "Couldn't read descriptor file: '{0}'".format(prj_file)) return # create a new project object with the same manifest if prj_config['version'] == Project.CONFIG_VERSION: return Project(workspace, prj_root, config=prj_config) # deal with different versions if prj_config['version'] < Project.CONFIG_VERSION and not translate: log.warning( "Project version {} is outdated (current: {}). To translate to new 5GTANGO project version use " "--translate".format(prj_config['version'], Project.CONFIG_VERSION)) if prj_config['version'] > Project.CONFIG_VERSION: log.warning( "Project version {} is ahead of the current version {}.". format(prj_config['version'], Project.CONFIG_VERSION)) return Project(workspace, prj_root, config=prj_config)
def test__create_from_descriptor__(self, m_path, m_open, m_yaml, m_log): """ Perform several tests to the static function "__create_from_descriptor__" to ensure that workspaces are correctly created from a configuration descriptor" """ # Make sure the workspace root dir and # config file do not exist by patching os.path m_path.join.return_value = None m_path.isdir.return_value = False m_path.isfile.return_value = False # Assure that None is returned using # non-existent root dir and config file self.assertEqual(Workspace.load_workspace("/test"), None) # Assure that an error message was logged self.assertTrue(m_log.error.called) # Make the root dir and config file exist m_path.isdir.return_value = True m_path.isfile.return_value = True # Create an invalid config descriptor for workspace conf_d = { 'version': Workspace.CONFIG_VERSION, 'service_platforms': { 'sp1': { 'url': 'http://sp.int3.sonata-nfv.eu:32001', 'credentials:': { 'username': '******', 'password': '******', 'token_file': 'token.txt' } } }, 'default_service_platform': 'sp1', 'default_descriptor_extension': 'yml', 'schemas_local_master': '~/.son-schema', 'schemas_remote_master': 'https://raw.githubusercontent.com/' 'sonata-nfv/son-schema/master/', 'platforms_dir': 'platforms', 'catalogues_dir': 'catalogues', 'configuration_dir': 'configuration', 'projects_dir': 'projects', 'validate_watch': '~/.tng-workspace/projects' } # Feed this descriptor as a config file # by patching os.open and yaml.load methods m_open.return_value = None m_yaml.load.return_value = conf_d # Ensure it raises error when loading incomplete config descriptor self.assertTrue(m_log.error.called) # Complete config descriptor conf_d['name'] = 'test workspace config' conf_d['log_level'] = 'info' # Ensure that a valid Workspace object is returned self.assertIsInstance(Workspace.load_workspace(None), Workspace)