Skip to contentSkip to conversation

Some fixes for the testimage class

PATCH Superseded Stefan Stanacar 1 participant 9 messages Jul 12, 2013

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Some fixes for the testimage class

Hello,

Some fixes for the testimage.bbclass and tests.
Also two new tests.

First two patches in the series have already been sent to ML, these are the same. The third one is a modified version of a patch already sent.
The rest of them are new and the should be safe :).

Cheers,
Stefan

The following changes since commit a63229917a5708de2d161aba0d67168ce0da6365:

meta-yocto-bsp: update reference board SRCREVs (2013-07-10 09:45:51 +0100)

are available in the git repository at:

git://mirror.rb.intel.com/git.yoctoproject.org/poky-contrib stefans/oeqa9

for you to fetch changes up to 1dad9f83f59020db8c50a7b0ae6fb2af75496194:

testimage.bbclass, lib/oeqa: add headers and comments (2013-07-12 19:33:52 +0300)

----------------------------------------------------------------
Alexandru Palalau (1):
lib/oeqa/runtime: add tests for syslog and df

Stefan Stanacar (7):
lib/oeqa/runtime/dmesg.py: whitelist dmesg message for systemd net interface name lib/oeqa/utils/sshcontrol.py: fix passing command to subprocess testimage.bbclass, lib/oeqa/utils/qemurunner.py: make boot timeout configurable and increase it lib/oeqa/runtime/multilib.py: use readelf instead of file
lib/oeqa/oetest.py: provide a ps command for all tests classes/testimage.bbclass: use a copy of rootfs for tests
testimage.bbclass, lib/oeqa: add headers and comments

 meta/classes/testimage.bbclass    | 43 +++++++++++++++++++++++++++++++---
 meta/lib/oeqa/oetest.py           | 14 ++++++++---
 meta/lib/oeqa/runtime/connman.py  |  5 ----
 meta/lib/oeqa/runtime/df.py       | 13 +++++++++++
 meta/lib/oeqa/runtime/dmesg.py    |  2 +-
 meta/lib/oeqa/runtime/multilib.py |  9 ++++---
 meta/lib/oeqa/runtime/syslog.py   | 34 +++++++++++++++++++++++++++
 meta/lib/oeqa/utils/decorators.py |  8 +++++++
 meta/lib/oeqa/utils/qemurunner.py | 12 +++++-----
 meta/lib/oeqa/utils/sshcontrol.py | 49 +++++++++++++++++++++------------------
 10 files changed, 145 insertions(+), 44 deletions(-)
 create mode 100644 meta/lib/oeqa/runtime/df.py
 create mode 100644 meta/lib/oeqa/runtime/syslog.py

Alexandru Palalau (1):
lib/oeqa/runtime: add tests for syslog and df

Stefan Stanacar (7):
lib/oeqa/runtime/dmesg.py: whitelist dmesg message for systemd net
interface name
lib/oeqa/utils/sshcontrol.py: fix passing command to subprocess testimage.bbclass, lib/oeqa/utils/qemurunner.py: make boot timeout
configurable and increase it
lib/oeqa/runtime/multilib.py: use readelf instead of file lib/oeqa/oetest.py: provide a ps command for all tests classes/testimage.bbclass: use a copy of rootfs for tests testimage.bbclass, lib/oeqa: add headers and comments

 meta/classes/testimage.bbclass    | 43 +++++++++++++++++++++++++++++++---
 meta/lib/oeqa/oetest.py           | 14 ++++++++---
 meta/lib/oeqa/runtime/connman.py  |  5 ----
 meta/lib/oeqa/runtime/df.py       | 13 +++++++++++
 meta/lib/oeqa/runtime/dmesg.py    |  2 +-
 meta/lib/oeqa/runtime/multilib.py |  9 ++++---
 meta/lib/oeqa/runtime/syslog.py   | 34 +++++++++++++++++++++++++++
 meta/lib/oeqa/utils/decorators.py |  8 +++++++
 meta/lib/oeqa/utils/qemurunner.py | 12 +++++-----
 meta/lib/oeqa/utils/sshcontrol.py | 49 +++++++++++++++++++++------------------
 10 files changed, 145 insertions(+), 44 deletions(-)
 create mode 100644 meta/lib/oeqa/runtime/df.py
 create mode 100644 meta/lib/oeqa/runtime/syslog.py
Signature · 1 line
1.8.1.4
#1 lore raw

PATCH 1/8 lib/oeqa/runtime/dmesg.py: whitelist dmesg message for systemd net interface name

Messages such as:
"systemd-udevd[79]: error changing net interface name eth0 to enp0s3: Device or resource busy" are harmless as systemd can't rename interfaces in qemu (the interface is already active). Alternatively, passing net.ifnames=0 to the kernel will stop systemd renaming the interfaces.

---
 meta/lib/oeqa/runtime/dmesg.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
meta/lib/oeqa/runtime/dmesg.py +1 -1
index b0e2175..48370fb 100644
@@ -9,5 +9,5 @@ class DmesgTest(oeRuntimeTest):
 
     @skipUnlessPassed('test_ssh')
     def test_dmesg(self):
-        (status, output) = self.target.run('dmesg | grep -v mmci-pl18x | grep -i error')
+        (status, output) = self.target.run('dmesg | grep -v mmci-pl18x | grep -v "error changing net interface name" | grep -i error')
         self.assertEqual(status, 1, msg = "Error messages in dmesg log: %s" % output)
Signature · 1 line
1.8.1.4
#2 lore raw

PATCH 2/8 lib/oeqa/utils/sshcontrol.py: fix passing command to subprocess

In reply to Stefan Stanacar

Don't use shlex.split in subprocess call and also prepend . /etc/profile, because PATH over ssh is always /usr/bin:/bin which isn't what many tests expect.

Changed in v2:
We now need to use a separate call for scp command.

---
 meta/lib/oeqa/utils/sshcontrol.py | 40 +++++++++++++++++----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)
meta/lib/oeqa/utils/sshcontrol.py +17 -23
index 85a09a0..6c61caa 100644
@@ -1,7 +1,6 @@
 import subprocess
 import time
 import os
-import shlex
 
 class SSHControl(object):
 
@@ -18,8 +17,12 @@ class SSHControl(object):
                 f.write("%s\n" % msg)
 
     def _internal_run(self, cmd):
+        # We need this for a proper PATH
+        cmd = ". /etc/profile; " + cmd
+        command = ['ssh', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', '-l', 'root', self.host, cmd ]
+        self.log("[Running]$ %s" % " ".join(command))
         # ssh hangs without os.setsid
-        proc = subprocess.Popen(shlex.split(cmd), shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid)
+        proc = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid)
         return proc
 
     def run(self, cmd, timeout=None):
@@ -30,15 +33,12 @@ class SSHControl(object):
 
 
 
-        actualcmd = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l root %s '%s'" % (self.host, cmd)
         if self.host:
-            sshconn = self._internal_run(actualcmd)
+            sshconn = self._internal_run(cmd)
         else:
             raise Exception("Remote IP hasn't been set: '%s'" % actualcmd)
 
         if timeout == 0:
-            self.log("[SSH run without timeout]$ %s" % actualcmd)
-            self.log("  # %s" % cmd)
             self._out = sshconn.communicate()[0]
             self._ret = sshconn.poll()
         else:
@@ -48,8 +48,6 @@ class SSHControl(object):
                 endtime = time.time() + timeout
             while sshconn.poll() is None and time.time() < endtime:
                 time.sleep(1)
-            self.log("[SSH run with timeout]$ %s" % actualcmd)
-            self.log("  # %s" % cmd)
             # process hasn't returned yet
             if sshconn.poll() is None:
                 self._ret = 255
@@ -70,27 +68,23 @@ class SSHControl(object):
         return (self._ret, self._out)
 
     def _internal_scp(self, cmd):
-        self.log("[SCP]$ %s" % cmd)
-        scpconn = self._internal_run(cmd)
-        try:
-            self._out = scpconn.communicate()[0]
-            self._ret = scpconn.poll()
-            if self._ret != 0:
-                self.log("%s" % self._out)
-                raise Exception("Error copying file")
-        except Exception as e:
-            print("Execution failed: %s :" % cmd)
-            print e
-        self.log("%s" % self._out)
-        return (self._ret, self._out)
+        self.log("[Running SCP]$ %s" % " ".join(cmd))
+        scpconn = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid)
+        out = scpconn.communicate()[0]
+        ret = scpconn.poll()
+        self.log("%s" % out)
+        if ret != 0:
+            # we raise an exception so that tests fail in setUp and setUpClass without a need for an assert
+            raise Exception("Error running %s, output: %s" % ( " ".join(cmd), out))
+        return (ret, out)
 
     def copy_to(self, localpath, remotepath):
-        actualcmd = "scp -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no %s root@%s:%s" % (localpath, self.host, remotepath)
+        actualcmd = ['scp', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', localpath, 'root@%s:%s' % (self.host, remotepath)]
         return self._internal_scp(actualcmd)
 
 
     def copy_from(self, remotepath, localpath):
-        actualcmd = "scp -o UserKnownHostsFile=/dev/null  -o StrictHostKeyChecking=no root@%s:%s %s" % (self.host, remotepath, localpath)
+        actualcmd = ['scp', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', 'root@%s:%s' % (self.host, remotepath), localpath]
         return self._internal_scp(actualcmd)
 
     def get_status(self):
Signature · 1 line
1.8.1.4
#3 lore raw

PATCH 3/8 testimage.bbclass, lib/oeqa/utils/qemurunner.py: make boot timeout configurable and increase it

In reply to Stefan Stanacar

On a loaded host (such as an AB setup where multiple builds run) the 200 seconds timeout might not be enough to reach the login prompt. Also make it configurable so we can set it from local.conf/auto.conf

---
 meta/classes/testimage.bbclass    |  6 ++++++
 meta/lib/oeqa/utils/qemurunner.py | 10 +++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)
meta/classes/testimage.bbclass +6 -0
index 35c6811..f66f514 100644
@@ -7,6 +7,8 @@ DEFAULT_TEST_SUITES_pn-core-image-sato-sdk = "ping ssh connman rpm smart gcc xor
 
 TEST_SUITES ?= "${DEFAULT_TEST_SUITES}"
 
+TEST_QEMUBOOT_TIMEOUT ?= "500"
+
 python do_testimage() {
     testimage_main(d)
 }
@@ -65,6 +67,10 @@ def testimage_main(d):
     qemu.tmpdir = d.getVar("TMPDIR", True)
     qemu.display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY", True)
     qemu.logfile = os.path.join(testdir, "qemu_boot_log.%s" % d.getVar('DATETIME', True))
+    try:
+        qemu.boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT", True))
+    except ValueError:
+        qemu.boottime = 500
 
     bb.note("DISPLAY value: %s" % qemu.display)
     bb.note("rootfs file: %s" %  rootfs)
meta/lib/oeqa/utils/qemurunner.py +5 -5
index 3132b68..ec92988 100644
@@ -10,7 +10,7 @@ from oeqa.utils.oeqemuconsole import oeQemuConsole
 
 class QemuRunner:
 
-    def __init__(self, machine, rootfs, display = None, tmpdir = None, logfile = None):
+    def __init__(self, machine, rootfs, display = None, tmpdir = None, logfile = None, boottime = 400):
         # Popen object
         self.runqemu = None
 
@@ -25,6 +25,7 @@ class QemuRunner:
         self.display = display
         self.tmpdir = tmpdir
         self.logfile = logfile
+        self.boottime = boottime
 
     def launch(self, qemuparams = None):
 
@@ -49,7 +50,6 @@ class QemuRunner:
         self.runqemu = subprocess.Popen(launch_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,preexec_fn=os.setpgrp)
 
         bb.note("runqemu started, pid is %s" % self.runqemu.pid)
-        # wait at most 30 seconds until qemu pid appears
         bb.note("waiting at most 60 seconds for qemu pid")
         endtime = time.time() + 60
         while not self.is_alive() and time.time() < endtime:
@@ -59,8 +59,8 @@ class QemuRunner:
             bb.note("qemu started - qemu procces pid is %s" % self.qemupid)
 
             console = oeQemuConsole(self.streampath, self.logfile)
-            bb.note("Waiting at most 200 seconds for login banner")
-            (match, text) = console.read_all_timeout("login:", 200)
+            bb.note("Waiting at most %d seconds for login banner" % self.boottime )
+            (match, text) = console.read_all_timeout("login:", self.boottime)
 
             if match:
                 bb.note("Reached login banner")
@@ -80,7 +80,7 @@ class QemuRunner:
                     return False
             else:
                 console.close()
-                bb.note("Target didn't reached login boot in 120 seconds")
+                bb.note("Target didn't reached login boot in %d seconds" % self.boottime)
                 lines = "\n".join(text.splitlines()[-5:])
                 bb.note("Last 5 lines of text:\n%s" % lines)
                 bb.note("Check full boot log: %s" % self.logfile)
Signature · 1 line
1.8.1.4
#4 lore raw

PATCH 4/8 lib/oeqa/runtime/multilib.py: use readelf instead of file

In reply to Stefan Stanacar

file was pulled by rpm in sato images, readelf comes with binutils so it's in ipk/deb too.
Also the test was looking at connmand instead of connman-applet (which is what the testcase says and the AB nightly-multilib target installs)

---
 meta/lib/oeqa/runtime/multilib.py | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
meta/lib/oeqa/runtime/multilib.py +6 -3
index 397d075..2d952aa 100644
@@ -1,5 +1,6 @@
 import unittest
 from oeqa.oetest import oeRuntimeTest, skipModule
+from oeqa.utils.decorators import *
 
 def setUpModule():
     multilibs = oeRuntimeTest.tc.d.getVar("MULTILIBS", True) or ""
@@ -7,8 +8,10 @@ def setUpModule():
         skipModule("this isn't a multilib:lib32 image")
 
 
-class MultilibFileTest(oeRuntimeTest):
+class MultilibTest(oeRuntimeTest):
 
+    @skipUnlessPassed('test_ssh')
     def test_file_connman(self):
-        (status, output) = self.target.run('file -L /usr/sbin/connmand | grep "ELF 32-bit LSB executable"')
-        self.assertEqual(status, 0, msg="status and output : %s and %s" % (status,output))
+        self.assertTrue(oeRuntimeTest.hasPackage('connman-gnome'), msg="This test assumes connman-gnome is installed")
+        (status, output) = self.target.run("readelf -h /usr/bin/connman-applet | sed -n '3p' | awk '{print $2}'")
+        self.assertEqual(output, "ELF32", msg="connman-applet isn't an ELF32 binary. readelf says: %s" % self.target.run("readelf -h /usr/bin/connman-applet")[1])
Signature · 1 line
1.8.1.4
#5 lore raw

PATCH 5/8 lib/oeqa/oetest.py: provide a ps command for all tests

In reply to Stefan Stanacar

Many tests will use 'ps' but we need to know if it's busybox or standard ps.
Drop the existing check from the connman test.

---
 meta/lib/oeqa/oetest.py          | 5 ++---
 meta/lib/oeqa/runtime/connman.py | 5 -----
 2 files changed, 2 insertions(+), 8 deletions(-)
meta/lib/oeqa/oetest.py +2 -3
index 24548e9..5777ff8 100644
@@ -9,7 +9,8 @@ def runTests(tc):
 
     # set the context object passed from the test class
     setattr(oeRuntimeTest, "tc", tc)
-
+    # set ps command to use
+    setattr(oeRuntimeTest, "pscmd", "ps -ef" if oeRuntimeTest.hasPackage("procps") else "ps")
     # prepare test suite, loader and runner
     suite = unittest.TestSuite()
     testloader = unittest.TestLoader()
@@ -30,7 +31,6 @@ class oeRuntimeTest(unittest.TestCase):
     testFailures = []
     testSkipped = []
     testErrors = []
-    pscmd = "ps"
 
     def __init__(self, methodName='runTest'):
         self.target = oeRuntimeTest.tc.target
@@ -74,7 +74,6 @@ class oeRuntimeTest(unittest.TestCase):
 
 
 
-
 def getmodule(pos=2):
     # stack returns a list of tuples containg frame information
     # First element of the list the is current frame, caller is 1
meta/lib/oeqa/runtime/connman.py +0 -5
index 835e135..5ef96f6 100644
@@ -17,11 +17,6 @@ class ConnmanTest(oeRuntimeTest):
 
     @skipUnlessPassed('test_connmand_help')
     def test_connmand_running(self):
-        status = self.target.run('ls -l `which ps` | grep busybox')[0]
-        if status == 0:
-            oeRuntimeTest.pscmd = 'ps'
-        else:
-            oeRuntimeTest.pscmd = 'ps -ef'
         (status, output) = self.target.run(oeRuntimeTest.pscmd + ' | grep [c]onnmand')
         self.assertEqual(status, 0, msg="no connmand process, ps output: %s" % self.target.run(oeRuntimeTest.pscmd)[1])
 
Signature · 1 line
1.8.1.4
#6 lore raw

PATCH 6/8 lib/oeqa/runtime: add tests for syslog and df

In reply to Stefan Stanacar

From: Alexandru Palalau <[email protected]>

---
 meta/classes/testimage.bbclass  |  4 ++--
 meta/lib/oeqa/runtime/df.py     | 13 +++++++++++++
 meta/lib/oeqa/runtime/syslog.py | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 2 deletions(-)
 create mode 100644 meta/lib/oeqa/runtime/df.py
 create mode 100644 meta/lib/oeqa/runtime/syslog.py
meta/classes/testimage.bbclass +2 -2
index f66f514..22f0a92 100644
@@ -2,8 +2,8 @@ TEST_LOG_DIR ?= "${WORKDIR}/testimage"
 
 DEFAULT_TEST_SUITES = "ping auto"
 DEFAULT_TEST_SUITES_pn-core-image-minimal = "ping"
-DEFAULT_TEST_SUITES_pn-core-image-sato = "ping ssh connman rpm smart xorg dmesg"
-DEFAULT_TEST_SUITES_pn-core-image-sato-sdk = "ping ssh connman rpm smart gcc xorg dmesg"
+DEFAULT_TEST_SUITES_pn-core-image-sato = "ping ssh connman df rpm smart xorg syslog dmesg"
+DEFAULT_TEST_SUITES_pn-core-image-sato-sdk = "ping ssh connman df rpm smart gcc xorg syslog dmesg"
 
 TEST_SUITES ?= "${DEFAULT_TEST_SUITES}"
 
meta/lib/oeqa/runtime/df.py new file +13 -0
new file mode 100644
index 0000000..a781ea4
@@ -0,0 +1,13 @@
+import unittest
+from oeqa.oetest import oeRuntimeTest
+from oeqa.utils.decorators import *
+
+def setUpModule():
+    skipModuleUnless(oeRuntimeTest.tc.target.run('which df')[0] == 0, "No df in image or no connection")
+
+class DfTest(oeRuntimeTest):
+
+    @skipUnlessPassed("test_ssh")
+    def test_df(self):
+        (status,output) = self.target.run("df | awk '{if($1 == \"/dev/root\") print $4}'")
+        self.assertTrue(int(output)>5120, msg="Not enough space on image. Current size is %s" % output)
meta/lib/oeqa/runtime/syslog.py new file +34 -0
new file mode 100644
index 0000000..9259349
@@ -0,0 +1,34 @@
+import unittest
+from oeqa.oetest import oeRuntimeTest, skipModule
+from oeqa.utils.decorators import *
+
+def setUpModule():
+    if not oeRuntimeTest.hasPackage("syslog"):
+        skipModule("No syslog package in image")
+
+class SyslogTest(oeRuntimeTest):
+
+    @skipUnlessPassed("test_ssh")
+    def test_syslog_help(self):
+        (status,output) = self.target.run('/sbin/syslogd --help')
+        self.assertEqual(status, 1, msg="status and output: %s and %s" % (status,output))
+
+    @skipUnlessPassed("test_syslog_help")
+    def test_syslogd_running(self):
+        (status,output) = self.target.run(oeRuntimeTest.pscmd + ' | grep -i [s]yslogd')
+        self.assertEqual(status, 0, msg="no syslogd process, ps output: %s" % self.target.run(oeRuntimeTest.pscmd)[1])
+
+class SyslogTestConfig(oeRuntimeTest):
+
+    def setUp(self):
+        self.target.run('echo "LOGFILE=/var/log/test" >> /etc/syslog-startup.conf')
+
+    @skipUnlessPassed("test_syslogd_running")
+    def test_syslogd_configurable(self):
+        (status,output) = self.target.run('/etc/init.d/syslog restart')
+        self.assertEqual(status, 0, msg="Could not restart syslog service. Status and output: %s and %s" % (status,output))
+        (status,output) = self.target.run('logger foobar && grep foobar /var/log/test')
+        self.assertEqual(status, 0, msg="Test log string not found. Output: %s " % output)
+
+    def tearDown(self):
+        self.target.run("sed -i 's#LOGFILE=/var/log/test##' /etc/syslog-startup.conf")
Signature · 1 line
1.8.1.4
#7 lore raw

PATCH 7/8 classes/testimage.bbclass: use a copy of rootfs for tests

In reply to Stefan Stanacar

Make a copy of the rootfs and test that.
We can now drop the snapshot option.

---
 meta/classes/testimage.bbclass    | 9 ++++++++-
 meta/lib/oeqa/utils/qemurunner.py | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)
meta/classes/testimage.bbclass +8 -1
index 22f0a92..940520f 100644
@@ -22,6 +22,7 @@ def testimage_main(d):
     import os
     import oeqa.runtime
     import re
+    import shutil
     from oeqa.oetest import runTests
     from oeqa.utils.sshcontrol import SSHControl
     from oeqa.utils.qemurunner import QemuRunner
@@ -61,7 +62,13 @@ def testimage_main(d):
     # and boot each supported fs type
     machine=d.getVar("MACHINE", True)
     #will handle fs type eventually, stick with ext3 for now
-    rootfs=d.getVar("DEPLOY_DIR_IMAGE", True) + '/' + d.getVar("IMAGE_BASENAME",True) + '-' + machine + '.ext3'
+    #make a copy of the original rootfs and use that for tests
+    origrootfs=os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True),  d.getVar("IMAGE_LINK_NAME",True) + '.ext3')
+    rootfs=os.path.join(testdir, d.getVar("IMAGE_LINK_NAME", True) + '-testimage.ext3')
+    try:
+        shutil.copyfile(origrootfs, rootfs)
+    except Exception as e:
+        bb.fatal("Error copying rootfs: %s" % e)
 
     qemu = QemuRunner(machine, rootfs)
     qemu.tmpdir = d.getVar("TMPDIR", True)
meta/lib/oeqa/utils/qemurunner.py +1 -1
index ec92988..1051b2b 100644
@@ -18,7 +18,7 @@ class QemuRunner:
         self.rootfs = rootfs
 
         self.streampath = '/tmp/qemuconnection.%s' % os.getpid()
-        self.qemuparams = 'bootparams="console=ttyS0" qemuparams="-snapshot -serial unix:%s,server,nowait"' % self.streampath
+        self.qemuparams = 'bootparams="console=ttyS0" qemuparams="-serial unix:%s,server,nowait"' % self.streampath
         self.qemupid = None
         self.ip = None
 
Signature · 1 line
1.8.1.4
#8 lore raw

PATCH 8/8 testimage.bbclass, lib/oeqa: add headers and comments

In reply to Stefan Stanacar

Adds some comments to testimage.bbclass and the files it calls, just to give an ideea of what it does.

---
 meta/classes/testimage.bbclass    | 24 ++++++++++++++++++++++++
 meta/lib/oeqa/oetest.py           |  9 +++++++++
 meta/lib/oeqa/utils/decorators.py |  8 ++++++++
 meta/lib/oeqa/utils/sshcontrol.py |  9 +++++++++
 4 files changed, 50 insertions(+)
meta/classes/testimage.bbclass +24 -0
index 940520f..903849d 100644
@@ -1,3 +1,27 @@
+# Copyright (C) 2013 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+
+# testimage.bbclass enables testing of qemu images using python unittests.
+# Most of the tests are commands run on target image over ssh.
+# To use it add testimage to global inherit and call your target image with -c testimage
+# You can try it out like this:
+# - first build a qemu core-image-sato
+# - add INHERIT += "testimage" in local.conf
+# - then bitbake core-image-sato -c testimage. That will run a standard suite of tests.
+
+# You can set (or append to) TEST_SUITES in local.conf to select the tests
+# which you want to run for your target.
+# The test names are the module names in meta/lib/oeqa/runtime.
+# Each name in TEST_SUITES represents a required test for the image. (no skipping allowed)
+# Appending "auto" means that it will try to run all tests that are suitable for the image (each test decides that on it's own).
+# Note that order in TEST_SUITES is important (it's the order tests run) and it influences tests dependencies.
+
+# TEST_LOG_DIR contains a ssh log (what command is running, output and return codes) and a qemu boot log till login
+# Booting is handled by this class, and it's not a test in itself.
+# TEST_QEMUBOOT_TIMEOUT can be used to set the maximum time in seconds the launch code will wait for the login prompt.
+
 TEST_LOG_DIR ?= "${WORKDIR}/testimage"
 
 DEFAULT_TEST_SUITES = "ping auto"
meta/lib/oeqa/oetest.py +9 -0
index 5777ff8..7f6baa4 100644
@@ -1,3 +1,12 @@
+# Copyright (C) 2013 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+# Main unittest module used by testimage.bbclass
+# This provides the oeRuntimeTest base class which is inherited by all tests in meta/lib/oeqa/runtime.
+
+# It also has some helper functions and it's responsible for actually starting the tests
+
 import os, re, mmap
 import unittest
 import inspect
meta/lib/oeqa/utils/decorators.py +8 -0
index 21e6b22..adec65e 100644
@@ -1,3 +1,11 @@
+# Copyright (C) 2013 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+# Some custom decorators that can be used by unittests
+# Most useful is skipUnlessPassed which can be used for
+# creating dependecies between two test methods.
+
 from oeqa.oetest import *
 
 class skipIfFailure(object):
meta/lib/oeqa/utils/sshcontrol.py +9 -0
index 6c61caa..8f98c45 100644
@@ -1,3 +1,12 @@
+# Copyright (C) 2013 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+# Provides a class for setting up ssh connections,
+# running commands and copying files to/from a target.
+# It's used by testimage.bbclass and tests in lib/oeqa/runtime.
+
+
 import subprocess
 import time
 import os
Signature · 1 line
1.8.1.4