Yocto 2.3

Move OpenBMC to Yocto 2.3(pyro).

Tested: Built and verified Witherspoon and Palmetto images
Change-Id: I50744030e771f4850afc2a93a10d3507e76d36bc
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Resolves: openbmc/openbmc#2461
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/systemd.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/systemd.py
new file mode 100644
index 0000000..db69384
--- /dev/null
+++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/cases/systemd.py
@@ -0,0 +1,181 @@
+import re
+import time
+
+from oeqa.runtime.case import OERuntimeTestCase
+from oeqa.core.decorator.depends import OETestDepends
+from oeqa.core.decorator.oeid import OETestID
+from oeqa.core.decorator.data import skipIfDataVar, skipIfNotDataVar
+from oeqa.runtime.decorator.package import OEHasPackage
+from oeqa.core.decorator.data import skipIfNotFeature
+
+class SystemdTest(OERuntimeTestCase):
+
+    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:
+            cmd = 'systemctl status --full %s' % target
+            message += self.target.run(cmd)[1]
+        self.assertEqual(status, expected, message)
+        return output
+
+    #TODO: use pyjournalctl instead
+    def journalctl(self, args='',l_match_units=None):
+        """
+        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 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):
+
+    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).
+        """
+        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)
+
+    @skipIfNotFeature('systemd',
+                      'Test requires systemd to be in DISTRO_FEATURES')
+    @skipIfNotDataVar('VIRTUAL-RUNTIME_init_manager', 'systemd',
+                      'systemd is not the init manager for this image')
+    @OETestDepends(['ssh.SSHTest.test_ssh'])
+    def test_systemd_basic(self):
+        self.systemctl('--version')
+
+    @OETestID(551)
+    @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
+    def test_systemd_list(self):
+        self.systemctl('list-unit-files')
+
+    @OETestID(550)
+    @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
+    def test_systemd_failed(self):
+        settled, output = self.settle()
+        msg = "Timed out waiting for systemd to settle:\n%s" % output
+        self.assertTrue(settled, msg=msg)
+
+        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):
+
+    @OEHasPackage(['avahi-daemon'])
+    @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
+    def test_systemd_status(self):
+        self.systemctl('status --full', 'avahi-daemon.service')
+
+    @OETestID(695)
+    @OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
+    def test_systemd_stop_start(self):
+        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)
+
+    @OETestID(696)
+    @OETestDepends(['systemd.SystemdServiceTests.test_systemd_status'])
+    def test_systemd_disable_enable(self):
+        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):
+
+    @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic'])
+    def test_systemd_journal(self):
+        status, output = self.target.run('journalctl')
+        self.assertEqual(status, 0, output)
+
+    @OETestDepends(['systemd.SystemdBasicTests.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 get 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:
+            self.tc.logger.info('%s' % check_match)
+        else:
+            self.skipTest('Error at 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)
+        try:
+            # 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])
+        except ValueError:
+            self.skipTest('Error when parsing time from boot string')
+
+        # Assert the target boot time against systemd's unit start timeout.
+        if boot_time_sec > systemd_TimeoutStartSec:
+            msg = ("Target boot time %s exceeds systemd's TimeoutStartSec %s"
+                    % (boot_time_sec, systemd_TimeoutStartSec))
+            self.tc.logger.info(msg)