Exemple #1
0
class Test_hbw_detection(object):
    os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.dirname(__file__))
    binary_path = find_executable("memkind-hbw-nodes")
    environ_err_test = "../environ_err_hbw_malloc_test"
    expected_libnuma_warning = "libnuma: Warning: node argument -1 is out of range\n\n"
    fail_msg = "Test failed with:\n {0}"
    cmd_helper = CMD_helper()

    def get_hbw_nodes(self, nodemask=None):
        """ This function executes memkind function 'get_mbind_nodemask' and returns its output - comma separated HBW nodes """
        command = self.binary_path
        if (nodemask):
            command = "MEMKIND_HBW_NODES={}".format(nodemask) + command
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("\nError: Execution of \'{0}\' returns {1}, \noutput: {2}".format(command, retcode, output))
        print("\nExecution of {} returns output {}".format(command, output))
        return output

    def test_TC_MEMKIND_hbw_detection_compare_nodemask_default_and_env_variable(self):
        """ This test checks whether hbw_nodemask_default and hbw_nodemask_env_variable has the same value """
        hbw_nodemask_default = self.get_hbw_nodes()
        hbw_nodemask_env_variable = self.get_hbw_nodes(hbw_nodemask_default)
        assert hbw_nodemask_default == hbw_nodemask_env_variable, self.fail_msg.format("Error: Nodemask hbw_nodemask_default ({0}) " \
               "is not the same as nodemask hbw_nodemask_env_variable ({1})".format(hbw_nodemask_default, hbw_nodemask_env_variable))

    def test_TC_MEMKIND_hbw_detection_negative_hbw_malloc(self):
        """ This test sets usupported value of MEMKIND_HBW_NODES, then try to perform a successfull allocation from DRAM using hbw_malloc()
        thanks to default HBW_POLICY_PREFERRED policy """
        command = "MEMKIND_HBW_NODES=-1 " + self.cmd_helper.get_command_path(self.environ_err_test)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode != 0, self.fail_msg.format("\nError: Execution of: \'{0}\' returns: {1} \noutput: {2}".format(command, retcode, output))
        assert self.expected_libnuma_warning == output, self.fail_msg.format("Error: expected libnuma warning ({0}) " \
               "was not found (output: {1})").format(self.expected_libnuma_warning, output)
Exemple #2
0
class Test_trace_mechanism(object):
    binary = "../trace_mechanism_test_helper"
    fail_msg = "Test failed with:\n {0}"
    debug_env = "MEMKIND_DEBUG=1 "
    cmd_helper = CMD_helper()

    def test_TC_MEMKIND_logging_MEMKIND_HBW(self):
        #This test executes trace_mechanism_test_helper and test if MEMKIND_INFO message occurs while calling MEMKIND_HBW
        command = self.debug_env + self.cmd_helper.get_command_path(self.binary) + " MEMKIND_HBW"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("Error: trace_mechanism_test_helper returned {0} with output: {1}".format(retcode,output))
        assert "MEMKIND_INFO: NUMA node" in output, self.fail_msg.format("Error: trace mechanism in memkind doesn't show MEMKIND_INFO message (output: {0})").format(output)

    def test_TC_MEMKIND_2MBPages_logging_MEMKIND_HUGETLB(self):
        #This test executes trace_mechanism_test_helper and test if MEMKIND_INFO message occurs while calling MEMKIND_HUGETLB
        command = self.debug_env + self.cmd_helper.get_command_path(self.binary) + " MEMKIND_HUGETLB"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("Error: trace_mechanism_test_helper returned {0} with output: {1}".format(retcode,output))
        assert "MEMKIND_INFO: Number of" in output, self.fail_msg.format("Error: trace mechanism in memkind doesn't show MEMKIND_INFO message (output: {0})").format(output)
        assert "MEMKIND_INFO: Overcommit limit for" in output, self.fail_msg.format("Error: trace mechanism in memkind doesn't show MEMKIND_INFO message (output: {0})").format(output)

    def test_TC_MEMKIND_logging_negative_MEMKIND_DEBUG_env(self):
        #This test executes trace_mechanism_test_helper and test if setting MEMKIND_DEBUG to wrong value causes MEMKIND_WARNING message
        command = "MEMKIND_DEBUG=-1 " + self.cmd_helper.get_command_path(self.binary) + " MEMKIND_HBW"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("Error: trace_mechanism_test_helper returned {0} with output: {1}".format(retcode,output))
        assert "MEMKIND_WARNING: debug option" in output, self.fail_msg.format("Error: setting wrong MEMKIND_DEBUG environment variable doesn't show MEMKIND_WARNING (output: {0})").format(output)
Exemple #3
0
class Test_hbw_env_var(object):
    environ_err_threshold_test = "../environ_err_hbw_threshold_test"
    cmd_helper = CMD_helper()

    def run_test(self, threshold, kind):
        env = "MEMKIND_HBW_THRESHOLD=" + str(threshold)
        bin_path = self.cmd_helper.get_command_path(
            self.environ_err_threshold_test)
        command = " ".join([env, bin_path, kind])
        output, retcode = self.cmd_helper.execute_cmd(command)
        print(output)
        fail_msg = f"Test failed with error: \nExecution of: \'{command}\' returns: {retcode} \noutput: {output}"
        assert retcode == 0, fail_msg

    @pytest.mark.parametrize("kind", ["MEMKIND_HBW", "MEMKIND_HBW_ALL"])
    def test_TC_MEMKIND_hbw_threshold_default_value(self, kind):
        threshold = 204800
        self.run_test(threshold, kind)

    @pytest.mark.parametrize("kind", ["MEMKIND_HBW", "MEMKIND_HBW_ALL"])
    def test_TC_MEMKIND_hbw_threshold_negative_value(self, kind):
        threshold = -1
        self.run_test(threshold, kind)

    @pytest.mark.parametrize("kind", ["MEMKIND_HBW", "MEMKIND_HBW_ALL"])
    def test_TC_MEMKIND_hbw_threshold_low_value(self, kind):
        threshold = 1
        self.run_test(threshold, kind)

    @pytest.mark.parametrize("kind", ["MEMKIND_HBW", "MEMKIND_HBW_ALL"])
    def test_TC_MEMKIND_hbw_threshold_high_value(self, kind):
        threshold = 1024 * 1024 * 1024
        self.run_test(threshold, kind)
class Test_max_bg_threads_env_var():

    cmd_helper = CMD_helper()
    fail_msg = "Test failed with:\n {0}"
    MAIN_THREAD = 1
    threads_limit = 0

    @property
    def min_threads(self):
        return self.MAIN_THREAD + self.threads_limit

    def run_test_binary(self):
        cmd_path = self.cmd_helper.get_command_path(
            '../environ_max_bg_threads_test')
        command = "MEMKIND_BACKGROUND_THREAD_LIMIT=" \
            f"{self.threads_limit} {cmd_path}"
        output, retcode = self.cmd_helper.execute_cmd(command)
        assert retcode != 1, \
            self.fail_msg.format(
                f"\nError: Execution of \'{command}\'"
                f" returns {retcode}. Output: {output}")
        return output, retcode

    def test_TC_MEMKIND_max_bg_threads_env_var_min(self):
        """This test checks if MEMKIND_BACKGROUND_THREAD_LIMIT
           environment variable limits the number of
           background threads spawned correctly."""
        self.threads_limit = 1
        output, retcode = self.run_test_binary()
        assert int(output) == self.min_threads, \
            self.fail_msg.format(
                f"Error: There should be {self.min_threads} threads running. "
                f"Counted threads: {output}.")

    @pytest.mark.parametrize("threads_limit", [0, 10])
    def test_TC_MEMKIND_max_bg_threads_env_var_multiple_threads(
            self, threads_limit):
        """This test checks if MEMKIND_BACKGROUND_THREAD_LIMIT
           environment variable
           allows spawning of multiple threads."""
        output, threads_count = self.run_test_binary()
        assert int(output) > self.min_threads, \
            self.fail_msg.format(
                f"Error: There should be more than"
                f" {self.min_threads} threads running. "
                f"Counted threads: {output}.")

    def test_TC_MEMKIND_max_bg_threads_env_var_err(self):
        """This test checks if a negative value
           MEMKIND_BACKGROUND_THREAD_LIMIT environment variable is handled
           correctly."""
        self.threads_limit = -1
        output, retcode, threads_count = self.run_test_binary()
        assert retcode == 134, \
            self.fail_msg.format(
                "Error: Negative value of MEMKIND_BACKGROUND_THREAD_LIMIT"
                " should not be handled. "
                f"Counted threads: {threads_count}. Output: {output}")
class Test_hbw_detection(object):
    binary_path = find_executable("memkind-hbw-nodes")
    environ_err_test = "../environ_err_hbw_malloc_test"
    expected_libnuma_warning = "libnuma: Warning: node argument -1 is out of range\n\n"
    fail_msg = "Test failed with:\n {0}"
    cmd_helper = CMD_helper()

    def get_nodemask_default(self):
        """ This function executes memkind function 'get_mbind_nodemask' and returns its output """
        hbw_nodemask_default = None
        command = self.cmd_helper.get_command_path(self.binary_path)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        if retcode == 0:
            hbw_nodemask_default = output
            print "Nodemask detected in test_hbw_detection_default: {0}".format(hbw_nodemask_default)
        assert retcode == 0, self.fail_msg.format("Error: hbw_nodemask returned {0}".format(retcode))
        return hbw_nodemask_default

    def get_nodemask_env_variable(self):
        """ This function overrides environment variable MEMKIND_HBW_NODES with values returned from 'memkind-hbw-nodes',
        executes memkind function 'get_mbind_nodemask' and returns its output """
        hbw_nodemask_env_variable = None
        command = "MEMKIND_HBW_NODES=`memkind-hbw-nodes` " + self.cmd_helper.get_command_path(self.binary_path)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        if retcode == 0:
            hbw_nodemask_env_variable = output
            print "Nodemask detected in test_hbw_detection_env_variable: {0}".format(hbw_nodemask_env_variable)
        assert retcode == 0, self.fail_msg.format("Error: hbw_nodemask returned {0}".format(retcode))
        return hbw_nodemask_env_variable

    def test_TC_MEMKIND_hbw_detection_default(self):
        """ This test checks whether hbw_nodemask_default is not None """
        assert self.get_nodemask_default() is not None, self.fail_msg.format("Error: hbw_nodemask_default is None")

    def test_TC_MEMKIND_hbw_detection_env_variable(self):
        """ This test checks whether hbw_nodemask_env_variable is not None """
        assert self.get_nodemask_env_variable() is not None, self.fail_msg.format("Error: hbw_nodemask_env_variable is None")

    def test_TC_MEMKIND_hbw_detection_compare_nodemask_default_and_env_variable(self):
        """ This test checks whether hbw_nodemask_default and hbw_nodemask_env_variable has the same value """
        hbw_nodemask_default = self.get_nodemask_default()
        hbw_nodemask_env_variable = self.get_nodemask_env_variable()
        assert hbw_nodemask_default == hbw_nodemask_env_variable, self.fail_msg.format("Error: Nodemask hbw_nodemask_default ({0}) " \
               "is not the same as nodemask hbw_nodemask_env_variable ({1})".format(hbw_nodemask_default, hbw_nodemask_env_variable))

    def test_TC_MEMKIND_hbw_detection_negative_hbw_malloc(self):
        """ This test sets usupported value of MEMKIND_HBW_NODES, then try to perform a successfull allocation from DRAM using hbw_malloc()
        thanks to default HBW_POLICY_PREFERRED policy """
        command = "MEMKIND_HBW_NODES=-1 " + self.cmd_helper.get_command_path(self.environ_err_test)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode != 0, self.fail_msg.format("Error: hbw_nodemask returned {0} with output {1}".format(retcode, output))
        assert self.expected_libnuma_warning == output, self.fail_msg.format("Error: expected libnuma warning ({0}) " \
               "was not found (output: {1})").format(self.expected_libnuma_warning, output)
class Test_dax_kmem_env_var(object):
    os.environ["PATH"] += os.pathsep + os.path.dirname(
        os.path.dirname(__file__))
    binary_path = find_executable("memkind-auto-dax-kmem-nodes")
    environ_err_test = "../environ_err_dax_kmem_malloc_test"
    environ_err_positive_test = "../environ_err_dax_kmem_malloc_positive_test"
    expected_libnuma_warning = "libnuma: Warning: node argument -1 is out of range\n\n"
    fail_msg = "Test failed with:\n {0}"
    cmd_helper = CMD_helper()

    def get_dax_kmem_nodes(self, nodemask=None):
        """ This function executes memkind function 'get_mbind_nodemask' and returns its output - comma-separated DAX_KMEM nodes """
        command = self.binary_path
        if (nodemask):
            command = "MEMKIND_DAX_KMEM_NODES={}".format(nodemask) + command
        output, retcode = self.cmd_helper.execute_cmd(command)
        assert retcode == 0, self.fail_msg.format(
            "\nError: Execution of \'{0}\' returns {1}, \noutput: {2}".format(
                command, retcode, output))
        print("\nExecution of {} returns output {}".format(command, output))
        return output

    def test_TC_MEMKIND_dax_kmem_env_var_compare_nodemask_default_and_env_variable(
            self):
        """ This test checks whether dax_kmem_nodemask_default and dax_kmem_nodemask_env_variable have the same value """
        dax_kmem_nodemask_default = self.get_dax_kmem_nodes()
        dax_kmem_nodemask_env_variable = self.get_dax_kmem_nodes(
            dax_kmem_nodemask_default)
        assert dax_kmem_nodemask_default == dax_kmem_nodemask_env_variable, self.fail_msg.format("Error: Nodemask dax_kmem_nodemask_default ({0}) " \
               "is not the same as nodemask dax_kmem_nodemask_env_variable ({1})".format(dax_kmem_nodemask_default, dax_kmem_nodemask_env_variable))

    def test_TC_MEMKIND_dax_kmem_env_var_negative_memkind_malloc(self):
        """ This test sets unsupported value of MEMKIND_DAX_KMEM_NODES, then tries to perform a successful allocation from DRAM using memkind_malloc() """
        command = "MEMKIND_DAX_KMEM_NODES=-1 " + self.cmd_helper.get_command_path(
            self.environ_err_test)
        output, retcode = self.cmd_helper.execute_cmd(command)
        assert retcode != 0, self.fail_msg.format(
            "\nError: Execution of: \'{0}\' returns: {1} \noutput: {2}".format(
                command, retcode, output))
        assert self.expected_libnuma_warning == output, self.fail_msg.format("Error: expected libnuma warning ({0}) " \
               "was not found (output: {1})").format(self.expected_libnuma_warning, output)

    def test_TC_MEMKIND_dax_kmem_env_var_proper_memkind_malloc(self):
        """ This test checks if allocation is performed on persistent memory correctly """
        dax_kmem_nodemask_default = self.get_dax_kmem_nodes().strip()
        command = "MEMKIND_DAX_KMEM_NODES={} ".format(
            dax_kmem_nodemask_default) + self.cmd_helper.get_command_path(
                self.environ_err_positive_test)
        output, retcode = self.cmd_helper.execute_cmd(command)
        assert retcode == 0, self.fail_msg.format(
            "\nError: Execution of: \'{0}\' returns: {1} \noutput: {2}".format(
                command, retcode, output))
Exemple #7
0
class Test_autohbw(object):
    binary = "../autohbw_test_helper"
    fail_msg = "Test failed with:\n {0}"
    test_prefix = "AUTO_HBW_LOG=2 LD_PRELOAD=%s/libautohbw.so.0 " % _get_lib_path()
    memkind_malloc_log = "In my memkind malloc"
    memkind_calloc_log = "In my memkind calloc"
    memkind_realloc_log = "In my memkind realloc"
    memkind_posix_memalign_log = "In my memkind align"
    memkind_free_log = "In my memkind free"
    cmd_helper = CMD_helper()

    def test_TC_MEMKIND_autohbw_malloc_and_free(self):
        """ This test executes ./autohbw_test_helper with LD_PRELOAD that is overriding malloc() and free() to equivalent autohbw functions"""
        command = self.test_prefix + self.cmd_helper.get_command_path(self.binary) + " malloc"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("\nError: autohbw_test_helper returned {0} \noutput: {1}".format(retcode,output))
        assert self.memkind_malloc_log in output, self.fail_msg.format("\nError: malloc was not overridden by autohbw equivalent \noutput: {0}").format(output)
        assert self.memkind_free_log in output, self.fail_msg.format("\nError: free was not overridden by autohbw equivalent \noutput: {0}").format(output)

    def test_TC_MEMKIND_autohbw_calloc_and_free(self):
        """ This test executes ./autohbw_test_helper with LD_PRELOAD that is overriding calloc() and free() to equivalent autohbw functions"""
        command = self.test_prefix + self.cmd_helper.get_command_path(self.binary) + " calloc"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("\nError: autohbw_test_helper returned {0} \noutput: {1}".format(retcode,output))
        assert self.memkind_calloc_log in output, self.fail_msg.format("\nError: calloc was not overridden by autohbw equivalent \noutput: {0}").format(output)
        assert self.memkind_free_log in output, self.fail_msg.format("Error: free was not overridden by autohbw equivalent \noutput: {0}").format(output)

    def test_TC_MEMKIND_autohbw_realloc_and_free(self):
        """ This test executes ./autohbw_test_helper with LD_PRELOAD that is overriding realloc() and free() to equivalent autohbw functions"""
        command = self.test_prefix + self.cmd_helper.get_command_path(self.binary) + " realloc"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("\nError: autohbw_test_helper returned {0} \noutput: {1}".format(retcode,output))
        assert self.memkind_realloc_log in output, self.fail_msg.format("\nError: realloc was not overridden by autohbw equivalent \noutput: {0}").format(output)
        assert self.memkind_free_log in output, self.fail_msg.format("\nError: free was not overridden by autohbw equivalent \noutput: {0}").format(output)

    def test_TC_MEMKIND_autohbw_posix_memalign_and_free(self):
        """ This test executes ./autohbw_test_helper with LD_PRELOAD that is overriding posix_memalign() and free() to equivalent autohbw functions"""
        command = self.test_prefix + self.cmd_helper.get_command_path(self.binary) + " posix_memalign"
        print "Executing command: {0}".format(command)
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=False)
        assert retcode == 0, self.fail_msg.format("\nError: autohbw_test_helper returned {0} \noutput: {1}".format(retcode,output))
        assert self.memkind_posix_memalign_log in output, self.fail_msg.format("\nError: posix_memalign was not overridden by autohbw equivalent \noutput: {0}").format(output)
        assert self.memkind_free_log in output, self.fail_msg.format("\nError: free was not overridden by autohbw equivalent \noutput: {0}").format(output)
Exemple #8
0
class Test_malloc_stats_print(object):

    cmd_helper = CMD_helper()
    bin_path = cmd_helper.get_command_path("../stats_print_test_helper")
    fail_msg = "Test failed with:\n {0}"
    bin_param = ""
    error_msg = "Error: {0} option not parsed correctly."

    def run_test_binary(self):
        command = " ".join([self.bin_path, self.bin_param])
        output, retcode = self.cmd_helper.execute_cmd(command)
        assert retcode == 0, \
            self.fail_msg.format(
                f"\nError: Execution of \'{command}\' returns {retcode}. Output: {output}")
        return output, retcode

    @pytest.mark.parametrize("bin_param", ["default", "stdout", "no_write_cb"])
    def test_TC_MEMKIND_malloc_stats_print_check_output(self, bin_param):
        """ This test checks if there is output from malloc_stats_print() memkind API function """
        self.bin_param = bin_param
        output, _ = self.run_test_binary()
        assert output.endswith("--- End jemalloc statistics ---\n"), \
            f"Error: Didn't get the expected output from the '{self.bin_path}' binary."

    def test_TC_MEMKIND_malloc_stats_print_multi_opt_test(self):
        """ This test checks output from malloc_stats_print() memkind API function when options
        "MEMKIND_STAT_PRINT_JSON_FORMAT | MEMKIND_STAT_PRINT_OMIT_PER_ARENA | MEMKIND_STAT_PRINT_OMIT_EXTENT"
        are passed to the function """
        self.bin_param = "pass_opts"
        output, _ = self.run_test_binary()
        assert json.loads(output), \
            self.error_msg.format("MEMKIND_STAT_PRINT_JSON_FORMAT")
        assert "arenas[" not in output, \
               self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_PER_ARENA")
        assert "extents:" not in output, \
               self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_EXTENT")

    def test_TC_MEMKIND_malloc_stats_print_all_opts_test(self):
        """ This test checks output from malloc_stats_print() memkind API function when all possible options
        are passed to the function """
        self.bin_param = "all_opts"
        output, _ = self.run_test_binary()
        assert json.loads(output), \
            self.error_msg.format("MEMKIND_STAT_PRINT_JSON_FORMAT")
        assert "version" not in output, \
               self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_GENERAL")
        assert "merged" not in output, \
               self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_MERGED_ARENA")
        assert "destroyed" not in output, \
               self.error_msg.format(
                   "MEMKIND_STAT_PRINT_OMIT_DESTROYED_MERGED_ARENA")
        assert re.search(re.compile(r'(\d+)": {'), output) is None, \
            self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_PER_ARENA")
        assert "\"bins\"" not in output, \
               self.error_msg.format(
                   "MEMKIND_STAT_PRINT_OMIT_PER_SIZE_CLASS_BINS")
        assert "lextents" not in output, \
               self.error_msg.format(
                   "MEMKIND_STAT_PRINT_OMIT_PER_SIZE_CLASS_LARGE")
        assert "mutex" not in output, \
               self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_MUTEX")
        assert "\"extents\"" not in output, \
               self.error_msg.format("MEMKIND_STAT_PRINT_OMIT_EXTENT")

    def test_TC_MEMKIND_malloc_stats_print_negative_test(self):
        """ This test checks if there is no output from malloc_stats_print() memkind API function when wrong arguments
            are being passed to the function """
        self.bin_param = "negative_test"
        output, _ = self.run_test_binary()
        assert len(output) == 0, \
            f"Error: There should be no output from the '{self.bin_path}' binary."

    def test_TC_MEMKIND_malloc_stats_print_opts_negative_test(self):
        """ This test checks if there is a failure in parsing opts in malloc_stats_print() memkind API function
            when wrong options string is passed to the function """
        self.bin_param = "opts_negative_test"
        _, retcode = self.run_test_binary()
        assert retcode == 0, \
            f"Error: '{self.bin_path}' binary should return 0 indicating that parsing opts string failed."