Beispiel #1
0
    def run(self, ctx):
        for env in self.envs0:
            ctx.env[env] = '0'
        for env in self.envs1:
            ctx.env[env] = '1'

        file_path = ctx.create_holey_file(16 * t.MiB, 'testfile')
        ctx.env['PMEM_LOG_LEVEL'] = '15'
        ctx.exec(
            'pmem_eADR_functions',
            self.test_case,
            file_path,
        )

        regex1 = F"{self.function_name}_mov_{self.isa}_noflush"
        regex2 = F"{self.function_name}_movnt_{self.isa}" \
                 F"_empty{self.perfbarrier}"
        regex3 = F"{self.function_name}_mov_{self.isa}_empty"
        regex = F"({regex1})|({regex2})|({regex3})"

        log_file = self.get_log_file_by_prefix("pmem")
        log_content = open(log_file).read()
        match = re.search(regex, log_content)

        if match is None:
            futils.fail(F"Failed to find any occurrence of "
                        F"{self.function_name}"
                        F" with eADR in pmem_{self.testnum}.log")
Beispiel #2
0
    def _run_match(self):
        """Match log files"""
        cwd_listdir = [path.join(self.cwd, f) for f in os.listdir(self.cwd)]

        suffix = '{}.log.match'.format(self.testnum)

        def is_matchfile(f):
            """Match file ends with specific suffix and a char before suffix
            is not a digit"""
            before_suffix = -len(suffix) - 1
            return path.isfile(f) and f.endswith(suffix) and \
                not f[before_suffix].isdigit()

        match_files = filter(is_matchfile, cwd_listdir)
        prefix = 'perl ' if sys.platform == 'win32' else ''
        match_cmd = prefix + path.join(futils.ROOTDIR, 'match')

        for mf in match_files:
            cmd = '{} {}'.format(match_cmd, mf)
            proc = sp.run(cmd.split(), stdout=sp.PIPE, cwd=self.cwd,
                          stderr=sp.STDOUT, universal_newlines=True)
            if proc.returncode != 0:
                futils.fail(proc.stdout, exit_code=proc.returncode)
            else:
                self.msg.print_verbose(proc.stdout)
Beispiel #3
0
    def run(self, ctx):
        file_path = ctx.create_holey_file(16 * t.MiB, 'testfile')
        ctx.env['PMEM2_LOG_LEVEL'] = '15'
        ctx.exec('pmem2_future', self.test_case, file_path, self.size)

        log_file = self.get_log_file_by_prefix("pmem2")
        log_content = open(log_file).read()

        # We do not do any checks if the granularity is byte because
        # in the case vdm instances do not have to call
        # anything in order to persist the memory.
        if isinstance(ctx.granularity, g.CacheLine):
            regex = "((pmem2_drain)|(memory_barrier))"
            matches = re.findall(regex, log_content)
            expected = ["pmem2_drain", "memory_barrier"]

            # We expect matches of:
            # [pmem2_drain, memory_barrier] because calling pmem2_memcpy_async
            # should ensure persistence by calling pmem2_drain and
            # memory_barrier after that.
            if check_match(matches, expected) is not True:
                futils.fail(F"Failed to find exact match to "
                            F"pmem2_drain+memory_barrier call!"
                            F"Got {matches} instead.")
        elif isinstance(ctx.granularity, g.Page):
            regex = "pmem2_log_flush"
            matches = re.findall(regex, log_content)

            # We expect exactly one call of pmem2_log_flush which should
            # be called by pmem2_memcpy_async
            if len(matches) != 1:
                futils.fail(F"Failed to find exactly one "
                            F"pmem2_log_flush call! "
                            F"Got {len(matches)} instead.")
Beispiel #4
0
    def _run_match(self):
        """Match log files"""
        cwd_listdir = [path.join(self.cwd, f) for f in os.listdir(self.cwd)]

        suffix = '{}.log.match'.format(self.testnum)

        def is_matchfile(f):
            """Match file ends with specific suffix and a char before suffix
            is not a digit"""
            before_suffix = -len(suffix) - 1
            return path.isfile(f) and f.endswith(suffix) and \
                not f[before_suffix].isdigit()

        match_files = filter(is_matchfile, cwd_listdir)
        prefix = 'perl ' if sys.platform == 'win32' else ''
        match_cmd = prefix + path.join(futils.ROOTDIR, 'match')

        for mf in match_files:
            cmd = '{} {}'.format(match_cmd, mf)
            proc = sp.run(cmd.split(),
                          stdout=sp.PIPE,
                          cwd=self.cwd,
                          stderr=sp.STDOUT,
                          universal_newlines=True)
            if proc.returncode != 0:
                futils.fail(proc.stdout, exit_code=proc.returncode)
            else:
                self.msg.print_verbose(proc.stdout)
Beispiel #5
0
 def get_size(self, path):
     """
     Returns size of the file or dax device.
     Value "2**64 - 1" is checked because pmemdetect in case of error prints it.
     """
     proc = tools.pmemdetect(self, '-z', path)
     if int(proc.stdout) != 2**64 - 1:
         return int(proc.stdout)
     futils.fail('Could not get size of the file, it is inaccessible or does not exist')
Beispiel #6
0
 def get_size(self, path):
     """
     Returns size of the file or dax device.
     Value "2**64 - 1" is checked because pmemdetect in case of error prints it.
     """
     proc = tools.pmemdetect(self, '-z', path)
     if int(proc.stdout) != 2**64 - 1:
         return int(proc.stdout)
     futils.fail('Could not get size of the file, it is inaccessible or does not exist')
Beispiel #7
0
 def set_parts(self, *parts):
     """
     Adds a main pool to the poolset file.
     The function accepts a list of Parts of any length.
     Should not be called more than once.
     """
     if not self.parts:
         self.parts = list(parts)
     else:
         futils.fail('This function should not be called more than once.')
Beispiel #8
0
 def supports_map_sync(self, path):
     """Checks if MAP_SYNC is supported on a filesystem from given path"""
     proc = tools.pmemdetect(self, '-s', path)
     if proc.returncode == tools.PMEMDETECT_ERROR:
         futils.fail(proc.stdout)
     if proc.returncode == tools.PMEMDETECT_TRUE:
         return True
     if proc.returncode == tools.PMEMDETECT_FALSE:
         return False
     futils.fail('Unknown value {} returned by pmemdetect'.format(proc.returncode))
Beispiel #9
0
 def is_devdax(self, path):
     """Checks if given path points to device dax"""
     proc = tools.pmemdetect(self, '-d', path)
     if proc.returncode == tools.PMEMDETECT_ERROR:
         futils.fail(proc.stdout)
     if proc.returncode == tools.PMEMDETECT_TRUE:
         return True
     if proc.returncode == tools.PMEMDETECT_FALSE:
         return False
     futils.fail('Unknown value {} returned by pmemdetect'.format(proc.returncode))
Beispiel #10
0
 def supports_map_sync(self, path):
     """Checks if MAP_SYNC is supported on a filesystem from given path"""
     proc = tools.pmemdetect(self, '-s', path)
     if proc.returncode == tools.PMEMDETECT_ERROR:
         futils.fail(proc.stdout)
     if proc.returncode == tools.PMEMDETECT_TRUE:
         return True
     if proc.returncode == tools.PMEMDETECT_FALSE:
         return False
     futils.fail('Unknown value {} returned by pmemdetect'.format(proc.returncode))
Beispiel #11
0
 def is_devdax(self, path):
     """Checks if given path points to device dax"""
     proc = tools.pmemdetect(self, '-d', path)
     if proc.returncode == tools.PMEMDETECT_ERROR:
         futils.fail(proc.stdout)
     if proc.returncode == tools.PMEMDETECT_TRUE:
         return True
     if proc.returncode == tools.PMEMDETECT_FALSE:
         return False
     futils.fail('Unknown value {} returned by pmemdetect'.format(proc.returncode))
Beispiel #12
0
 def set_parts(self, *parts):
     """
     Adds a main pool to the poolset file.
     The function accepts a list of Parts of any length.
     Should not be called more than once.
     """
     if not self.parts:
         self.parts = list(parts)
     else:
         futils.fail('This function should not be called more than once.')
Beispiel #13
0
    def exec(self, cmd, *args, expected_exitcode=0, stderr_file=None):
        """Execute binary in current test context"""

        tmp = self._env.copy()
        futils.add_env_common(tmp, os.environ.copy())

        # change cmd into list for supbrocess type compliance
        cmd = [
            cmd,
        ]

        if sys.platform == 'win32':
            cmd[0] = os.path.join(self.build.exedir, cmd[0]) + '.exe'
        else:
            cmd[0] = os.path.join(self.cwd, cmd[0]) + \
                self.build.exesuffix

            if self.valgrind:
                cmd = self.valgrind.cmd + cmd

        # cast all provided args to strings (required by subprocess run())
        # so that exec() can accept args of any printable type
        cmd.extend([str(a) for a in args])

        if self.conf.tracer:
            cmd = shlex.split(self.conf.tracer) + cmd

            # process stdout and stderr are not redirected - this lets running
            # tracer command in an interactive session
            proc = sp.run(cmd, env=tmp, cwd=self.cwd)
        else:
            if stderr_file:
                f = open(os.path.join(self.cwd, stderr_file), 'w')

            # let's create a dictionary of arguments to the run func
            run_kwargs = {
                'env': tmp,
                'cwd': self.cwd,
                'timeout': self.conf.timeout,
                'stdout': sp.PIPE,
                'universal_newlines': True,
                'stderr': sp.STDOUT if stderr_file is None else f
            }

            proc = sp.run(cmd, **run_kwargs)

            if stderr_file:
                f.close()

        if expected_exitcode is not None and \
           proc.returncode != expected_exitcode:
            futils.fail(proc.stdout, exit_code=proc.returncode)

        self.msg.print_verbose(proc.stdout)
Beispiel #14
0
    def exec(self, cmd, *args, expected_exit=0):
        """Execute binary in current test context"""

        env = {**self.env, **os.environ.copy(), **self.test.utenv}

        # change cmd into list for supbrocess type compliance
        cmd = [
            cmd,
        ]

        if sys.platform == 'win32':
            env['PATH'] = self.build.libdir + os.pathsep +\
                envconfig['GLOBAL_LIB_PATH'] + os.pathsep +\
                env.get('PATH', '')
            cmd[0] = os.path.join(self.build.exedir, cmd[0]) + '.exe'

        else:
            if self.test.ld_preload:
                env['LD_PRELOAD'] = env.get('LD_PRELOAD', '') + os.pathsep +\
                    self.test.ld_preload
                self.valgrind.handle_ld_preload(self.test.ld_preload)
            env['LD_LIBRARY_PATH'] = self.build.libdir + os.pathsep +\
                envconfig['GLOBAL_LIB_PATH'] + os.pathsep +\
                env.get('LD_LIBRARY_PATH', '')
            cmd[0] = os.path.join(self.test.cwd, cmd[0]) + self.build.exesuffix

            if self.valgrind:
                cmd = self.valgrind.cmd + cmd

        cmd = cmd + list(args)

        if self.conf.tracer:
            cmd = shlex.split(self.conf.tracer) + cmd

            # process stdout and stderr are not redirected - this lets running
            # tracer command in interactive session
            proc = sp.run(cmd, env=env, cwd=self.test.cwd)
        else:
            proc = sp.run(cmd,
                          env=env,
                          cwd=self.test.cwd,
                          timeout=self.conf.timeout,
                          stdout=sp.PIPE,
                          stderr=sp.STDOUT,
                          universal_newlines=True)

        if proc.returncode != expected_exit:
            futils.fail(proc.stdout, exit_code=proc.returncode)

        if sys.platform != 'win32' and expected_exit == 0 \
                and not self.valgrind.validate_log():
            futils.fail(proc.stdout)

        self.msg.print_verbose(proc.stdout)
Beispiel #15
0
 def _check_pools_size(self):
     """"
     Validate if pool and replicas have more than 8MiB (minimum pool size).
     This function does not validate remote replicas sizes.
     """
     size = 0
     for part in self.parts:
         size += part.size
     if size < POOL_MIN_SIZE:
         futils.fail('The pool has to have at least 8 MiB')
     for replica in self.replicas:
         size = 0
         for part in replica:
             size += part.size
         if size < POOL_MIN_SIZE:
             futils.fail('The pool has to have at least 8 MiB')
Beispiel #16
0
 def _check_pools_size(self):
     """"
     Validate if pool and replicas have more than 8MiB (minimum pool size).
     This function does not validate remote replicas sizes.
     """
     size = 0
     for part in self.parts:
         size += part.size
     if size < POOL_MIN_SIZE:
         futils.fail('The pool has to have at least 8 MiB')
     for replica in self.replicas:
         size = 0
         for part in replica:
             size += part.size
         if size < POOL_MIN_SIZE:
             futils.fail('The pool has to have at least 8 MiB')
Beispiel #17
0
    def exec(self, cmd, *args, expected_exitcode=0):
        """Execute binary in current test context"""

        tmp = self._env.copy()
        futils.add_env_common(tmp, os.environ.copy())

        # change cmd into list for supbrocess type compliance
        cmd = [
            cmd,
        ]

        if sys.platform == 'win32':
            cmd[0] = os.path.join(self.build.exedir, cmd[0]) + '.exe'
        else:
            cmd[0] = os.path.join(self.cwd, cmd[0]) + \
                self.build.exesuffix

            if self.valgrind:
                cmd = self.valgrind.cmd + cmd

        # cast all provided args to strings (required by subprocess run())
        # so that exec() can accept args of any printable type
        cmd.extend([str(a) for a in args])

        if self.conf.tracer:
            cmd = shlex.split(self.conf.tracer) + cmd

            # process stdout and stderr are not redirected - this lets running
            # tracer command in an interactive session
            proc = sp.run(cmd, env=tmp, cwd=self.cwd)
        else:
            proc = sp.run(cmd,
                          env=tmp,
                          cwd=self.cwd,
                          timeout=self.conf.timeout,
                          stdout=sp.PIPE,
                          stderr=sp.STDOUT,
                          universal_newlines=True)

        if expected_exitcode is not None and \
           proc.returncode != expected_exitcode:
            futils.fail(proc.stdout, exit_code=proc.returncode)

        self.msg.print_verbose(proc.stdout)
Beispiel #18
0
    def create(self):
        """
        Create a poolset file with basic space validation. If CREATE arguments
        ware passed to parts, create parts files as well.
        """
        self._check_pools_size()
        required_size = self._get_required_size()
        free_space = ctx.get_free_space()
        if required_size > free_space:
            futils.fail(
                'Not enough space available to create parts files. There is '
                '{}, and poolset requires {}'.format(free_space,
                                                     required_size))

        for part in self.parts:
            part._process(self.ctx)
        for replica in self.replicas:
            for part in replica:
                part._process(self.ctx)

        self.options = list(set(self.options))

        poolsetpath = os.path.join(self.ctx.testdir, self.path)
        with open(poolsetpath, 'w') as poolset:
            print('PMEMPOOLSET', end='\n\n', file=poolset)

            for option in self.options:
                print('OPTION', option, end='\n\n', file=poolset)

            for part in self.parts:
                print(part, file=poolset)
            print(file=poolset)

            for replica in self.replicas:
                print("REPLICA", file=poolset)
                for part in replica:
                    print(part, file=poolset)
                print(file=poolset)

            for remote in self.remote:
                print("REPLICA", remote[1], remote[0], file=poolset)
Beispiel #19
0
    def exec(self, cmd, *args, expected_exit=0):
        """Execute binary in current test context"""
        cmd_args = ' '.join(args) if args else ''

        env = {**self.env, **os.environ.copy(), **self.test.utenv}

        if sys.platform == 'win32':
            env['PATH'] = self.build.libdir + os.pathsep +\
                envconfig['GLOBAL_LIB_PATH'] + os.pathsep +\
                env.get('PATH', '')
            cmd = os.path.join(self.build.exedir, cmd) + '.exe'

        else:
            if self.test.ld_preload:
                env['LD_PRELOAD'] = env.get('LD_PRELOAD', '') + os.pathsep +\
                    self.test.ld_preload
                self.valgrind.handle_ld_preload(self.test.ld_preload)
            env['LD_LIBRARY_PATH'] = self.build.libdir + os.pathsep +\
                envconfig['GLOBAL_LIB_PATH'] + os.pathsep +\
                env.get('LD_LIBRARY_PATH', '')
            cmd = os.path.join(self.test.cwd, cmd) + self.build.exesuffix
            cmd = '{} {}'.format(self.valgrind.cmd, cmd)

        cmd = '{} {}'.format(cmd, cmd_args)
        proc = sp.run(cmd,
                      env=env,
                      cwd=self.test.cwd,
                      shell=True,
                      timeout=self.conf.timeout,
                      stdout=sp.PIPE,
                      stderr=sp.STDOUT,
                      universal_newlines=True)

        if sys.platform != 'win32' and expected_exit == 0 \
                and not self.valgrind.validate_log():
            self.test.fail(proc.stdout)

        if proc.returncode != expected_exit:
            futils.fail(proc.stdout, exit_code=proc.returncode)
        else:
            self.msg.print_verbose(proc.stdout)
Beispiel #20
0
    def create(self):
        """
        Create a poolset file with basic space validation. If CREATE arguments
        ware passed to parts, create parts files as well.
        """
        self._check_pools_size()
        required_size = self._get_required_size()
        free_space = ctx.get_free_space()
        if required_size > free_space:
            futils.fail('Not enough space available to create parts files. There is '
                 '{}, and poolset requires {}'.format(free_space,
                                                      required_size))

        for part in self.parts:
            part._process(self.ctx)
        for replica in self.replicas:
            for part in replica:
                part._process(self.ctx)

        self.options = list(set(self.options))

        poolsetpath = os.path.join(self.ctx.testdir, self.path)
        with open(poolsetpath, 'w') as poolset:
            print('PMEMPOOLSET', end='\n\n', file=poolset)

            for option in self.options:
                print('OPTION', option, end='\n\n', file=poolset)

            for part in self.parts:
                print(part, file=poolset)
            print(file=poolset)

            for replica in self.replicas:
                print("REPLICA", file=poolset)
                for part in replica:
                    print(part, file=poolset)
                print(file=poolset)

            for remote in self.remote:
                print("REPLICA", remote[1], remote[0], file=poolset)
Beispiel #21
0
    def exec(self, cmd, *args, expected_exit=0):
        """Execute binary in current test context"""
        cmd_args = ' '.join(args) if args else ''

        env = {**self.env, **os.environ.copy(), **self.test.utenv}

        if sys.platform == 'win32':
            env['PATH'] = self.build.libdir + os.pathsep +\
                envconfig['GLOBAL_LIB_PATH'] + os.pathsep +\
                env.get('PATH', '')
            cmd = os.path.join(self.build.exedir, cmd) + '.exe'

        else:
            if self.test.ld_preload:
                env['LD_PRELOAD'] = env.get('LD_PRELOAD', '') + os.pathsep +\
                    self.test.ld_preload
                self.valgrind.handle_ld_preload(self.test.ld_preload)
            env['LD_LIBRARY_PATH'] = self.build.libdir + os.pathsep +\
                envconfig['GLOBAL_LIB_PATH'] + os.pathsep +\
                env.get('LD_LIBRARY_PATH', '')
            cmd = os.path.join(self.test.cwd, cmd) + self.build.exesuffix
            cmd = '{} {}'.format(self.valgrind.cmd, cmd)

        cmd = '{} {}'.format(cmd, cmd_args)
        proc = sp.run(cmd, env=env, cwd=self.test.cwd, shell=True,
                      timeout=self.conf.timeout, stdout=sp.PIPE,
                      stderr=sp.STDOUT, universal_newlines=True)

        if sys.platform != 'win32' and expected_exit == 0 \
                and not self.valgrind.validate_log():
            self.test.fail(proc.stdout)

        if proc.returncode != expected_exit:
            futils.fail(proc.stdout, exit_code=proc.returncode)
        else:
            self.msg.print_verbose(proc.stdout)
Beispiel #22
0
    def __init__(self):
        if sys.platform == 'win32':
            futils.fail('ndctl is not available on Windows')

        self.version = self._get_ndctl_version()
        self.ndctl_list_output = self._cmd_out_to_json('list', '-RBNDMv')
Beispiel #23
0
 def __init__(self, path, size):
     if size < PART_MIN_SIZE:
         futils.fail('The part should have at least 2 MiB')
     self.size = size
     self.path = path
Beispiel #24
0
    def exec(self, cmd, *args, expected_exitcode=0, stderr_file=None,
             stdout_file=None):
        """
        Execute binary in the current test context as a separate process.

        Execution takes place in test cwd and uses environment variables
        stored in Context 'env' attribute. Timeout for the execution
        is set based on the execution configuration.

        Args:
            cmd (str): command to be executed
            *args: Variable length command arguments list
            expected_exitcode (int): if process exit code differs from
                expected, Fail is thrown. Defaults to 0. Ignored
                if set to None.
            stderr_file (str): path to file in which stderr output is
                stored. Stored in a string if None. Defaults to None.
            stdout_file (str): path to file in which stdout output is
                stored. Stored in a string if None. Defaults to None.

            If neither stderr_file nor stdout_file are set, both outputs
            are merged into single stdout output and stored in a string.
        """

        tmp = self._env.copy()
        futils.add_env_common(tmp, os.environ.copy())

        # change cmd into list for supbrocess type compliance
        cmd = [cmd, ]

        if sys.platform == 'win32':
            cmd[0] = os.path.join(self.build.exedir, cmd[0]) + '.exe'
        else:
            cmd[0] = os.path.join(self.cwd, cmd[0]) + \
                self.build.exesuffix

            if self.valgrind:
                cmd = self.valgrind.cmd + cmd

        # cast all provided args to strings (required by subprocess run())
        # so that exec() can accept args of any printable type
        cmd.extend([str(a) for a in args])

        if self.conf.tracer:
            cmd = shlex.split(self.conf.tracer) + cmd

            # process stdout and stderr are not redirected - this lets running
            # tracer command in an interactive session
            proc = sp.run(cmd, env=tmp, cwd=self.cwd)
        else:
            if stderr_file:
                f = open(os.path.join(self.cwd, stderr_file), 'w')

            # let's create a dictionary of arguments to the run func
            run_kwargs = {
                'env': tmp,
                'cwd': self.cwd,
                'timeout': self.conf.timeout,
                'stdout': sp.PIPE,
                'universal_newlines': True,
                'stderr': sp.STDOUT if stderr_file is None else f}

            proc = sp.run(cmd, **run_kwargs)

            if stderr_file:
                f.close()

        if expected_exitcode is not None and \
           proc.returncode != expected_exitcode:
            futils.fail(proc.stdout, exit_code=proc.returncode)

        if stdout_file is not None:
            with open(os.path.join(self.cwd, stdout_file), 'w') as f:
                f.write(proc.stdout)

        self.msg.print_verbose(proc.stdout)
Beispiel #25
0
 def __init__(self, ctx, path):
     if not ctx.is_devdax(path):
         futils.fail('Part with path "{}" does not point to dax device'
              ''.format(path))
     _Part.__init__(self, path, ctx.get_size(path))
 def __init__(self):
     if sys.platform != 'win32':
         futils.fail('Ipmctl tool class is currently implemented only'
                     ' for Windows - for Linux use ndctl instead')
Beispiel #27
0
 def __init__(self, ctx, path):
     if not ctx.is_devdax(path):
         futils.fail('Part with path "{}" does not point to dax device'
                     ''.format(path))
     _Part.__init__(self, path, ctx.get_size(path))
Beispiel #28
0
 def __init__(self, path, size):
     if size < PART_MIN_SIZE:
         futils.fail('The part should have at least 2 MiB')
     self.size = size
     self.path = path