Пример #1
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}\'"
                    f" 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)
Пример #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(
            "\nError: trace_mechanism_test_helper",
            " returned {0} \noutput: {1}".format(retcode, output))
        assert "MEMKIND_INFO: Initializing kind memkind_hbw." \
            in output, self.fail_msg.format(
                "\nError: trace mechanism in memkind doesn't show",
                " MEMKIND_INFO message \noutput: {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(
            "\nError: trace_mechanism_test_helper",
            " returned {0} \noutput: {1}".format(retcode, output))
        assert "MEMKIND_INFO: Number of" in output, self.fail_msg.format(
            "\nError: trace mechanism in memkind doesn't show",
            " MEMKIND_INFO message \noutput: {0}").format(output)
        assert "MEMKIND_INFO: Overcommit limit for" \
            in output, self.fail_msg.format(
                "\nError: trace mechanism in memkind doesn't show",
                " MEMKIND_INFO message \n 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(
            "\nError: trace_mechanism_test_helper",
            " returned {0} \noutput: {1}".format(retcode, output))
        assert "MEMKIND_WARNING: debug option" in output, self.fail_msg.format(
            "\nError: setting wrong MEMKIND_DEBUG environment variable",
            " doesn't show MEMKIND_WARNING \noutput: {0})").format(output)
Пример #3
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_cmp_nodemask_default_and_env_var(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 unsupported value of MEMKIND_HBW_NODES,
            then try to perform a successful 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)
Пример #4
0
class Huge_page_organizer(object):

    cmd_helper = CMD_helper()
    path = "/sys/devices/system/node/node{0}/hugepages/" \
           "hugepages-2048kB/nr_hugepages"
    restore_values = []

    def __restore(self):
        """Restore initial setup of hugepages."""
        for node_id, restore_value in enumerate(self.restore_values):
            self.__set_nr_hugepages(node_id, restore_value)

    def __get_nr_hugepages(self, node_id):
        """Return number of hugepages on given node
           or None if given node is not configured."""
        if not os.path.isfile(self.path.format(node_id)):
            return None
        with open(self.path.format(node_id), "r") as f:
            return int(f.read())

    def __set_nr_hugepages(self, node_id, nr_hugepages):
        """Set hugepages on given node to given number.
           Return True on success, False otherwise."""
        command = 'sh -c "echo {0} >> {1}"'.format(nr_hugepages,
                                                   self.path.format(node_id))
        output, retcode = self.cmd_helper.execute_cmd(command, sudo=True)
        if retcode:
            return False
        return self.__get_nr_hugepages(node_id) is nr_hugepages

    def __init__(self, nr_hugepages_per_node):
        """Save current hugepages setup and set hugepages per NUMA node."""
        for node_id in itertools.count():
            nr_hugepages = self.__get_nr_hugepages(node_id)
            if nr_hugepages is None:
                break
            self.restore_values.append(nr_hugepages)
            retcode = self.__set_nr_hugepages(node_id, nr_hugepages_per_node)
            if not retcode:
                self.__restore()
            assert retcode, "Error: Could not set the requested"\
                            " amount of hugepages."

    def __del__(self):
        """Call __restore() function."""
        self.__restore()
Пример #5
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}\'",
                f" 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"), \
            "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, \
            "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."
Пример #6
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 " % _get_libautohbw_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)
Пример #7
0
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_cmp_with_nodemask_default(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))