On Wed, Jun 22, 2011 at 1:22 AM, Yiqiao Pu <[email protected]> wrote:
> This class configures khugepaged to active mode, with
> functions to restore original guest configuration.
>
> Changes from v1:
> * Rather than a pre/post script, config is now part of
> the framework
> * No need to store configuration in files anymore to restore
> host khugepaged original behavior
>
> Changes from v2:
> * Walk through  the thp config directory. And test khugepaged
> with the default value in system.
> * Add 5s sleep time in khugepaged test

Hi Yiqiao, excellent changes to the test setup! I found and cleaned up
some minor details, and made some comments, which I have fixed on a
v4, that I'm sending to the list shortly.

> Signed-off-by: Yiqiao Pu <[email protected]>
> Signed-off-by: Lucas Meneghel Rodrigues <[email protected]>
> ---
>  client/virt/virt_test_setup.py |  187 
> +++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 186 insertions(+), 1 deletions(-)
>
> diff --git a/client/virt/virt_test_setup.py b/client/virt/virt_test_setup.py
> index 3e1f5b5..70cf3c2 100644
> --- a/client/virt/virt_test_setup.py
> +++ b/client/virt/virt_test_setup.py
> @@ -1,11 +1,196 @@
>  """
>  Library to perform pre/post test setup for KVM autotest.
>  """
> -import os, logging
> +import os, logging, time, re, sre, random
>  from autotest_lib.client.common_lib import error
>  from autotest_lib.client.bin import utils
>
>
> +class THPError(Exception):
> +    """
> +    Base exception for Transparent Hugepage setup.
> +    """
> +    pass
> +
> +
> +class THPNotSupportedError(THPError):
> +    """
> +    Thrown when host does not support tansparent hugepages.
> +    """
> +    pass
> +
> +
> +class THPWriteConfigError(THPError):
> +    """
> +    Thrown when host does not support tansparent hugepages.
> +    """
> +    pass
> +
> +
> +class THPKhugepagedError(THPError):
> +    """
> +    Thrown when khugepaged is not behaving as expected.
> +    """
> +    pass
> +
> +
> +class TransparentHugePageConfig(object):
> +    def __init__(self, test, params):
> +        """
> +        Find paths for transparent hugepages and kugepaged configuration. 
> Also,
> +        back up original host configuration so it can be restored during
> +        cleanup.
> +        """
> +        def file_writeable(file_name):
> +            """
> +            Check if the file is writeable
> +            """
> +            o = utils.system_output("ls -l %s" % file_name)
> +            if re.findall("w", o[0:10]):
> +                return True
> +            return False

^ This can be replaced with os.access (file_name, os.W_OK)

> +        self.params = params
> +
> +        RH_THP_PATH = "/sys/kernel/mm/redhat_transparent_hugepage"
> +        UPSTREAM_THP_PATH = "/sys/kernel/mm/transparent_hugepage"
> +        if os.path.isdir(RH_THP_PATH):
> +            self.thp_path = RH_THP_PATH
> +        elif os.path.isdir(UPSTREAM_THP_PATH):
> +            self.thp_path = UPSTREAM_THP_PATH
> +        else:
> +            raise THPNotSupportedError("System doesn't support transparent "
> +                                       "hugepages")
> +
> +        tmp_list = []
> +        test_cfg = {}
> +        test_config = self.params.get("test_config", None)
> +        if test_config is not None:
> +            tmp_list = re.split(';', test_config)
> +        while len(tmp_list) > 0:
> +            tmp_cfg = tmp_list.pop()
> +            test_cfg[re.split(":", tmp_cfg)[0]] = sre.split(":", tmp_cfg)[1]
> +        # Save host current config, so we can restore it during cleanup
> +        # We will only save the writeable part of the config files
> +        original_config = {}
> +        file_list_str = []
> +        file_list_num = []
> +        for f in os.walk(self.thp_path):
> +            base_dir = f[0]
> +            if f[2]:
> +                for name in f[2]:
> +                    f_dir = os.path.join(base_dir, name)
> +                    parameter = file(f_dir, 'r').read()
> +                    if file_writeable(f_dir):

^ See comment above.

> +                        if re.findall("\[(.*)\]", parameter):
> +                            original_config[f_dir] = re.findall("\[(.*)\]",
> +                                                           parameter)[0]
> +                            file_list_str.append(f_dir)
> +                        else:
> +                            original_config[f_dir] = int(parameter)
> +                            file_list_num.append(f_dir)
> +
> +        self.test_config = test_cfg
> +        self.original_config = original_config
> +        self.file_list_str = file_list_str
> +        self.file_list_num = file_list_num

^ Same here, I verified and this intermediary assignment is not necessary.

> +    def set_env(self):
> +        """
> +        Applies test configuration on the host.
> +        """
> +        if self.test_config:
> +            for path in self.test_config.keys():
> +                file(path, 'w').write(self.test_config[path])
> +
> +    def value_listed(self, value):
> +        """
> +        Get a parameters list from a string
> +        """
> +        value_list = []
> +        for i in re.split("\[|\]|\n+|\s+", value):
> +            if i:
> +                value_list.append(i)
> +        return value_list
> +
> +    def khugepaged_test(self):
> +        """
> +        Start, stop and frequency change test for khugepaged.
> +        """
> +        def check_status_with_value(action_list, file_name):
> +            """
> +            Check the status of khugepaged when set value to specify file
> +            """
> +            for (a, r) in action_list:
> +                open(file_name, "w").write(a)
> +                time.sleep(5)
> +                try:
> +                    utils.run('pgrep khugepaged')
> +                    if r !=0:
> +                        raise THPKhugepagedError("Khugepaged still alive 
> when"
> +                                                 "transparent huge page is "
> +                                                 "disabled")
> +                except error.CmdError:
> +                    if r == 0:
> +                        raise THPKhugepagedError("khugepaged can not set to"
> +                                                 "status %s" % a)
> +
> +        file_list_str = self.file_list_str
> +        file_list_num = self.file_list_num

^ I verified and see no reason to do this assignment, just use
self.file_list_str and such...

> +        for file_path in file_list_str:
> +            action_list = []
> +            if re.findall("enabled", file_path):
> +                # Start and stop test for khugepaged
> +                value_list = self.value_listed(open(file_path,"r").read())
> +                for i in value_list:
> +                    if re.match("n", i, re.I):
> +                        action_stop = (i, 256)
> +                for i in value_list:
> +                    if re.match("[^n]", i, re.I):
> +                        action = (i, 0)
> +                        action_list += [action_stop, action, action_stop]
> +                action_list += [action]
> +
> +                check_status_with_value(action_list, file_path)
> +            else:
> +                value_list = self.value_listed(open(file_path,"r").read())
> +                for i in value_list:
> +                    action = (i, 0)
> +                    action_list.append(action)
> +                check_status_with_value(action_list, file_path)
> +
> +        for file_path in file_list_num:
> +            action_list = []
> +            value = int(open(file_path, "r").read())
> +            if value != 0 and value != 1:
> +                new_value = random.random()
> +                action_list.append((str(int(value * new_value)),0))
> +                action_list.append((str(int(value * ( new_value + 1))),0))
> +            else:
> +                action_list.append(("0", 0))
> +                action_list.append(("1", 0))
> +
> +            check_status_with_value(action_list, file_path)
> +
> +
> +    def setup(self):
> +        """
> +        Configure host for testing. Also, check that khugepaged is working as
> +        expected.
> +        """
> +        self.set_env()
> +        self.khugepaged_test()
> +
> +
> +    def cleanup(self):
> +        """:
> +        Restore the host's original configuration after test
> +        """
> +        for path in self.original_config:
> +            p_file = open(path, 'w')
> +            p_file.write(str(self.original_config[path]))
> +            p_file.close()
> +
>  class HugePageConfig(object):
>     def __init__(self, params):
>         """
> --
> 1.7.1
>
> _______________________________________________
> Autotest mailing list
> [email protected]
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
>



-- 
Lucas
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

Reply via email to