[OE-core] [PATCH 3/3] oeqa/runtime: Automatic test for ptest
Lucian Musat
georgex.l.musat at intel.com
Fri Aug 29 13:51:06 UTC 2014
For images without ptest the packages are automatically installed alongside ptest-runner. Log results are saved in ./results folder.
No cleanup is done for packages after the test is finished.
Signed-off-by: Stefan Stanacar <stefanx.stanacar at intel.com>
Signed-off-by: Lucian Musat <georgex.l.musat at intel.com>
---
meta/lib/oeqa/runtime/_ptest.py | 140 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
create mode 100644 meta/lib/oeqa/runtime/_ptest.py
diff --git a/meta/lib/oeqa/runtime/_ptest.py b/meta/lib/oeqa/runtime/_ptest.py
new file mode 100644
index 0000000..cd1e4ad
--- /dev/null
+++ b/meta/lib/oeqa/runtime/_ptest.py
@@ -0,0 +1,140 @@
+import unittest, os, shutil
+from oeqa.oetest import oeRuntimeTest, skipModule
+from oeqa.utils.decorators import *
+from oeqa.utils.logparser import *
+from oeqa.utils.httpserver import HTTPService
+from difflib import SequenceMatcher
+
+def setUpModule():
+ if not oeRuntimeTest.hasFeature("package-management"):
+ skipModule("Image doesn't have package management feature")
+ if not oeRuntimeTest.hasPackage("smart"):
+ skipModule("Image doesn't have smart installed")
+ if "package_rpm" != oeRuntimeTest.tc.d.getVar("PACKAGE_CLASSES", True).split()[0]:
+ skipModule("Rpm is not the primary package manager")
+
+class PtestRunnerTest(oeRuntimeTest):
+
+ # a ptest log parser
+ def parse_ptest(logfile):
+ parser = Lparser(test_0_pass_regex="^PASS:(.+)", test_0_fail_regex="^FAIL:(.+)", section_0_begin_regex="^BEGIN: .*/(.+)/ptest", section_0_end_regex="^END: .*/(.+)/ptest")
+ parser.init()
+ result = Result()
+
+ with open(logfile) as f:
+ for line in f:
+ result_tuple = parser.parse_line(line)
+ if not result_tuple:
+ continue
+ result_tuple = line_type, category, status, name = parser.parse_line(line)
+
+ if line_type == 'section' and status == 'begin':
+ current_section = name
+ continue
+
+ if line_type == 'section' and status == 'end':
+ current_section = None
+ continue
+
+ if line_type == 'test' and status == 'pass':
+ result.store(current_section, name, status)
+ continue
+
+ if line_type == 'test' and status == 'fail':
+ result.store(current_section, name, status)
+ continue
+
+ result.sort_tests()
+ return result
+
+ @classmethod
+ def setUpClass(self):
+ #note the existing channels that are on the board before creating new ones
+ self.existingchannels = set()
+ (status, result) = oeRuntimeTest.tc.target.run('smart channel --show | grep "\["', 0)
+ for x in result.split("\n"):
+ self.existingchannels.add(x)
+ self.repo_server = HTTPService(oeRuntimeTest.tc.d.getVar('DEPLOY_DIR', True), oeRuntimeTest.tc.target.server_ip)
+ self.repo_server.start()
+ (status, result) = oeRuntimeTest.tc.target.run('smart query', 0)
+ self.packagelist = result
+ if self.packagelist == "":
+ raise AssertionError("Cannot get package list!")
+ self.pkglist = self.packagelist.split("\n")
+
+ @classmethod
+ def tearDownClass(self):
+ self.repo_server.stop()
+ #remove created channels to be able to repeat the tests on same image
+ (status, result) = oeRuntimeTest.tc.target.run('smart channel --show | grep "\["', 0)
+ for x in result.split("\n"):
+ if x not in self.existingchannels:
+ oeRuntimeTest.tc.target.run('smart channel --remove '+x[1:-1]+' -y', 0)
+
+ def add_smart_channel(self):
+ image_pkgtype = self.tc.d.getVar('IMAGE_PKGTYPE', True)
+ deploy_url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, image_pkgtype)
+ pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS', True).replace("-","_").split()
+ for arch in os.listdir('%s/%s' % (self.repo_server.root_dir, image_pkgtype)):
+ if arch in pkgarchs:
+ self.target.run('smart channel -y --add {a} type=rpm-md baseurl={u}/{a}'.format(a=arch, u=deploy_url), 0)
+ self.target.run('smart update', 0)
+
+ def get_ptest_packages(self):
+ pkgs = set()
+ image_pkgtype = self.tc.d.getVar('IMAGE_PKGTYPE', True)
+ pkgarchs = self.tc.d.getVar('PACKAGE_ARCHS', True).replace("-","_").split()
+ for arch in pkgarchs:
+ folder = self.repo_server.root_dir+"/"+image_pkgtype+'/'+arch
+ if (os.path.isdir(folder)):
+ for fil in os.listdir(folder):
+ if ("ptest" in str(fil) and "ptest-runner" not in str(fil)):
+ #get all the packages with -ptest in the name and remove ptest from them for future comparisons
+ filez = "".join(str(fil).split("-ptest"))
+ rootfilez = ".".join(filez.split(".")[:-2])
+ filex = str(fil).split("-ptest")[0]
+ #compare with all the packages installed on the board and get a list of potential matches
+ if filex in self.packagelist:
+ i = 0
+ matches = []
+ while i<len(self.pkglist):
+ if filex in self.pkglist[i]:
+ matches.append(self.pkglist[i])
+ i +=1
+ for i in matches:
+ #sometimes package names differ from corresponding ptest package names (ex. libacl1 != acl-ptest) so we use the Source field from smart info to compare
+ (status, result) = self.target.run("smart info "+i,0)
+ rootpkg = re.search("(.*Source:.*)", result).group(1).split(":")[1][1:]
+ #even source package names mai differ a little so we do a fuzzy string match (ex. libz-1.2.8-r0 -> zlib-1.2.8-r0)
+ m = SequenceMatcher(None, rootpkg, rootfilez)
+ if (m.ratio > 0.9):
+ filey = "".join(str(fil).split("-ptest")[0])+"-ptest"
+ pkgs.add(filey)
+ if str(pkgs) == "set([])":
+ raise AssertionError("Cannot get ptest packages to install!")
+ pkgs.add("ptest-runner")
+ return pkgs
+
+ def setUp(self):
+ self.buildhist_dir = oeRuntimeTest.tc.d.getVar("BUILDHISTORY_DIR_IMAGE", True)
+ self.assertTrue(os.path.exists(self.buildhist_dir))
+ self.ptest_log = os.path.join(oeRuntimeTest.tc.d.getVar("TEST_LOG_DIR",True), "ptest-%s.log" % oeRuntimeTest.tc.d.getVar('DATETIME', True))
+
+ @skipUnlessPassed('test_ssh')
+ def test_ptestrunner(self):
+ self.add_smart_channel()
+ self.install_packages(list(self.get_ptest_packages()))
+
+ self.target.run('/usr/bin/ptest-runner > /tmp/ptest.log 2>&1', 0)
+ self.target.copy_from('/tmp/ptest.log', self.ptest_log)
+ shutil.copyfile(self.ptest_log, os.path.join(self.buildhist_dir, "ptest.log"))
+
+ result = self.parse_ptest(os.path.join(self.buildhist_dir, "ptest.log"))
+ log_results_to_location = os.path.join('./results')
+ if not os.path.exists(log_results_to_location):
+ os.makedirs(log_results_to_location)
+
+ # clear the results directory each time
+ for path in os.listdir(log_results_to_location):
+ os.remove(os.path.join(log_results_to_location, path))
+ result.log_as_files(log_results_to_location, test_status = ['fail'])
--
1.9.1
More information about the Openembedded-core
mailing list