Files
poky/meta/lib/oeqa/runtime/systemd.py
Benjamin Esquivel 23083e7e5e oeqa/systemd: get runtest target boot time and log
oeqa.runtime.systemd.SystemdJournalTests.test_systemd_boot_time
this test will query the target boot time from journactl and will
print it to the output, if the time is obtained, the test passes

it then compares the boot time against the default systemd's
timeout TimeoutStartSec and if the boot time is greater than the
it will print it too

this test prints the startup time in the test log like:
...
test_systemd_boot_time (oeqa.runtime.systemd.SystemdJournalTests) ...
Startup finished in 6.922s (kernel) + 52.089s (userspace) = 59.011s.

(From OE-Core rev: 59c6c13a8fa1bfc8e0615463e00ccdef04a87a47)

Signed-off-by: Benjamin Esquivel <benjamin.esquivel@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-12 23:42:51 +00:00

177 lines
7.0 KiB
Python

import unittest
import re
from oeqa.oetest import oeRuntimeTest, skipModule
from oeqa.utils.decorators import *
def setUpModule():
if not oeRuntimeTest.hasFeature("systemd"):
skipModule("target doesn't have systemd in DISTRO_FEATURES")
if "systemd" != oeRuntimeTest.tc.d.getVar("VIRTUAL-RUNTIME_init_manager", True):
skipModule("systemd is not the init manager for this image")
class SystemdTest(oeRuntimeTest):
def systemctl(self, action = '', target = '', expected = 0, verbose = False):
command = 'systemctl %s %s' % (action, target)
status, output = self.target.run(command)
message = '\n'.join([command, output])
if status != expected and verbose:
message += self.target.run('systemctl status --full %s' % target)[1]
self.assertEqual(status, expected, message)
return output
#TODO: use pyjournalctl instead
def journalctl(self, args='',l_match_units=[]):
"""
Request for the journalctl output to the current target system
Arguments:
-args, an optional argument pass through argument
-l_match_units, an optional list of units to filter the output
Returns:
-string output of the journalctl command
Raises:
-AssertionError, on remote commands that fail
-ValueError, on a journalctl call with filtering by l_match_units that
returned no entries
"""
query_units=""
if len(l_match_units):
query_units = ['_SYSTEMD_UNIT='+unit for unit in l_match_units]
query_units = " ".join(query_units)
command = 'journalctl %s %s' %(args, query_units)
status, output = self.target.run(command)
if status:
raise AssertionError("Command '%s' returned non-zero exit \
code %d:\n%s" % (command, status, output))
if len(output) == 1 and "-- No entries --" in output:
raise ValueError("List of units to match: %s, returned no entries"
% l_match_units)
return output
class SystemdBasicTests(SystemdTest):
@skipUnlessPassed('test_ssh')
def test_systemd_basic(self):
self.systemctl('--version')
@testcase(551)
@skipUnlessPassed('test_system_basic')
def test_systemd_list(self):
self.systemctl('list-unit-files')
def settle(self):
"""
Block until systemd has finished activating any units being activated,
or until two minutes has elapsed.
Returns a tuple, either (True, '') if all units have finished
activating, or (False, message string) if there are still units
activating (generally, failing units that restart).
"""
import time
endtime = time.time() + (60 * 2)
while True:
status, output = self.target.run('systemctl --state=activating')
if "0 loaded units listed" in output:
return (True, '')
if time.time() >= endtime:
return (False, output)
time.sleep(10)
@testcase(550)
@skipUnlessPassed('test_systemd_basic')
def test_systemd_failed(self):
settled, output = self.settle()
self.assertTrue(settled, msg="Timed out waiting for systemd to settle:\n" + output)
output = self.systemctl('list-units', '--failed')
match = re.search("0 loaded units listed", output)
if not match:
output += self.systemctl('status --full --failed')
self.assertTrue(match, msg="Some systemd units failed:\n%s" % output)
class SystemdServiceTests(SystemdTest):
def check_for_avahi(self):
if not self.hasPackage('avahi-daemon'):
raise unittest.SkipTest("Testcase dependency not met: need avahi-daemon installed on target")
@skipUnlessPassed('test_systemd_basic')
def test_systemd_status(self):
self.check_for_avahi()
self.systemctl('status --full', 'avahi-daemon.service')
@testcase(695)
@skipUnlessPassed('test_systemd_status')
def test_systemd_stop_start(self):
self.check_for_avahi()
self.systemctl('stop', 'avahi-daemon.service')
self.systemctl('is-active', 'avahi-daemon.service', expected=3, verbose=True)
self.systemctl('start','avahi-daemon.service')
self.systemctl('is-active', 'avahi-daemon.service', verbose=True)
@testcase(696)
@skipUnlessPassed('test_systemd_basic')
def test_systemd_disable_enable(self):
self.check_for_avahi()
self.systemctl('disable', 'avahi-daemon.service')
self.systemctl('is-enabled', 'avahi-daemon.service', expected=1)
self.systemctl('enable', 'avahi-daemon.service')
self.systemctl('is-enabled', 'avahi-daemon.service')
class SystemdJournalTests(SystemdTest):
@skipUnlessPassed('test_ssh')
def test_systemd_journal(self):
(status, output) = self.target.run('journalctl')
self.assertEqual(status, 0, output)
@skipUnlessPassed('test_systemd_basic')
def test_systemd_boot_time(self, systemd_TimeoutStartSec=90):
"""
Get the target boot time from journalctl and log it
Arguments:
-systemd_TimeoutStartSec, an optional argument containing systemd's
unit start timeout to compare against
"""
# the expression chain that uniquely identifies the time boot message
expr_items=["Startup finished","kernel", "userspace","\.$"]
try:
output = self.journalctl(args="-o cat --reverse")
except AssertionError:
self.fail("Error occurred while calling journalctl")
if not len(output):
self.fail("Error: unable to obtain the startup time from\
systemd journal")
# check for the regular expression items that match the startup time
for line in output.split('\n'):
check_match = "".join(re.findall(".*".join(expr_items), line))
if check_match: break
# put the startup time in the test log
if check_match:
print "%s" % check_match
else:
self.fail("Error while obtaining the boot time from journalctl")
boot_time_sec = 0
# get the numeric values from the string and convert them to seconds
# same data will be placed in list and string for manipulation
l_boot_time = check_match.split(" ")[-2:]
s_boot_time = " ".join(l_boot_time)
# Obtain the minutes it took to boot
if l_boot_time[0].endswith('min') and l_boot_time[0][0].isdigit():
boot_time_min = s_boot_time.split("min")[0]
# convert to seconds and accumulate it
boot_time_sec += int(boot_time_min) * 60
# Obtain the seconds it took to boot and accumulate
boot_time_sec += float(l_boot_time[1].split("s")[0])
#Assert the target boot time against systemd's unit start timeout
if boot_time_sec > systemd_TimeoutStartSec:
print "Target boot time %s exceeds systemd's TimeoutStartSec %s"\
%(boot_time_sec, systemd_TimeoutStartSec)