Example #1
0
    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)
Example #2
0
    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'])
Example #3
0
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']
Example #5
0
    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)
Example #6
0
    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)
Example #8
0
    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)
Example #10
0
    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)