[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