예제 #1
0
def get_config_values(config_path, section, default='default'):
    """
    Parse ini config file and return a dict of values.

    The provided section overrides any values in default section.
    """
    values = {}

    if not os.path.isfile(config_path):
        raise IpaUtilsException(
            'Config file not found: %s' % config_path
        )

    config = configparser.ConfigParser()

    try:
        config.read(config_path)
    except Exception:
        raise IpaUtilsException(
            'Config file format invalid.'
        )

    try:
        values.update(config.items(default))
    except Exception:
        pass

    try:
        values.update(config.items(section))
    except Exception:
        pass

    return values
예제 #2
0
def update_history_log(history_log,
                       clear=False,
                       description=None,
                       test_log=None):
    """
    Update the history log file with item.
    If clear flag is provided the log file is deleted.
    """
    if not test_log and not clear:
        raise IpaUtilsException('A test log or clear flag must be provided.')

    if clear:
        with ignored(OSError):
            os.remove(history_log)

    else:
        history_dir = os.path.dirname(history_log)
        if not os.path.isdir(history_dir):
            try:
                os.makedirs(history_dir)
            except OSError as error:
                raise IpaUtilsException('Unable to create directory: %s' %
                                        error)

        with open(history_log, 'a+') as f:
            # Using append mode creates file if it does not exist
            if description:
                description = '"%s"' % description

            out = '{} {}'.format(test_log, description or '')
            f.write(out.strip() + '\n')
예제 #3
0
def get_test_files(test_dirs):
    """
    Walk all test dirs and find all tests and test descriptions.

    Returns:
        A tuple containing a dict mapping test names to full path
        and a dict mapping test descriptions to full path.
    Raises:
        IpaUtilsException: If there are multiple test files or
            test descriptions with the same name. Or, if there is a
            name overlap with a test file and test description.
    """
    tests = {}
    descriptions = {}
    for test_dir in test_dirs:
        if not os.path.exists(test_dir):
            continue

        for root, dirs, files in os.walk(test_dir):
            test_files = fnmatch.filter(files, 'test_*.py')
            description_files = fnmatch.filter(files, 'test_*.yaml')

            for test_file in test_files:
                path = os.path.join(root, test_file)
                name, ext = test_file.split('.')
                if name not in tests:
                    tests[name] = path
                else:
                    raise IpaUtilsException(
                        'Duplicate test file name found: %s, %s'
                        % (path, tests.get(name))
                    )

            for description_file in description_files:
                path = os.path.join(root, description_file)
                name, ext = description_file.split('.')
                if name in tests:
                    raise IpaUtilsException(
                        'Test description name matches test file: %s, %s'
                        % (path, tests.get(name))
                    )
                elif name not in descriptions:
                    descriptions[name] = path
                else:
                    raise IpaUtilsException(
                        'Duplicate test description file name found: %s, %s'
                        % (path, descriptions.get(name))
                    )

    return tests, descriptions
예제 #4
0
def expand_test_files(test_dirs, names):
    """
    Expand the list of test files and test descriptions.

    The list is split on sync points and duplicates in
    each set are removed.

    Returns:
        List of test files split into sets by sync points.
    Raises:
        IpaUtilsException: If names is not a list.
    """
    if not isinstance(names, list):
        raise IpaUtilsException(
            'Names must be a list containing test names'
            ' and/or test descriptions.'
        )

    tests, descriptions = get_test_files(test_dirs)

    expanded_names = []
    for name in names:
        if name in descriptions:
            expanded_names += get_tests_from_description(
                name,
                descriptions
            )
        else:
            expanded_names.append(name)

    return parse_sync_points(expanded_names, tests)
예제 #5
0
def generate_public_ssh_key(ssh_private_key_file):
    """Generate SSH public key from private key file."""
    try:
        with open(ssh_private_key_file, "rb") as key_file:
            key = key_file.read()
    except FileNotFoundError:
        raise IpaUtilsException('SSH private key file: %s cannot be found.' %
                                ssh_private_key_file)

    try:
        private_key = serialization.load_pem_private_key(
            key, password=None, backend=default_backend())
    except ValueError:
        raise IpaUtilsException(
            'SSH private key file: %s is not a valid key file.' %
            ssh_private_key_file)

    return private_key.public_key().public_bytes(
        serialization.Encoding.OpenSSH, serialization.PublicFormat.OpenSSH)
예제 #6
0
def put_file(client, source_file, destination_file):
    """
    Copy file to instance using Paramiko client connection.
    """
    try:
        sftp_client = client.open_sftp()
        sftp_client.put(source_file, destination_file)
    except Exception as error:
        raise IpaUtilsException(
            'Error copying file to instance: {0}.'.format(error))
    finally:
        with ignored(Exception):
            sftp_client.close()
예제 #7
0
def get_yaml_config(config_path):
    """
    Load yaml config file and return dictionary.

    Todo:
        * This will need refactoring similar to the test search.
    """
    config_path = os.path.expanduser(config_path)
    if not os.path.isfile(config_path):
        raise IpaUtilsException('Config file not found: %s' % config_path)

    with open(config_path, 'r') as f:
        config = yaml.safe_load(f)
    return config
예제 #8
0
def get_public_ssh_key(ssh_private_key_file):
    """Get SSH public key from private key file."""
    pub_key = ssh_private_key_file + '.pub'

    try:
        with open(pub_key, "rb") as key_file:
            key = key_file.read()
    except FileNotFoundError:
        raise IpaUtilsException(
            'SSH public key file: {key_path} cannot be found.'.format(
                key_path=pub_key
            )
        )

    return key
예제 #9
0
def get_tests_from_description(name,
                               descriptions,
                               parsed=None):
    """
    Recursively collect all tests in test description.

    Args:
        name (str): Yaml test description file name.
        descriptions (dict): Dict of test description name
                             (key) and absolute file paths
                             (value).
        parsed (list): List of description paths which have
                       already been parsed to prevent infinte
                       recursion.
    Returns:
        A list of expanded test files.
    """
    tests = []
    if not parsed:
        parsed = []

    description = descriptions.get(name, None)
    if not description:
        raise IpaUtilsException(
            'Test description file with name: %s cannot be located.'
            % name
        )

    if description in parsed:
        return tests

    parsed.append(description)
    test_data = get_yaml_config(description)

    if 'tests' in test_data:
        tests += test_data.get('tests')

    if 'include' in test_data:
        for description_name in test_data.get('include'):
            tests += get_tests_from_description(
                description_name,
                descriptions,
                parsed
            )

    return tests
예제 #10
0
def find_test_file(name, tests):
    """
    Find test file by name, given a list of tests.

    If a specific test case is appended to test
    name, split the case and append to path.

    Raises:
        IpaUtilsException: If test file not found.
    """
    try:
        test_name, test_case = name.split('::', 1)
    except ValueError:
        test_name, test_case = name, None

    path = tests.get(test_name, None)
    if not path:
        raise IpaUtilsException('Test file with name: %s cannot be found.' %
                                test_name)

    if test_case:
        path = ''.join([path, '::', test_case])
    return path