added tests

Change-Id: I337664f5862b6f84355d17008140c6ccee8d1c6d
diff --git a/tests/ansible-test b/tests/ansible-test
new file mode 100755
index 0000000..4cf46ec
--- /dev/null
+++ b/tests/ansible-test
@@ -0,0 +1,15 @@
+#!/usr/bin/env ansible-playbook
+---
+- hosts: localhost
+  remote_user: root
+
+  tasks:
+  - name: Install the requirements
+    package: 
+      name: "{{item}}" 
+      state: latest
+    with_items:
+      - systemd
+ 
+  - name: Execute the tests
+    shell: systemctl 2>&1 | tee output
\ No newline at end of file
diff --git a/tests/assert.sh b/tests/assert.sh
new file mode 100644
index 0000000..eccc338
--- /dev/null
+++ b/tests/assert.sh
@@ -0,0 +1,25 @@
+# utility functions for shell tests
+
+assert_true() {
+    if ! $1; then
+        echo "FAIL: command '$1' failed with exit code $?" >&2
+        exit 1
+    fi
+}
+
+
+assert_eq() {
+    if [ "$1" != "$2" ]; then
+        echo "FAIL: expected: '$2' actual: '$1'" >&2
+        exit 1
+    fi
+}
+
+assert_in() {
+    if ! echo "$2" | grep -q "$1"; then
+        echo "FAIL: '$1' not found in:" >&2
+        echo "$2" >&2
+        exit 1
+    fi
+}
+
diff --git a/tests/control b/tests/control
new file mode 100644
index 0000000..006e17c
--- /dev/null
+++ b/tests/control
@@ -0,0 +1,18 @@
+Tests: timedated, hostnamed
+Depends: systemd,
+  acl,
+  tzdata,
+Restrictions: needs-root, isolation-container
+
+Tests: unit-config
+Depends: systemd,
+  acl,
+  python3,
+  pkg-config,
+Restrictions: needs-root, allow-stderr
+
+Tests: ansible-test
+Depends: systemd,
+  ansible,
+  python2-dnf,
+Restrictions: needs-root, allow-stderr
diff --git a/tests/hostnamed b/tests/hostnamed
new file mode 100755
index 0000000..1b22869
--- /dev/null
+++ b/tests/hostnamed
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -e
+
+. `dirname $0`/assert.sh
+
+ORIG_HOST=`cat /etc/hostname`
+echo "original hostname: $ORIG_HOST"
+
+# should activate daemon and work
+STATUS="`hostnamectl`"
+assert_in "Static hostname: $ORIG_HOST" "$STATUS"
+assert_in "Kernel:.* `uname -r`" "$STATUS"
+
+# change hostname
+assert_eq "`hostnamectl set-hostname testhost 2>&1`" ""
+assert_eq "`cat /etc/hostname`" "testhost"
+assert_in "Static hostname: testhost" "`hostnamectl`"
+
+# reset to original
+assert_eq "`hostnamectl set-hostname $ORIG_HOST 2>&1`" ""
+assert_eq "`cat /etc/hostname`" "$ORIG_HOST"
+assert_in "Static hostname: $ORIG_HOST" "`hostnamectl`"
diff --git a/tests/timedated b/tests/timedated
new file mode 100755
index 0000000..90a9053
--- /dev/null
+++ b/tests/timedated
@@ -0,0 +1,21 @@
+#!/bin/sh
+set -e
+
+. `dirname $0`/assert.sh
+
+ORIG_TZ=$(timedatectl | grep -F 'Time zone'|sed -e 's@.*: @@' -e 's@ .*@@')
+echo "original tz: $ORIG_TZ"
+
+echo 'timedatectl works'
+assert_in "Local time:" "`timedatectl --no-pager`"
+
+echo 'change timezone'
+assert_eq "`timedatectl --no-pager set-timezone Europe/Moscow 2>&1`" ""
+assert_eq "`readlink /etc/localtime | sed 's#^.*zoneinfo/##'`" "Europe/Moscow"
+[ -n "$TEST_UPSTREAM" ] || assert_in "Europe/Moscow" "`timedatectl | grep -F 'Time zone: '`"
+assert_in "Time.*zone: Europe/Moscow (MSK, +" "`timedatectl --no-pager`"
+
+echo 'reset timezone to original'
+assert_eq "`timedatectl  --no-pager set-timezone $ORIG_TZ 2>&1`" ""
+assert_eq "`readlink /etc/localtime | sed 's#^.*zoneinfo/##'`" "$ORIG_TZ"
+[ -n "$TEST_UPSTREAM" ] || assert_eq "`timedatectl | grep -F 'Time zone'|sed -e 's@.*: @@' -e 's@ .*@@'`" "$ORIG_TZ"
diff --git a/tests/unit-config b/tests/unit-config
new file mode 100755
index 0000000..986c2f0
--- /dev/null
+++ b/tests/unit-config
@@ -0,0 +1,370 @@
+#!/usr/bin/python3
+# autopkgtest check: enable/disable/configure units
+# (C) 2015 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt@ubuntu.com>
+
+import unittest
+import subprocess
+import os
+import sys
+import tempfile
+from glob import glob
+
+system_unit_dir = subprocess.check_output(
+    ['pkg-config', '--variable=systemdsystemunitdir', 'systemd'],
+    universal_newlines=True).strip()
+systemd_sysv_install = os.path.join(os.path.dirname(system_unit_dir),
+                                    'systemd-sysv-install')
+
+
+class EnableTests(unittest.TestCase):
+    def tearDown(self):
+        # remove all traces from our test unit
+        f = glob(system_unit_dir + '/test_enable*.service')
+        f += glob(system_unit_dir + '/*/test_enable*.service')
+        f += glob('/etc/systemd/system/test_enable*.service')
+        f += glob('/etc/systemd/system/*/test_enable*.service')
+        f += glob('/etc/init.d/test_enable*')
+        f += glob('/etc/rc?.d/???test_enable*')
+        [os.unlink(i) for i in f]
+        subprocess.check_call(['systemctl', 'daemon-reload'])
+
+    def create_unit(self, suffix='', enable=False):
+        '''Create a test unit'''
+
+        unit = os.path.join(system_unit_dir,
+                            'test_enable%s.service' % suffix)
+        with open(unit, 'w') as f:
+            f.write('''[Unit]
+Description=Testsuite unit %s
+[Service]
+ExecStart=/bin/echo hello
+[Install]
+WantedBy=multi-user.target
+''' % suffix)
+
+        if enable:
+            os.symlink(unit, '/etc/systemd/system/multi-user.target.wants/' +
+                       os.path.basename(unit))
+
+        return unit
+
+    def create_sysv(self, suffix='', enable=False):
+        '''Create a test SysV script'''
+
+        script = '/etc/init.d/test_enable%s' % suffix
+        with open(script, 'w') as f:
+            f.write('''/bin/sh
+### BEGIN INIT INFO
+# Provides:          test_enable%s
+# Required-Start:    $remote_fs $syslog
+# Required-Stop:     $remote_fs $syslog
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Testsuite script%s
+### END INIT INFO
+
+echo hello
+''' % (suffix, suffix))
+        os.chmod(script, 0o755)
+
+        if enable:
+            subprocess.check_call(
+                [systemd_sysv_install, 'enable', os.path.basename(script)])
+
+    def assertEnabled(self, enabled, unit='test_enable.service'):
+        '''assert that given unit has expected state'''
+
+        systemctl = subprocess.Popen(['systemctl', 'is-enabled', unit],
+                                     stdout=subprocess.PIPE,
+                                     universal_newlines=True)
+        out = systemctl.communicate()[0].strip()
+        if enabled:
+            self.assertEqual(systemctl.returncode, 0)
+            self.assertEqual(out, 'enabled')
+        else:
+            self.assertEqual(systemctl.returncode, 1)
+            self.assertEqual(out, 'disabled')
+
+    def test_unit_enable(self):
+        '''no sysv: enable unit'''
+
+        self.create_unit()
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         system_unit_dir + '/test_enable.service')
+
+        # enable should be idempotent
+        subprocess.check_call(['systemctl', 'enable', 'test_enable.service'])
+        self.assertEnabled(True)
+
+    def test_unit_disable(self):
+        '''no sysv: disable unit'''
+
+        self.create_unit(enable=True)
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # disable should be idempotent
+        subprocess.check_call(['systemctl', 'disable', 'test_enable.service'])
+        self.assertEnabled(False)
+
+    def test_unit_sysv_enable(self):
+        '''with sysv: enable unit'''
+
+        self.create_unit()
+        self.create_sysv()
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         system_unit_dir + '/test_enable.service')
+
+        # enabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(len(l), 1, 'expect one symlink in %s' % repr(l))
+        self.assertEqual(os.readlink(l[0]), '../init.d/test_enable')
+
+        # enable should be idempotent
+        subprocess.check_call(['systemctl', 'enable', 'test_enable.service'])
+        self.assertEnabled(True)
+
+    def test_unit_sysv_disable(self):
+        '''with sysv: disable unit'''
+
+        self.create_unit(enable=True)
+        self.create_sysv(enable=True)
+        self.assertEnabled(True)
+        # also works without .service suffix
+        self.assertEnabled(True, unit='test_enable')
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        self.assertEnabled(False)
+        # also works without .service suffix
+        self.assertEnabled(False, unit='test_enable')
+
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # disabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(l, [])
+
+        # disable should be idempotent
+        subprocess.check_call(['systemctl', 'enable', 'test_enable.service'])
+        self.assertEnabled(True)
+
+    def test_unit_alias_enable(self):
+        '''no sysv: enable unit with an alias'''
+
+        u = self.create_unit()
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+
+        self.assertEnabled(False)
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        self.assertEnabled(True)
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         system_unit_dir + '/test_enable.service')
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         system_unit_dir + '/test_enable.service')
+
+    def test_unit_alias_disable(self):
+        '''no sysv: disable unit with an alias'''
+
+        u = self.create_unit()
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+        os.symlink(system_unit_dir + '/test_enable.service',
+                   '/etc/systemd/system/test_enablea.service')
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        self.assertEnabled(False)
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertFalse(os.path.islink(l))
+
+    def test_unit_sysv_alias_enable(self):
+        '''with sysv: enable unit with an alias'''
+
+        u = self.create_unit()
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+        self.create_sysv()
+
+        self.assertEnabled(False)
+
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         system_unit_dir + '/test_enable.service')
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertTrue(os.path.islink(l))
+        self.assertEqual(os.readlink(l),
+                         system_unit_dir + '/test_enable.service')
+
+        # enabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(len(l), 1, 'expect one symlink in %s' % repr(l))
+        self.assertEqual(os.readlink(l[0]), '../init.d/test_enable')
+
+        self.assertEnabled(True)
+
+    def test_unit_sysv_alias_disable(self):
+        '''with sysv: disable unit with an alias'''
+
+        u = self.create_unit(enable=True)
+        with open(u, 'a') as f:
+            f.write('Alias=test_enablea.service\n')
+        os.symlink(system_unit_dir + '/test_enable.service',
+                   '/etc/systemd/system/test_enablea.service')
+        self.create_sysv(enable=True)
+
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        # enablement symlink
+        l = '/etc/systemd/system/multi-user.target.wants/test_enable.service'
+        self.assertFalse(os.path.islink(l))
+
+        # alias symlink
+        l = '/etc/systemd/system/test_enablea.service'
+        self.assertFalse(os.path.islink(l))
+
+        # disabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(l, [])
+
+        self.assertEnabled(False)
+
+    def test_sysv_enable(self):
+        '''only sysv: enable'''
+
+        self.create_sysv()
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+
+        # enabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(len(l), 1, 'expect one symlink in %s' % repr(l))
+        self.assertEqual(os.readlink(l[0]), '../init.d/test_enable')
+
+        # enable should be idempotent
+        subprocess.check_call(['systemctl', 'enable', 'test_enable'])
+        self.assertEnabled(True)
+
+    def test_sysv_disable(self):
+        '''only sysv: disable'''
+
+        self.create_sysv(enable=True)
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+
+        # disabled the sysv script
+        l = glob('/etc/rc2.d/S??test_enable')
+        self.assertEqual(l, [])
+
+        # disable should be idempotent
+        subprocess.check_call(['systemctl', 'disable', 'test_enable'])
+        self.assertEnabled(False)
+
+    def test_unit_link(self):
+        '''systemctl link'''
+
+        with tempfile.NamedTemporaryFile(suffix='.service') as f:
+            f.write(b'[Unit]\n')
+            f.flush()
+            subprocess.check_call(['systemctl', 'link', f.name])
+
+            unit = os.path.basename(f.name)
+            l = os.path.join('/etc/systemd/system', unit)
+            self.assertEqual(os.readlink(l), f.name)
+
+            # disable it again
+            subprocess.check_call(['systemctl', 'disable', unit])
+            # this should also remove the unit symlink
+            self.assertFalse(os.path.islink(l))
+
+    @unittest.skip("do not work under Fedora")
+    def test_unit_enable_full_path(self):
+        '''systemctl enable a unit in a non-default path'''
+
+        with tempfile.NamedTemporaryFile(suffix='.service') as f:
+            f.write(b'''[Unit]
+Description=test
+[Service]
+ExecStart=/bin/true
+[Install]
+WantedBy=multi-user.target''')
+            f.flush()
+            unit = os.path.basename(f.name)
+
+            # now enable it
+            subprocess.check_call(['systemctl', 'enable', f.name])
+            self.assertEnabled(True, unit=unit)
+            l = os.path.join('/etc/systemd/system', unit)
+            self.assertEqual(os.readlink(l), f.name)
+            enable_l = '/etc/systemd/system/multi-user.target.wants/' + unit
+            self.assertEqual(os.readlink(enable_l), f.name)
+
+            # disable it again
+            subprocess.check_call(['systemctl', 'disable', unit])
+            # self.assertEnabled(False) does not work as now systemd does not
+            # know about the unit at all any more
+            self.assertFalse(os.path.islink(enable_l))
+            # this should also remove the unit symlink
+            self.assertFalse(os.path.islink(l))
+
+
+if __name__ == '__main__':
+    unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
+                                                     verbosity=2))