[libvirt] [test-API PATCH 0/2] support variables share across testcases

These two patch is to create a shared module in the root of test-API The framework will create connection object for shared use in testcases based on environment checking results. sharedmod.py # This is a module for variable sharing across testcases during # running. You have to import it in each of testcases which want # to share data. The framwork have already set 'conn' for use in # testcases. # connection object in libvirt.py conn = None # shared variables for customized use in testcases # Note: please set them to None at the end of sharing defined_var1 = None defined_var2 = None defined_var3 = None

sharedmod.py: in root directory --- sharedmod.py | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..f3de5a6 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,13 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set 'conn' for use in +# testcases. + +# connection object in libvirt.py +conn = None + +# shared variables for customized use in testcases +# Note: please set them to None at the end of sharing +defined_var1 = None +defined_var2 = None +defined_var3 = None -- 1.7.7.5

On 04/06/2012 11:14 AM, Guannan Ren wrote:
sharedmod.py: in root directory --- sharedmod.py | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..f3de5a6 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,13 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set 'conn' for use in +# testcases. + +# connection object in libvirt.py +conn = None + +# shared variables for customized use in testcases +# Note: please set them to None at the end of sharing +defined_var1 = None +defined_var2 = None +defined_var3 = None
I see this could be little more error-prone. And maybe little more variable. I know we can add a variable for every test making use of some sharemod persistence, but that would mean there will be big mess very early. I would probably just do something like this for example: data = {} And then in the test when you want to use shared variable, you can do: Setting: sharedmod.data['my_test_variable'] = 'test_value' Checking: if sharedmod.data.has_key('my_test_valiable'): # The value is set Getting: sharemod.data.get('my_test_variable', 'test_variable_default_value') But if the current suits you better, I think you can go with it as well. Martin

On 04/10/2012 07:28 PM, Martin Kletzander wrote:
On 04/06/2012 11:14 AM, Guannan Ren wrote:
sharedmod.py: in root directory --- sharedmod.py | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..f3de5a6 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,13 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set 'conn' for use in +# testcases. + +# connection object in libvirt.py +conn = None + +# shared variables for customized use in testcases +# Note: please set them to None at the end of sharing +defined_var1 = None +defined_var2 = None +defined_var3 = None
I see this could be little more error-prone. And maybe little more variable. I know we can add a variable for every test making use of some sharemod persistence, but that would mean there will be big mess very early. I would probably just do something like this for example:
data = {}
And then in the test when you want to use shared variable, you can do:
Setting: sharedmod.data['my_test_variable'] = 'test_value'
Checking: if sharedmod.data.has_key('my_test_valiable'): # The value is set
Getting: sharemod.data.get('my_test_variable', 'test_variable_default_value')
But if the current suits you better, I think you can go with it as well.
Martin
Thanks for your advice, I think it is very good. I will send v2. Guannan Ren

sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework +# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it, +# the framework do it. +libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value') +data = {} -- 1.7.7.5

s/sharing in/sharing among/, but given it's already pushed. let's live with it. On 2012年04月10日 21:38, Guannan Ren wrote:
sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework
Any checking? I.e could testcase r/w it too?
+# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it,
IMHO "need not" should be "should never". How about the follow up use of connection if it's already closed, reopen one again?
+# the framework do it.
<snip> The framwork have already set {'conn': connobj}
+# in libvirtobj dictionary for use in testcases. + </snip>
The comment above should resides here.
+libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value')
From my p.o.v, "libvirtobj" is a confused name, also "data" is not enough to tell what the meaning is. How about use "framework_shares" and "case_shares" instead? And implement get/set/has functions for both "framework_shares" and "case_shares", but not access them directly. e.g. def case_shares_get(key): pass def case_shares_set(key, value): pass def case_shares_has(key) pass Even perhaps a class is good. Osier

On 04/16/2012 08:03 AM, Osier Yang wrote:
s/sharing in/sharing among/, but given it's already pushed. let's live with it.
On 2012年04月10日 21:38, Guannan Ren wrote:
sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework
Any checking? I.e could testcase r/w it too?
+# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it,
IMHO "need not" should be "should never". How about the follow up use of connection if it's already closed, reopen one again?
+# the framework do it.
<snip> The framwork have already set {'conn': connobj}
+# in libvirtobj dictionary for use in testcases. + </snip>
The comment above should resides here.
+libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value')
From my p.o.v, "libvirtobj" is a confused name, also "data" is not enough to tell what the meaning is. How about use "framework_shares" and "case_shares" instead?
And implement get/set/has functions for both "framework_shares" and "case_shares", but not access them directly. e.g.
def case_shares_get(key): pass
def case_shares_set(key, value): pass
def case_shares_has(key) pass
Even perhaps a class is good.
Osier
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
That's getting closer and closer to what I recommended as a redesign for the whole test-API. Class would be better, tests shouldn't need to import the mod every time, there should be checking etc. However I feel the need to make this stable asap and after some release, we can go ahead with some major redesigns (or at least that's how I understood our talk about this with Dave few weeks ago). Martin

On 04/16/2012 04:04 PM, Martin Kletzander wrote:
s/sharing in/sharing among/, but given it's already pushed. let's live with it.
On 2012年04月10日 21:38, Guannan Ren wrote:
sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework
Any checking? I.e could testcase r/w it too?
+# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it, IMHO "need not" should be "should never". How about the follow up use of connection if it's already closed, reopen one again?
+# the framework do it. <snip> The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + </snip>
The comment above should resides here.
+libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value') From my p.o.v, "libvirtobj" is a confused name, also "data" is not enough to tell what the meaning is. How about use "framework_shares" and "case_shares" instead?
And implement get/set/has functions for both "framework_shares" and "case_shares", but not access them directly. e.g.
def case_shares_get(key): pass
def case_shares_set(key, value): pass
def case_shares_has(key) pass
Even perhaps a class is good.
Osier
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list That's getting closer and closer to what I recommended as a redesign for
On 04/16/2012 08:03 AM, Osier Yang wrote: the whole test-API. Class would be better, tests shouldn't need to import the mod every time, there should be checking etc. However I feel the need to make this stable asap and after some release, we can go ahead with some major redesigns (or at least that's how I understood our talk about this with Dave few weeks ago).
Martin
Sorry, I missed the mail thread. No problem for me to use the class or something in framework. Use the Class in testcases is not a good idea, it make writing testcase complex than the use of function directly. But, anyway, the common purpose is to ease the work of writing testcases. Guannan Ren

sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework +# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it, +# the framework do it. +libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value') +data = {} -- 1.7.7.5

On 04/10/2012 09:55 PM, Guannan Ren wrote:
sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework +# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it, +# the framework do it. +libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value') +data = {}
If no more comments, I will push these two patches. Guannan Ren

On 04/13/2012 02:23 PM, Guannan Ren wrote:
On 04/10/2012 09:55 PM, Guannan Ren wrote:
sharedmod.py --- sharedmod.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 sharedmod.py
diff --git a/sharedmod.py b/sharedmod.py new file mode 100644 index 0000000..8af26d8 --- /dev/null +++ b/sharedmod.py @@ -0,0 +1,16 @@ +# This is a module for variable sharing across testcases during +# running. You have to import it in each of testcases which want +# to share data. The framwork have already set {'conn': connobj} +# in libvirtobj dictionary for use in testcases. + +# The libvirtobj dictionary is only set and used by framework +# in testcases you could use sharedmod.libvirtobj['conn'] to get +# the connection object in libvirt.py, you need not to close it, +# the framework do it. +libvirtobj = {} + +# shared variables for customized use in testcases +# set variable: sharedmod.data['my_test_variable'] = 'test_value' +# check the variable: sharedmod.data.has_key('my_test_variable') +# get the varialbe: sharedmod.data.get('my_test_variable', 'test_variable_default_value') +data = {}
If no more comments, I will push these two patches.
Guannan Ren
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
This one looks ok, I haven't had a chance to look at the second one yet. Martin

dist/redhat/env_inspect.py: initialize shared conn obj for use in all testcases generator.py: make use of sharedmod --- dist/redhat/env_inspect.py | 173 +++++++++++++++++++++++--------------------- generator.py | 15 +--- 2 files changed, 93 insertions(+), 95 deletions(-) diff --git a/dist/redhat/env_inspect.py b/dist/redhat/env_inspect.py index 8cff106..5a63866 100644 --- a/dist/redhat/env_inspect.py +++ b/dist/redhat/env_inspect.py @@ -19,104 +19,109 @@ # from each testcase to the corresponding testcase's # argument in the order of testcase running -import subprocess - -def childprocess(pcmd, acmd): - P1 = subprocess.Popen(pcmd, stdout = subprocess.PIPE) - P2 = subprocess.Popen(acmd, stdin = P1.stdout, stdout =subprocess.PIPE) - out = P2.communicate()[0].strip() - rc = P2.returncode - - if rc == 0: - return out - else: - return "" - -def get_libvirt_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-[0-9]"]) - if ver == "": - return 100, "No libvirt installed" - else: - return 0, ver - -def get_libvirt_pyth_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-python-[0-9]"]) - if ver == "": - return 100, "No libvirt-python installed" +import commands +import libvirt +import sharedmod + +def check_libvirt(logger): + virsh = 'virsh -v' + status, output = commands.getstatusoutput(virsh) + if status: + logger.error(output) + return 1 else: - return 0, ver - -def get_libvirt_cli_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-client-[0-9]"]) - if ver == "": - return 100, "No libvirt-client installed" + logger.info(" Virsh command line tool of libvirt: %s" % output) + + libvirtd = 'libvirtd --version' + status, output = commands.getstatusoutput(libvirtd) + logger.info(" %s" % output) + if status: + return 1 + + default_uri = 'virsh uri' + status, output = commands.getstatusoutput(default_uri) + if status: + logger.error(output) + return 1 else: - return 0, ver - -def get_qemu_kvm_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "qemu-kvm-[0-9]"]) - if ver == "": - return 150, "No qemu-kvm installed" - else: - return 0, ver + logger.info(" default uri: %s" % output.strip()) + + if 'qemu' in output: + qemu = 'qemu --version' + status, output = commands.getstatusoutput(qemu) + logger.info(" %s" % output) + if status: + return 1 + elif 'xen' in output: + #TODO need to get xen hypervisor info here + pass + + return 0 + +def hostinfo(logger): + command = 'uname -a' + status, output = commands.getstatusoutput(command) + logger.info(" %s" % output) + if status: + return 1 + return 0 + +def request_credentials(credentials, user_data): + for credential in credentials: + if credential[0] == libvirt.VIR_CRED_AUTHNAME: + credential[4] = user_data[0] + + if len(credential[4]) == 0: + credential[4] = credential[3] + elif credential[0] == libvirt.VIR_CRED_PASSPHRASE: + credential[4] = user_data[1] + else: + return -1 -def get_kernel_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^kernel-[0-9]"]) - if ver == "": - return 100, "No kernel installed" - else: - return 0, ver + return 0 +def sharemod_init(env_parser, logger): + """ get connection object from libvirt module + initialize sharemod for use by testcases + """ + uri = env_parser.get_value('variables', 'defaulturi') + username = env_parser.get_value('variables', 'username') + password = env_parser.get_value('variables', 'password') + user_data = [username, password] + auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], request_credentials, user_data] + conn = libvirt.openAuth(uri, auth, 0) + if not conn: + logger.error("Failed to setup libvirt connection"); + return 1 + + # initialize conn object in sharedmod + sharedmod.conn = conn + return 0 class EnvInspect(object): """to check and collect the testing enviroment infomation before performing testing """ - def __init__(self, logger): + def __init__(self, env_parser, logger): self.logger = logger + self.env_parser = env_parser def env_checking(self): - flag = 0 - result = "" - if get_libvirt_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_ver()[1], result)) - - if get_libvirt_pyth_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_pyth_ver()[1], result)) + if hostinfo(self.logger): + return 1 - if get_libvirt_cli_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_cli_ver()[1], result)) - - if get_qemu_kvm_ver()[0] == 150 and flag == 0: - flag = 0 - elif get_qemu_kvm_ver()[0] == 150 and flag == 1: - flag = 1 - else: - pass - self.logger.info(" %-36s%-6s" % (get_qemu_kvm_ver()[1], OK)) - - if get_kernel_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_kernel_ver()[1], result)) + if check_libvirt(self.logger): + return 1 - return flag + if sharemod_init(self.env_parser, self.logger): + return 1 + return 0 -OK = "ok" -NOTOK = "not ok" + def close_hypervisor_connection(self): + shared_conn = sharedmod.conn + if shared_conn: + shared_conn.close() + shared_conn = None + return 0 diff --git a/generator.py b/generator.py index 0af4227..d7cd985 100644 --- a/generator.py +++ b/generator.py @@ -20,6 +20,7 @@ import time import fcntl import sys +import os import traceback import mapper @@ -30,7 +31,6 @@ from utils.Python import env_parser # Import of distribution-specific code. If this is needed somewhere # else in the future, please don't copy-paste this, but create some # sensible distribution-specific package -import os for dist in os.listdir('dist'): if os.path.exists('/etc/%s-release' % dist): exec('from dist.%s import env_inspect' % dist) @@ -119,7 +119,7 @@ class FuncGen(object): start_time = time.strftime("%Y-%m-%d %H:%M:%S") env_logger.info("Checking Testing Environment... ") - envck = env_inspect.EnvInspect(env_logger) + envck = env_inspect.EnvInspect(self.env, env_logger) if envck.env_checking() == 1: sys.exit(1) @@ -157,15 +157,6 @@ class FuncGen(object): clean_ret = -1 try: try: - # Get default uri from env.cfg, if the uri is defined in - # case config file, the value will be overrode. - if 'uri' not in case_params: - case_params['uri'] = self.env.get_value("variables", "defaulturi") - if 'username' not in case_params: - case_params['username'] = self.env.get_value("variables", "username") - if 'password' not in case_params: - case_params['password'] = self.env.get_value("variables", "password") - if case_ref_name != 'sleep': case_params['logger'] = case_logger @@ -211,6 +202,8 @@ class FuncGen(object): else: self.fmt.print_string(21*" " + "Fail", env_logger) + # close hypervisor connection + envck.close_hypervisor_connection() end_time = time.strftime("%Y-%m-%d %H:%M:%S") env_logger.info("\nSummary:") -- 1.7.7.5

dist/redhat/env_inspect.py: initialize shared connection object for use in all testcases generator.py: make use of sharedmod --- dist/redhat/env_inspect.py | 192 ++++++++++++++++++++++++-------------------- generator.py | 15 +--- 2 files changed, 108 insertions(+), 99 deletions(-) diff --git a/dist/redhat/env_inspect.py b/dist/redhat/env_inspect.py index 8cff106..3e8da2c 100644 --- a/dist/redhat/env_inspect.py +++ b/dist/redhat/env_inspect.py @@ -19,104 +19,120 @@ # from each testcase to the corresponding testcase's # argument in the order of testcase running -import subprocess - -def childprocess(pcmd, acmd): - P1 = subprocess.Popen(pcmd, stdout = subprocess.PIPE) - P2 = subprocess.Popen(acmd, stdin = P1.stdout, stdout =subprocess.PIPE) - out = P2.communicate()[0].strip() - rc = P2.returncode - - if rc == 0: - return out - else: - return "" - -def get_libvirt_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-[0-9]"]) - if ver == "": - return 100, "No libvirt installed" - else: - return 0, ver - -def get_libvirt_pyth_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-python-[0-9]"]) - if ver == "": - return 100, "No libvirt-python installed" +import commands +import libvirt +import sharedmod + +def check_libvirt(logger): + virsh = 'virsh -v' + status, output = commands.getstatusoutput(virsh) + if status: + logger.error(output) + return 1 else: - return 0, ver - -def get_libvirt_cli_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-client-[0-9]"]) - if ver == "": - return 100, "No libvirt-client installed" - else: - return 0, ver - -def get_qemu_kvm_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "qemu-kvm-[0-9]"]) - if ver == "": - return 150, "No qemu-kvm installed" + logger.info(" Virsh command line tool of libvirt: %s" % output) + + libvirtd = 'libvirtd --version' + status, output = commands.getstatusoutput(libvirtd) + logger.info(" %s" % output) + if status: + return 1 + + default_uri = 'virsh uri' + status, output = commands.getstatusoutput(default_uri) + if status: + logger.error(output) + return 1 else: - return 0, ver + logger.info(" Default URI: %s" % output.strip()) + + if 'qemu' in output: + qemu = 'qemu --version' + status, output = commands.getstatusoutput(qemu) + logger.info(" %s" % output) + if status: + return 1 + elif 'xen' in output: + #TODO need to get xen hypervisor info here + pass + + return 0 + +def hostinfo(logger): + command = 'uname -a' + status, output = commands.getstatusoutput(command) + logger.info(" %s" % output) + if status: + return 1 + return 0 + +def request_credentials(credentials, user_data): + for credential in credentials: + if credential[0] == libvirt.VIR_CRED_AUTHNAME: + credential[4] = user_data[0] + + if len(credential[4]) == 0: + credential[4] = credential[3] + elif credential[0] == libvirt.VIR_CRED_PASSPHRASE: + credential[4] = user_data[1] + else: + return -1 -def get_kernel_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^kernel-[0-9]"]) - if ver == "": - return 100, "No kernel installed" - else: - return 0, ver + return 0 +def sharemod_init(env_parser, logger): + """ get connection object from libvirt module + initialize sharemod for use by testcases + """ + uri = env_parser.get_value('variables', 'defaulturi') + username = env_parser.get_value('variables', 'username') + password = env_parser.get_value('variables', 'password') + user_data = [username, password] + auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], request_credentials, user_data] + conn = libvirt.openAuth(uri, auth, 0) + if not conn: + logger.error("Failed to setup libvirt connection"); + return 1 + + # initialize conn object in sharedmod + sharedmod.libvirtobj.clear() + sharedmod.data.clear() + sharedmod.libvirtobj['conn'] = conn + return 0 class EnvInspect(object): """to check and collect the testing enviroment infomation before performing testing """ - def __init__(self, logger): + def __init__(self, env_parser, logger): self.logger = logger + self.env_parser = env_parser def env_checking(self): - flag = 0 - result = "" - if get_libvirt_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_ver()[1], result)) - - if get_libvirt_pyth_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_pyth_ver()[1], result)) - - if get_libvirt_cli_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_cli_ver()[1], result)) - - if get_qemu_kvm_ver()[0] == 150 and flag == 0: - flag = 0 - elif get_qemu_kvm_ver()[0] == 150 and flag == 1: - flag = 1 - else: - pass - self.logger.info(" %-36s%-6s" % (get_qemu_kvm_ver()[1], OK)) - - if get_kernel_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_kernel_ver()[1], result)) - - return flag - - -OK = "ok" -NOTOK = "not ok" + if hostinfo(self.logger): + return 1 + + if check_libvirt(self.logger): + return 1 + + if sharemod_init(self.env_parser, self.logger): + return 1 + + return 0 + + def close_hypervisor_connection(self): + conn = sharedmod.libvirtobj.get('conn', None) + if conn: + # conn probably is invalid pointer + # that means the connection is closed + # If so we ignore the error here + try: + conn.close() + conn = None + except: + pass + + sharedmod.libvirtobj.clear() + sharedmod.data.clear() + return 0 diff --git a/generator.py b/generator.py index 0af4227..d7cd985 100644 --- a/generator.py +++ b/generator.py @@ -20,6 +20,7 @@ import time import fcntl import sys +import os import traceback import mapper @@ -30,7 +31,6 @@ from utils.Python import env_parser # Import of distribution-specific code. If this is needed somewhere # else in the future, please don't copy-paste this, but create some # sensible distribution-specific package -import os for dist in os.listdir('dist'): if os.path.exists('/etc/%s-release' % dist): exec('from dist.%s import env_inspect' % dist) @@ -119,7 +119,7 @@ class FuncGen(object): start_time = time.strftime("%Y-%m-%d %H:%M:%S") env_logger.info("Checking Testing Environment... ") - envck = env_inspect.EnvInspect(env_logger) + envck = env_inspect.EnvInspect(self.env, env_logger) if envck.env_checking() == 1: sys.exit(1) @@ -157,15 +157,6 @@ class FuncGen(object): clean_ret = -1 try: try: - # Get default uri from env.cfg, if the uri is defined in - # case config file, the value will be overrode. - if 'uri' not in case_params: - case_params['uri'] = self.env.get_value("variables", "defaulturi") - if 'username' not in case_params: - case_params['username'] = self.env.get_value("variables", "username") - if 'password' not in case_params: - case_params['password'] = self.env.get_value("variables", "password") - if case_ref_name != 'sleep': case_params['logger'] = case_logger @@ -211,6 +202,8 @@ class FuncGen(object): else: self.fmt.print_string(21*" " + "Fail", env_logger) + # close hypervisor connection + envck.close_hypervisor_connection() end_time = time.strftime("%Y-%m-%d %H:%M:%S") env_logger.info("\nSummary:") -- 1.7.7.5

dist/redhat/env_inspect.py: initialize shared connection object for use in all testcases generator.py: make use of sharedmod --- dist/redhat/env_inspect.py | 192 ++++++++++++++++++++++++-------------------- generator.py | 15 +--- 2 files changed, 108 insertions(+), 99 deletions(-) diff --git a/dist/redhat/env_inspect.py b/dist/redhat/env_inspect.py index 8cff106..3e8da2c 100644 --- a/dist/redhat/env_inspect.py +++ b/dist/redhat/env_inspect.py @@ -19,104 +19,120 @@ # from each testcase to the corresponding testcase's # argument in the order of testcase running -import subprocess - -def childprocess(pcmd, acmd): - P1 = subprocess.Popen(pcmd, stdout = subprocess.PIPE) - P2 = subprocess.Popen(acmd, stdin = P1.stdout, stdout =subprocess.PIPE) - out = P2.communicate()[0].strip() - rc = P2.returncode - - if rc == 0: - return out - else: - return "" - -def get_libvirt_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-[0-9]"]) - if ver == "": - return 100, "No libvirt installed" - else: - return 0, ver - -def get_libvirt_pyth_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-python-[0-9]"]) - if ver == "": - return 100, "No libvirt-python installed" +import commands +import libvirt +import sharedmod + +def check_libvirt(logger): + virsh = 'virsh -v' + status, output = commands.getstatusoutput(virsh) + if status: + logger.error(output) + return 1 else: - return 0, ver - -def get_libvirt_cli_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^libvirt-client-[0-9]"]) - if ver == "": - return 100, "No libvirt-client installed" - else: - return 0, ver - -def get_qemu_kvm_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "qemu-kvm-[0-9]"]) - if ver == "": - return 150, "No qemu-kvm installed" + logger.info(" Virsh command line tool of libvirt: %s" % output) + + libvirtd = 'libvirtd --version' + status, output = commands.getstatusoutput(libvirtd) + logger.info(" %s" % output) + if status: + return 1 + + default_uri = 'virsh uri' + status, output = commands.getstatusoutput(default_uri) + if status: + logger.error(output) + return 1 else: - return 0, ver + logger.info(" Default URI: %s" % output.strip()) + + if 'qemu' in output: + qemu = 'qemu --version' + status, output = commands.getstatusoutput(qemu) + logger.info(" %s" % output) + if status: + return 1 + elif 'xen' in output: + #TODO need to get xen hypervisor info here + pass + + return 0 + +def hostinfo(logger): + command = 'uname -a' + status, output = commands.getstatusoutput(command) + logger.info(" %s" % output) + if status: + return 1 + return 0 + +def request_credentials(credentials, user_data): + for credential in credentials: + if credential[0] == libvirt.VIR_CRED_AUTHNAME: + credential[4] = user_data[0] + + if len(credential[4]) == 0: + credential[4] = credential[3] + elif credential[0] == libvirt.VIR_CRED_PASSPHRASE: + credential[4] = user_data[1] + else: + return -1 -def get_kernel_ver(): - ver = childprocess(['rpm', '-qa'], ['egrep', "^kernel-[0-9]"]) - if ver == "": - return 100, "No kernel installed" - else: - return 0, ver + return 0 +def sharemod_init(env_parser, logger): + """ get connection object from libvirt module + initialize sharemod for use by testcases + """ + uri = env_parser.get_value('variables', 'defaulturi') + username = env_parser.get_value('variables', 'username') + password = env_parser.get_value('variables', 'password') + user_data = [username, password] + auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], request_credentials, user_data] + conn = libvirt.openAuth(uri, auth, 0) + if not conn: + logger.error("Failed to setup libvirt connection"); + return 1 + + # initialize conn object in sharedmod + sharedmod.libvirtobj.clear() + sharedmod.data.clear() + sharedmod.libvirtobj['conn'] = conn + return 0 class EnvInspect(object): """to check and collect the testing enviroment infomation before performing testing """ - def __init__(self, logger): + def __init__(self, env_parser, logger): self.logger = logger + self.env_parser = env_parser def env_checking(self): - flag = 0 - result = "" - if get_libvirt_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_ver()[1], result)) - - if get_libvirt_pyth_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_pyth_ver()[1], result)) - - if get_libvirt_cli_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_libvirt_cli_ver()[1], result)) - - if get_qemu_kvm_ver()[0] == 150 and flag == 0: - flag = 0 - elif get_qemu_kvm_ver()[0] == 150 and flag == 1: - flag = 1 - else: - pass - self.logger.info(" %-36s%-6s" % (get_qemu_kvm_ver()[1], OK)) - - if get_kernel_ver()[0] == 100: - result = NOTOK - flag = 1 - else: - result = OK - self.logger.info(" %-36s%-6s" % (get_kernel_ver()[1], result)) - - return flag - - -OK = "ok" -NOTOK = "not ok" + if hostinfo(self.logger): + return 1 + + if check_libvirt(self.logger): + return 1 + + if sharemod_init(self.env_parser, self.logger): + return 1 + + return 0 + + def close_hypervisor_connection(self): + conn = sharedmod.libvirtobj.get('conn', None) + if conn: + # conn probably is invalid pointer + # that means the connection is closed + # If so we ignore the error here + try: + conn.close() + conn = None + except: + pass + + sharedmod.libvirtobj.clear() + sharedmod.data.clear() + return 0 diff --git a/generator.py b/generator.py index 0af4227..d7cd985 100644 --- a/generator.py +++ b/generator.py @@ -20,6 +20,7 @@ import time import fcntl import sys +import os import traceback import mapper @@ -30,7 +31,6 @@ from utils.Python import env_parser # Import of distribution-specific code. If this is needed somewhere # else in the future, please don't copy-paste this, but create some # sensible distribution-specific package -import os for dist in os.listdir('dist'): if os.path.exists('/etc/%s-release' % dist): exec('from dist.%s import env_inspect' % dist) @@ -119,7 +119,7 @@ class FuncGen(object): start_time = time.strftime("%Y-%m-%d %H:%M:%S") env_logger.info("Checking Testing Environment... ") - envck = env_inspect.EnvInspect(env_logger) + envck = env_inspect.EnvInspect(self.env, env_logger) if envck.env_checking() == 1: sys.exit(1) @@ -157,15 +157,6 @@ class FuncGen(object): clean_ret = -1 try: try: - # Get default uri from env.cfg, if the uri is defined in - # case config file, the value will be overrode. - if 'uri' not in case_params: - case_params['uri'] = self.env.get_value("variables", "defaulturi") - if 'username' not in case_params: - case_params['username'] = self.env.get_value("variables", "username") - if 'password' not in case_params: - case_params['password'] = self.env.get_value("variables", "password") - if case_ref_name != 'sleep': case_params['logger'] = case_logger @@ -211,6 +202,8 @@ class FuncGen(object): else: self.fmt.print_string(21*" " + "Fail", env_logger) + # close hypervisor connection + envck.close_hypervisor_connection() end_time = time.strftime("%Y-%m-%d %H:%M:%S") env_logger.info("\nSummary:") -- 1.7.7.5

An example: #sharedvar.cfg domain:testa domain:testb #testa.py import sharedmod def testa(params): conn = sharedmod.conn logger = params['logger'] logger.info(conn.listNetworks()) sharedmod.defined_var1 = "I am from testa" return 0 #testb.py import sharedmod def testb(params): logger = params['logger'] logger.info(sharedmod.conn.getURI()) logger.info(sharedmod.defined_var1) return 0 The output of 'python libvirt-test-api.py -c sharedvar.cfg Checking Testing Environment... Linux localhost.localdomain 3.2.5-3.fc16.x86_64 #1 SMP Thu Feb 9 01:24:38 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux Virsh command line tool of libvirt: 0.9.10 libvirtd (libvirt) 0.9.10 default uri: qemu:///system QEMU emulator version 0.15.0 (qemu-kvm-0.15.0), Copyright (c) 2003-2008 Fabrice Bellard Start Testing: Case Count: 2 Log File: log/20120406174144/libvirt_test001 domain:testa 17:41:44|INFO |['default'] Result: OK domain:testb 17:41:44|INFO |qemu:///system 17:41:44|INFO |I am from testa Result: OK Summary: Total:2 [Pass:2 Fail:0]

On 2012年04月06日 17:53, Guannan Ren wrote:
An example:
#sharedvar.cfg domain:testa
domain:testb
#testa.py import sharedmod
def testa(params): conn = sharedmod.conn logger = params['logger']
Given that the "connection" object is shared among test cases now, why not "logger" object too?
logger.info(conn.listNetworks()) sharedmod.defined_var1 = "I am from testa" return 0
#testb.py import sharedmod
def testb(params): logger = params['logger'] logger.info(sharedmod.conn.getURI()) logger.info(sharedmod.defined_var1) return 0
The output of 'python libvirt-test-api.py -c sharedvar.cfg
Checking Testing Environment... Linux localhost.localdomain 3.2.5-3.fc16.x86_64 #1 SMP Thu Feb 9 01:24:38 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux Virsh command line tool of libvirt: 0.9.10 libvirtd (libvirt) 0.9.10 default uri: qemu:///system QEMU emulator version 0.15.0 (qemu-kvm-0.15.0), Copyright (c) 2003-2008 Fabrice Bellard
Start Testing: Case Count: 2 Log File: log/20120406174144/libvirt_test001
domain:testa 17:41:44|INFO |['default'] Result: OK
domain:testb 17:41:44|INFO |qemu:///system 17:41:44|INFO |I am from testa Result: OK
Summary: Total:2 [Pass:2 Fail:0]
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 04/16/2012 10:03 AM, Osier Yang wrote:
On 2012年04月06日 17:53, Guannan Ren wrote:
An example:
#sharedvar.cfg domain:testa
domain:testb
#testa.py import sharedmod
def testa(params): conn = sharedmod.conn logger = params['logger']
Given that the "connection" object is shared among test cases now, why not "logger" object too?
It's good idea, but if put the logger object in sharedmod.py the sharedmod.py will have to be included in each testcases right now, it is optional, only the testcase that wants to use the connection object offered by framework should import it. Maybe let me wait for some times until the sharedmod become necessary mod for all testcase, then move logger into it.
participants (3)
-
Guannan Ren
-
Martin Kletzander
-
Osier Yang