Blame tests/unittests/test_handler/test_handler_runcmd.py

Packit Service a04d08
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service a04d08
Packit Service a04d08
from cloudinit.config.cc_runcmd import handle, schema
Packit Service a04d08
from cloudinit.sources import DataSourceNone
Packit Service 751c4a
from cloudinit import (distros, helpers, cloud, subp, util)
Packit Service a04d08
from cloudinit.tests.helpers import (
Packit Service a04d08
    CiTestCase, FilesystemMockingTestCase, SchemaTestCaseMixin,
Packit Service a04d08
    skipUnlessJsonSchema)
Packit Service a04d08
Packit Service a04d08
import logging
Packit Service a04d08
import os
Packit Service a04d08
import stat
Packit Service a04d08
Packit Service a04d08
LOG = logging.getLogger(__name__)
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class TestRuncmd(FilesystemMockingTestCase):
Packit Service a04d08
Packit Service a04d08
    with_logs = True
Packit Service a04d08
Packit Service a04d08
    def setUp(self):
Packit Service a04d08
        super(TestRuncmd, self).setUp()
Packit Service 751c4a
        self.subp = subp.subp
Packit Service a04d08
        self.new_root = self.tmp_dir()
Packit Service a04d08
Packit Service a04d08
    def _get_cloud(self, distro):
Packit Service a04d08
        self.patchUtils(self.new_root)
Packit Service a04d08
        paths = helpers.Paths({'scripts': self.new_root})
Packit Service a04d08
        cls = distros.fetch(distro)
Packit Service a04d08
        mydist = cls(distro, {}, paths)
Packit Service a04d08
        myds = DataSourceNone.DataSourceNone({}, mydist, paths)
Packit Service a04d08
        paths.datasource = myds
Packit Service a04d08
        return cloud.Cloud(myds, paths, {}, mydist, None)
Packit Service a04d08
Packit Service a04d08
    def test_handler_skip_if_no_runcmd(self):
Packit Service a04d08
        """When the provided config doesn't contain runcmd, skip it."""
Packit Service a04d08
        cfg = {}
Packit Service a04d08
        mycloud = self._get_cloud('ubuntu')
Packit Service a04d08
        handle('notimportant', cfg, mycloud, LOG, None)
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            "Skipping module named notimportant, no 'runcmd' key",
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_handler_invalid_command_set(self):
Packit Service a04d08
        """Commands which can't be converted to shell will raise errors."""
Packit Service a04d08
        invalid_config = {'runcmd': 1}
Packit Service a04d08
        cc = self._get_cloud('ubuntu')
Packit Service a04d08
        handle('cc_runcmd', invalid_config, cc, LOG, [])
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'Failed to shellify 1 into file'
Packit Service a04d08
            ' /var/lib/cloud/instances/iid-datasource-none/scripts/runcmd',
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    @skipUnlessJsonSchema()
Packit Service a04d08
    def test_handler_schema_validation_warns_non_array_type(self):
Packit Service a04d08
        """Schema validation warns of non-array type for runcmd key.
Packit Service a04d08
Packit Service a04d08
        Schema validation is not strict, so runcmd attempts to shellify the
Packit Service a04d08
        invalid content.
Packit Service a04d08
        """
Packit Service a04d08
        invalid_config = {'runcmd': 1}
Packit Service a04d08
        cc = self._get_cloud('ubuntu')
Packit Service a04d08
        handle('cc_runcmd', invalid_config, cc, LOG, [])
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'Invalid config:\nruncmd: 1 is not of type \'array\'',
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
        self.assertIn('Failed to shellify', self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    @skipUnlessJsonSchema()
Packit Service a04d08
    def test_handler_schema_validation_warns_non_array_item_type(self):
Packit Service a04d08
        """Schema validation warns of non-array or string runcmd items.
Packit Service a04d08
Packit Service a04d08
        Schema validation is not strict, so runcmd attempts to shellify the
Packit Service a04d08
        invalid content.
Packit Service a04d08
        """
Packit Service a04d08
        invalid_config = {
Packit Service a04d08
            'runcmd': ['ls /', 20, ['wget', 'http://stuff/blah'], {'a': 'n'}]}
Packit Service a04d08
        cc = self._get_cloud('ubuntu')
Packit Service a04d08
        handle('cc_runcmd', invalid_config, cc, LOG, [])
Packit Service a04d08
        expected_warnings = [
Packit Service a04d08
            'runcmd.1: 20 is not valid under any of the given schemas',
Packit Service a04d08
            'runcmd.3: {\'a\': \'n\'} is not valid under any of the given'
Packit Service a04d08
            ' schema'
Packit Service a04d08
        ]
Packit Service a04d08
        logs = self.logs.getvalue()
Packit Service a04d08
        for warning in expected_warnings:
Packit Service a04d08
            self.assertIn(warning, logs)
Packit Service a04d08
        self.assertIn('Failed to shellify', logs)
Packit Service a04d08
Packit Service a04d08
    def test_handler_write_valid_runcmd_schema_to_file(self):
Packit Service a04d08
        """Valid runcmd schema is written to a runcmd shell script."""
Packit Service a04d08
        valid_config = {'runcmd': [['ls', '/']]}
Packit Service a04d08
        cc = self._get_cloud('ubuntu')
Packit Service a04d08
        handle('cc_runcmd', valid_config, cc, LOG, [])
Packit Service a04d08
        runcmd_file = os.path.join(
Packit Service a04d08
            self.new_root,
Packit Service a04d08
            'var/lib/cloud/instances/iid-datasource-none/scripts/runcmd')
Packit Service a04d08
        self.assertEqual("#!/bin/sh\n'ls' '/'\n", util.load_file(runcmd_file))
Packit Service a04d08
        file_stat = os.stat(runcmd_file)
Packit Service a04d08
        self.assertEqual(0o700, stat.S_IMODE(file_stat.st_mode))
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
@skipUnlessJsonSchema()
Packit Service a04d08
class TestSchema(CiTestCase, SchemaTestCaseMixin):
Packit Service a04d08
    """Directly test schema rather than through handle."""
Packit Service a04d08
Packit Service a04d08
    schema = schema
Packit Service a04d08
Packit Service a04d08
    def test_duplicates_are_fine_array_array(self):
Packit Service a04d08
        """Duplicated commands array/array entries are allowed."""
Packit Service a04d08
        self.assertSchemaValid(
Packit Service a04d08
            [["echo", "bye"], ["echo", "bye"]],
Packit Service a04d08
            "command entries can be duplicate.")
Packit Service a04d08
Packit Service a04d08
    def test_duplicates_are_fine_array_string(self):
Packit Service a04d08
        """Duplicated commands array/string entries are allowed."""
Packit Service a04d08
        self.assertSchemaValid(
Packit Service a04d08
            ["echo bye", "echo bye"],
Packit Service a04d08
            "command entries can be duplicate.")
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab