Blame cloudinit/cmd/devel/tests/test_render.py

Packit Service a04d08
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service a04d08
Packit Service 11b429
from six import StringIO
Packit Service a04d08
import os
Packit Service a04d08
Packit Service a04d08
from collections import namedtuple
Packit Service a04d08
from cloudinit.cmd.devel import render
Packit Service a04d08
from cloudinit.helpers import Paths
Packit Service a04d08
from cloudinit.sources import INSTANCE_JSON_FILE, INSTANCE_JSON_SENSITIVE_FILE
Packit Service a04d08
from cloudinit.tests.helpers import CiTestCase, mock, skipUnlessJinja
Packit Service a04d08
from cloudinit.util import ensure_dir, write_file
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class TestRender(CiTestCase):
Packit Service a04d08
Packit Service a04d08
    with_logs = True
Packit Service a04d08
Packit Service a04d08
    args = namedtuple('renderargs', 'user_data instance_data debug')
Packit Service a04d08
Packit Service a04d08
    def setUp(self):
Packit Service a04d08
        super(TestRender, self).setUp()
Packit Service a04d08
        self.tmp = self.tmp_dir()
Packit Service a04d08
Packit Service a04d08
    def test_handle_args_error_on_missing_user_data(self):
Packit Service a04d08
        """When user_data file path does not exist, log an error."""
Packit Service a04d08
        absent_file = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        instance_data = self.tmp_path('instance-data', dir=self.tmp)
Packit Service a04d08
        write_file(instance_data, '{}')
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=absent_file, instance_data=instance_data, debug=False)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO):
Packit Service a04d08
            self.assertEqual(1, render.handle_args('anyname', args))
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'Missing user-data file: %s' % absent_file,
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_handle_args_error_on_missing_instance_data(self):
Packit Service a04d08
        """When instance_data file path does not exist, log an error."""
Packit Service a04d08
        user_data = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        absent_file = self.tmp_path('instance-data', dir=self.tmp)
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=user_data, instance_data=absent_file, debug=False)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO):
Packit Service a04d08
            self.assertEqual(1, render.handle_args('anyname', args))
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'Missing instance-data.json file: %s' % absent_file,
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_handle_args_defaults_instance_data(self):
Packit Service a04d08
        """When no instance_data argument, default to configured run_dir."""
Packit Service a04d08
        user_data = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        run_dir = self.tmp_path('run_dir', dir=self.tmp)
Packit Service a04d08
        ensure_dir(run_dir)
Packit Service a04d08
        paths = Paths({'run_dir': run_dir})
Packit Service a04d08
        self.add_patch('cloudinit.cmd.devel.render.read_cfg_paths', 'm_paths')
Packit Service a04d08
        self.m_paths.return_value = paths
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=user_data, instance_data=None, debug=False)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO):
Packit Service a04d08
            self.assertEqual(1, render.handle_args('anyname', args))
Packit Service a04d08
        json_file = os.path.join(run_dir, INSTANCE_JSON_FILE)
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'Missing instance-data.json file: %s' % json_file,
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_handle_args_root_fallback_from_sensitive_instance_data(self):
Packit Service a04d08
        """When root user defaults to sensitive.json."""
Packit Service a04d08
        user_data = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        run_dir = self.tmp_path('run_dir', dir=self.tmp)
Packit Service a04d08
        ensure_dir(run_dir)
Packit Service a04d08
        paths = Paths({'run_dir': run_dir})
Packit Service a04d08
        self.add_patch('cloudinit.cmd.devel.render.read_cfg_paths', 'm_paths')
Packit Service a04d08
        self.m_paths.return_value = paths
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=user_data, instance_data=None, debug=False)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO):
Packit Service a04d08
            with mock.patch('os.getuid') as m_getuid:
Packit Service a04d08
                m_getuid.return_value = 0
Packit Service a04d08
                self.assertEqual(1, render.handle_args('anyname', args))
Packit Service a04d08
        json_file = os.path.join(run_dir, INSTANCE_JSON_FILE)
Packit Service a04d08
        json_sensitive = os.path.join(run_dir, INSTANCE_JSON_SENSITIVE_FILE)
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'WARNING: Missing root-readable %s. Using redacted %s' % (
Packit Service a04d08
                json_sensitive, json_file), self.logs.getvalue())
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'ERROR: Missing instance-data.json file: %s' % json_file,
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_handle_args_root_uses_sensitive_instance_data(self):
Packit Service a04d08
        """When root user, and no instance-data arg, use sensitive.json."""
Packit Service a04d08
        user_data = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        write_file(user_data, '##template: jinja\nrendering: {{ my_var }}')
Packit Service a04d08
        run_dir = self.tmp_path('run_dir', dir=self.tmp)
Packit Service a04d08
        ensure_dir(run_dir)
Packit Service a04d08
        json_sensitive = os.path.join(run_dir, INSTANCE_JSON_SENSITIVE_FILE)
Packit Service a04d08
        write_file(json_sensitive, '{"my-var": "jinja worked"}')
Packit Service a04d08
        paths = Paths({'run_dir': run_dir})
Packit Service a04d08
        self.add_patch('cloudinit.cmd.devel.render.read_cfg_paths', 'm_paths')
Packit Service a04d08
        self.m_paths.return_value = paths
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=user_data, instance_data=None, debug=False)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO):
Packit Service a04d08
            with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
Packit Service a04d08
                with mock.patch('os.getuid') as m_getuid:
Packit Service a04d08
                    m_getuid.return_value = 0
Packit Service a04d08
                    self.assertEqual(0, render.handle_args('anyname', args))
Packit Service a04d08
        self.assertIn('rendering: jinja worked', m_stdout.getvalue())
Packit Service a04d08
Packit Service a04d08
    @skipUnlessJinja()
Packit Service a04d08
    def test_handle_args_renders_instance_data_vars_in_template(self):
Packit Service a04d08
        """If user_data file is a jinja template render instance-data vars."""
Packit Service a04d08
        user_data = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        write_file(user_data, '##template: jinja\nrendering: {{ my_var }}')
Packit Service a04d08
        instance_data = self.tmp_path('instance-data', dir=self.tmp)
Packit Service a04d08
        write_file(instance_data, '{"my-var": "jinja worked"}')
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=user_data, instance_data=instance_data, debug=True)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO) as m_console_err:
Packit Service a04d08
            with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
Packit Service a04d08
                self.assertEqual(0, render.handle_args('anyname', args))
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'DEBUG: Converted jinja variables\n{', self.logs.getvalue())
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'DEBUG: Converted jinja variables\n{', m_console_err.getvalue())
Packit Service a04d08
        self.assertEqual('rendering: jinja worked', m_stdout.getvalue())
Packit Service a04d08
Packit Service a04d08
    @skipUnlessJinja()
Packit Service a04d08
    def test_handle_args_warns_and_gives_up_on_invalid_jinja_operation(self):
Packit Service a04d08
        """If user_data file has invalid jinja operations log warnings."""
Packit Service a04d08
        user_data = self.tmp_path('user-data', dir=self.tmp)
Packit Service a04d08
        write_file(user_data, '##template: jinja\nrendering: {{ my-var }}')
Packit Service a04d08
        instance_data = self.tmp_path('instance-data', dir=self.tmp)
Packit Service a04d08
        write_file(instance_data, '{"my-var": "jinja worked"}')
Packit Service a04d08
        args = self.args(
Packit Service a04d08
            user_data=user_data, instance_data=instance_data, debug=True)
Packit Service a04d08
        with mock.patch('sys.stderr', new_callable=StringIO):
Packit Service a04d08
            self.assertEqual(1, render.handle_args('anyname', args))
Packit Service a04d08
        self.assertIn(
Packit Service a04d08
            'WARNING: Ignoring jinja template for %s: Undefined jinja'
Packit Service a04d08
            ' variable: "my-var". Jinja tried subtraction. Perhaps you meant'
Packit Service a04d08
            ' "my_var"?' % user_data,
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab