def ts(monkeypatch): ts = Scenario(site_id="site1") ts.add_host("host1", tags={"agent": "no-agent", "criticality": "test"}) ts.add_host("host2", tags={"agent": "no-agent"}) ts.add_host("host3", tags={"agent": "no-agent", "site": "site2"}) ts.apply(monkeypatch) return ts
def test_get_check_table__static_checks_win(monkeypatch: MonkeyPatch) -> None: hostname_str = "df_host" hostname = HostName(hostname_str) plugin_name = CheckPluginName("df") item = "/snap/core/9066" ts = Scenario() ts.add_host(hostname) ts.set_option( "static_checks", { "filesystem": [ ((str(plugin_name), item, { "source": "static" }), [], [hostname_str]), ], }, ) ts.set_autochecks( hostname_str, [AutocheckEntry(plugin_name, item, {"source": "auto"}, {})]) ts.apply(monkeypatch) chk_table = check_table.get_check_table(hostname) # assert check table is populated as expected assert len(chk_table) == 1 # assert static checks won effective_params = chk_table[(plugin_name, item)].parameters.evaluate(lambda _: True) assert effective_params[ "source"] == "static" # type: ignore[index,call-overload]
def test_get_effective_service_level(monkeypatch): ts = Scenario().add_host("testhost1") ts.add_host("testhost2") ts.add_host("testhost3") ts.set_ruleset( "host_service_levels", [ (10, [], ["testhost2"], {}), (2, [], ["testhost2"], {}), ], ) ts.set_ruleset( "service_service_levels", [ (33, [], ["testhost1"], ["CPU load$"], {}), ], ) ts.apply(monkeypatch) with plugin_contexts.current_service( Service( item=None, check_plugin_name=CheckPluginName("cpu_loads"), description="CPU load", parameters={}, )): with plugin_contexts.current_host("testhost1"): assert check_api.get_effective_service_level() == 33 with plugin_contexts.current_host("testhost2"): assert check_api.get_effective_service_level() == 10 with plugin_contexts.current_host("testhost3"): assert check_api.get_effective_service_level() == 0
def test_attribute_defaults(self, monkeypatch): hostname = "testhost" ipaddress = "1.2.3.4" ts = Scenario() ts.add_host(hostname) ts.set_option("management_protocol", {hostname: "snmp"}) ts.set_option( "host_attributes", { hostname: { "management_address": ipaddress }, }, ) ts.apply(monkeypatch) source = SNMPSource.management_board( HostName(hostname), ipaddress, force_cache_refresh=False, selected_sections=NO_SELECTION, on_scan_error=OnError.RAISE, ) assert source.description == ( "Management board - SNMP " "(Community: 'public', Bulk walk: no, Port: 161, Backend: Classic)" )
def test_ruleset_matcher_get_host_ruleset_values_tags_duplicate_ids( monkeypatch: MonkeyPatch, rule_spec: RuleConditionsSpec, expected_result: Sequence[RuleValue], ) -> None: ts = Scenario() add_tag_config = TagConfig.from_config( { "aux_tags": [], "tag_groups": [ { "id": "grp1", "tags": [ { "aux_tags": [], "id": "v1", "title": "Value1", }, ], "title": "Group 1", }, { "id": "grp2", "tags": [ { "aux_tags": [], "id": "v1", "title": "Value1", }, ], "title": "Group 2", }, ], } ) ts.tags += add_tag_config ts.add_host( "host", tags={ "grp1": "v1", }, ) config_cache = ts.apply(monkeypatch) matcher = config_cache.ruleset_matcher assert ( list( matcher.get_host_ruleset_values( RulesetMatchObject( host_name=HostName("host"), service_description=None, ), ruleset=[rule_spec], is_binary=False, ) ) == expected_result )
def test_basic_host_ruleset_is_matching_host_ruleset( monkeypatch: MonkeyPatch) -> None: ts = Scenario() ts.add_host(HostName("abc")) ts.add_host(HostName("abc")) ts.add_host(HostName("xyz")) ts.add_host(HostName("host1")) ts.add_host(HostName("host2")) config_cache = ts.apply(monkeypatch) matcher = config_cache.ruleset_matcher assert (matcher.is_matching_host_ruleset( RulesetMatchObject(host_name=HostName("abc"), service_description=None), ruleset=binary_ruleset, ) is False) assert (matcher.is_matching_host_ruleset( RulesetMatchObject(host_name=HostName("xyz"), service_description=None), ruleset=binary_ruleset, ) is False) assert (matcher.is_matching_host_ruleset( RulesetMatchObject(host_name=HostName("host1"), service_description=None), ruleset=binary_ruleset, ) is True) assert (matcher.is_matching_host_ruleset( RulesetMatchObject(host_name=HostName("host2"), service_description=None), ruleset=binary_ruleset, ) is False)
def test_get_cmk_passive_service_attributes(monkeypatch, hostname, result): ts = Scenario() ts.add_host("localhost") ts.add_host("blub") ts.set_option( "extra_service_conf", { "contact_groups": [ ("ding", ["localhost"], ["CPU load$"]), ], "check_interval": [ (40.0, ["blub"], ["Check_MK$"]), (33.0, ["localhost"], ["CPU load$"]), ], }, ) config_cache = ts.apply(monkeypatch) host_config = config_cache.get_host_config(hostname) check_mk_attrs = core_config.get_service_attributes( hostname, "Check_MK", config_cache) service = ConfiguredService( check_plugin_name=CheckPluginName("cpu_loads"), item=None, description="CPU load", parameters=TimespecificParameters(), discovered_parameters={}, service_labels={}, ) service_spec = core_config.get_cmk_passive_service_attributes( config_cache, host_config, service, check_mk_attrs) assert service_spec == result
def test_dump_precompiled_hostcheck_without_check_mk_service( monkeypatch: MonkeyPatch, config_path: VersionedConfigPath) -> None: hostname = HostName("localhost") ts = Scenario().add_host(hostname) config_cache = ts.apply(monkeypatch) host_check = core_nagios._dump_precompiled_hostcheck( config_cache, config_path, hostname, ) assert host_check is None
def test_sanitize_snmp_encoding(monkeypatch, encoding, columns, expected): ts = Scenario().add_host("localhost") ts.set_ruleset( "snmp_character_encodings", [ (encoding, [], config.ALL_HOSTS, {}), ], ) config_cache = ts.apply(monkeypatch) snmp_config = config_cache.get_host_config("localhost").snmp_config("") assert snmp_table._sanitize_snmp_encoding(columns, snmp_config) == expected
def test_analyse_host(monkeypatch): automation = automations.AutomationAnalyseHost() ts = Scenario() ts.add_host("test-host") ts.set_option( "host_labels", { "test-host": { "explicit": "ding", }, }, ) ts.apply(monkeypatch) assert automation.execute(["test-host"]) == AnalyseHostResult( label_sources={ "cmk/site": "discovered", "explicit": "explicit" }, labels={ "cmk/site": "NO_SITE", "explicit": "ding" }, )
def test_compile_delayed_host_check(monkeypatch: MonkeyPatch, config_path: VersionedConfigPath) -> None: hostname = HostName("localhost") ts = Scenario().add_host(hostname) ts.set_option("delay_precompile", True) config_cache = ts.apply(monkeypatch) # Ensure a host check is created monkeypatch.setattr( core_nagios, "_get_needed_plugin_names", lambda c: (set(), {CheckPluginName("uptime")}, set()), ) source_file = core_nagios.HostCheckStore.host_check_source_file_path( config_path, hostname, ) compiled_file = core_nagios.HostCheckStore.host_check_file_path( config_path, hostname) assert config.delay_precompile is True assert not source_file.exists() assert not compiled_file.exists() # Write the host check source file host_check = core_nagios._dump_precompiled_hostcheck( config_cache, config_path, hostname, verify_site_python=False, ) assert host_check is not None core_nagios.HostCheckStore().write(config_path, hostname, host_check) # The compiled file path links to the source file until it has been executed for the first # time. Then the symlink is replaced with the compiled file assert source_file.exists() assert compiled_file.exists() assert compiled_file.resolve() == source_file # Expect the command to fail: We don't have the correct environment to execute it. # But this is no problem for our test, we only want to see the result of the compilation. assert (subprocess.Popen(["python3", str(compiled_file)], shell=False, close_fds=True).wait() == 1) assert compiled_file.resolve() != source_file with compiled_file.open("rb") as f: assert f.read().startswith(importlib.util.MAGIC_NUMBER)
def make_scenario(hostname, tags): ts = Scenario() ts.add_host(hostname, tags=tags) ts.set_ruleset( "datasource_programs", [ ("echo 1", [], ["ds-host-14", "all-agents-host", "all-special-host"], {}), ], ) ts.set_option( "special_agents", { "jolokia": [ ( {}, [], [ "special-host-14", "all-agents-host", "all-special-host", ], {}, ), ] }, ) return ts
def test_attribute_defaults( self, special_agent_id, ipaddress, agent_dir, expected_args, expected_stdin, monkeypatch, ): hostname = HostName("testhost") params: Dict[Any, Any] = {} Scenario().add_host(hostname).apply(monkeypatch) # end of setup source = SpecialAgentSource( hostname, ipaddress, special_agent_id=special_agent_id, params=params, ) assert source.hostname == hostname assert source.ipaddress == ipaddress assert source.cmdline == ( # str(agent_dir / "special" / ("agent_%s" % special_agent_id)) + " " + expected_args ) assert source.stdin == expected_stdin assert source.id == "special_%s" % special_agent_id
def test_attribute_defaults(monkeypatch): ipaddress = "1.2.3.4" hostname = HostName("testhost") Scenario().add_host(hostname).apply(monkeypatch) source = TCPSource(hostname, ipaddress) monkeypatch.setattr(source, "file_cache_base_path", Path("/my/path/")) assert source.fetcher_configuration == { "file_cache": { "hostname": "testhost", "disabled": False, "max_age": MaxAge.none(), "base_path": "/my/path", "simulation": False, "use_outdated": False, }, "family": socket.AF_INET, "address": (ipaddress, 6556), "host_name": str(hostname), "timeout": 5.0, "encryption_settings": { "use_realtime": "enforce", "use_regular": "disable", }, "use_only_cache": False, } assert source.description == "TCP: %s:%s" % (ipaddress, 6556) assert source.id == "agent"
def test_check_crash_report_read_snmp_info(monkeypatch): Scenario().apply(monkeypatch) config.load_checks( check_api.get_check_api_context, ["%s/uptime" % cmk.utils.paths.checks_dir, "%s/snmp_uptime" % cmk.utils.paths.checks_dir], ) cache_path = Path(cmk.utils.paths.data_source_cache_dir, "snmp", "testhost") cache_path.parent.mkdir(parents=True, exist_ok=True) with cache_path.open("w", encoding="utf-8") as f: f.write("[]\n") try: raise Exception("DING") except Exception: crash = crash_reporting.CheckCrashReport.from_exception_and_context( hostname=HostName("testhost"), check_plugin_name="snmp_uptime", check_plugin_kwargs={}, is_manual_check=False, description="Uptime", text="Output", ) assert isinstance(crash, crash_reporting.CheckCrashReport) assert crash.agent_output is None assert crash.snmp_info == b"[]\n"
def test_is_bulkwalk_host(monkeypatch): ts = Scenario() ts.set_ruleset( "bulkwalk_hosts", [ ([], ["localhost"], {}), ], ) ts.add_host("abc") ts.add_host("localhost") config_cache = ts.apply(monkeypatch) assert config_cache.get_host_config("abc").snmp_config("").is_bulkwalk_host is False assert config_cache.get_host_config("localhost").snmp_config("").is_bulkwalk_host is True
def test_dump_precompiled_hostcheck_not_existing_host( monkeypatch: MonkeyPatch, config_path: VersionedConfigPath) -> None: config_cache = Scenario().apply(monkeypatch) host_check = core_nagios._dump_precompiled_hostcheck( config_cache, config_path, HostName("not-existing"), ) assert host_check is None
def test_ruleset_optimizer_clear_ruleset_caches(monkeypatch: MonkeyPatch) -> None: config_cache = Scenario().apply(monkeypatch) ruleset_optimizer = config_cache.ruleset_matcher.ruleset_optimizer ruleset_optimizer.get_service_ruleset(ruleset, False, False) ruleset_optimizer.get_host_ruleset(ruleset, False, False) assert ruleset_optimizer._host_ruleset_cache assert ruleset_optimizer._service_ruleset_cache ruleset_optimizer.clear_ruleset_caches() assert not ruleset_optimizer._host_ruleset_cache assert not ruleset_optimizer._service_ruleset_cache
def test_attribute_defaults(monkeypatch: MonkeyPatch, ipaddress: HostAddress, mode: Mode) -> None: hostname = HostName("testhost") Scenario().add_host(hostname).apply(monkeypatch) source = PiggybackSource(hostname, ipaddress) assert source.hostname == hostname assert source.ipaddress == ipaddress assert source.description.startswith("Process piggyback data from") assert not source.summarize(result.OK(AgentHostSections()), mode=mode) assert source.id == "piggyback"
def test_template_translation(self, ipaddress, monkeypatch): template = "<NOTHING>x<IP>x<HOST>x<host>x<ip>x" hostname = HostName("testhost") Scenario().add_host(hostname).apply(monkeypatch) source = DSProgramSource(hostname, ipaddress, template=template) assert source.cmdline == "<NOTHING>x%sx%sx<host>x<ip>x" % ( ipaddress if ipaddress is not None else "", hostname, )
def test_dump_precompiled_hostcheck(monkeypatch: MonkeyPatch, config_path: VersionedConfigPath) -> None: hostname = HostName("localhost") ts = Scenario().add_host(hostname) config_cache = ts.apply(monkeypatch) # Ensure a host check is created monkeypatch.setattr( core_nagios, "_get_needed_plugin_names", lambda c: (set(), {CheckPluginName("uptime")}, set()), ) host_check = core_nagios._dump_precompiled_hostcheck( config_cache, config_path, hostname, ) assert host_check is not None assert host_check.startswith("#!/usr/bin/env python3")
def test_update_dns_cache(monkeypatch: MonkeyPatch) -> None: def _getaddrinfo(host, port, family=None, socktype=None, proto=None, flags=None): # Needs to return [(family, type, proto, canonname, sockaddr)] but only # caring about the address return { ("blub", socket.AF_INET): [(family, None, None, None, ("127.0.0.13", 1337))], ("bla", socket.AF_INET): [(family, None, None, None, ("127.0.0.37", 1337))], ("dual", socket.AF_INET): [(family, None, None, None, ("127.0.0.42", 1337))], }[(host, family)] monkeypatch.setattr(socket, "getaddrinfo", _getaddrinfo) ts = Scenario() ts.add_host(HostName("blub"), tags={"criticality": "offline"}) ts.add_host(HostName("bla")) ts.add_host(HostName("dual"), tags={"address_family": "ip-v4v6"}) ts.apply(monkeypatch) config_cache = config.get_config_cache() assert (ip_lookup.update_dns_cache( host_configs=(config_cache.get_host_config(hn) for hn in config_cache.all_active_hosts()), configured_ipv4_addresses={}, configured_ipv6_addresses={}, simulation_mode=False, override_dns=None, ) == (3, ["dual"])) # Check persisted data cache = ip_lookup.IPLookupCache({}) cache.load_persisted() assert cache[(HostName("blub"), socket.AF_INET)] == "127.0.0.13" assert cache.get((HostName("dual"), socket.AF_INET6)) is None
def test_check_plugins_do_not_discover_upon_empty_snmp_input( monkeypatch, fix_register): """ In Checkmk < 1.6 the parse function has not been called for empty table data, unless "handle_empty_info" has been set. From version 2.0 on, the parse function will be called allways. In case no further processing is desired, the parse functions should return `None`. (Returning something falsey usually means nothing will be discovered!) Since this was the behaviour for *almost* every plugin we maintain this test with a list of known exceptions, to ensure the old behaviour is not changed. However: There is nothing wrong with not returning None, in principle. If you whish to do that (see one of the listed exceptions for examples), just add an exception below. If maintaining this test becvomes too tedious, we can probably just remove it. """ Scenario().apply(monkeypatch) # host_extra_conf needs the ruleset_matcher plugins_expected_to_discover_upon_empty = { "printer_alerts", "liebert_system_events", "apc_inrow_system_events", } plugins_discovering_upon_empty = set() for plugin in fix_register.check_plugins.values(): for sections in _section_permutations(plugin.sections): kwargs = { str(section.name): _get_empty_parsed_result(section) for section in sections } if all(v is None for v in kwargs.values()): continue if len(kwargs) > 1: kwargs = {f"section_{k}": v for k, v in kwargs.items()} else: kwargs = {"section": v for v in kwargs.values()} if plugin.discovery_default_parameters is not None: kwargs["params"] = (plugin.discovery_default_parameters if (plugin.discovery_ruleset_type == "merged") else [plugin.discovery_default_parameters]) with current_host( "testhost"): # host_extra_conf needs a host_name() if list(plugin.discovery_function(**kwargs)): plugins_discovering_upon_empty.add(str(plugin.name)) assert plugins_discovering_upon_empty == plugins_expected_to_discover_upon_empty
def test_tcpdatasource_only_from(monkeypatch, res, reported, rule): # TODO(ml): Not only is this white box testing but all these instantiations # before the summarizer obscure the purpose of the test. This is # way too complicated. Test the `AgentSummarizerDefault` directly # in `tests.unit.cmk.core_helpers.test_summarizers` instead. ts = Scenario().add_host("hostname") ts.set_option("agent_config", {"only_from": [rule]} if rule else {}) config_cache = ts.apply(monkeypatch) source = TCPSource(HostName("hostname"), "ipaddress") monkeypatch.setattr(config_cache, "host_extra_conf", lambda host, ruleset: ruleset) summarizer = AgentSummarizerDefault( source.exit_spec, is_cluster=source.host_config.is_cluster, agent_min_version=0, agent_target_version=source.host_config.agent_target_version, only_from=source.host_config.only_from, ) assert summarizer._check_only_from(reported) == res
def test__rename_discovered_host_label_files_do_not_overwrite( monkeypatch: pytest.MonkeyPatch, uc: update_config.UpdateConfig, ) -> None: ts = Scenario() ts.add_host("abc.d") ts.apply(monkeypatch) host_name = "abc.d" old_path = (cmk.utils.paths.discovered_host_labels_dir / host_name).with_suffix(".mk") new_path = cmk.utils.paths.discovered_host_labels_dir / (host_name + ".mk") old_path.parent.mkdir(exist_ok=True, parents=True) with old_path.open("w") as f: f.write("{}\n") assert old_path.exists() with new_path.open("w") as f: f.write("{}\n") assert new_path.exists() uc._rename_discovered_host_label_files() assert old_path.exists() assert new_path.exists()
def test_get_host_attributes(fixup_ip_lookup, monkeypatch): ts = Scenario().add_host("test-host", tags={"agent": "no-agent"}) ts.set_option( "host_labels", { "test-host": { "ding": "dong", }, }, ) config_cache = ts.apply(monkeypatch) expected_attrs = { "_ADDRESS_4": "0.0.0.0", "_ADDRESS_6": "", "_ADDRESS_FAMILY": "4", "_FILENAME": "/wato/hosts.mk", "_TAGS": "/wato/ auto-piggyback ip-v4 ip-v4-only lan no-agent no-snmp prod site:unit", "__TAG_address_family": "ip-v4-only", "__TAG_agent": "no-agent", "__TAG_criticality": "prod", "__TAG_ip-v4": "ip-v4", "__TAG_networking": "lan", "__TAG_piggyback": "auto-piggyback", "__TAG_site": "unit", "__TAG_snmp_ds": "no-snmp", "__LABEL_ding": "dong", "__LABEL_cmk/site": "NO_SITE", "__LABELSOURCE_cmk/site": "discovered", "__LABELSOURCE_ding": "explicit", "address": "0.0.0.0", "alias": "test-host", } if cmk_version.is_managed_edition(): expected_attrs["_CUSTOMER"] = "provider" attrs = core_config.get_host_attributes("test-host", config_cache) assert attrs == expected_attrs
def test_get_labels_of_service(monkeypatch): automation = automations.AutomationGetLabelsOf() ts = Scenario().add_host("test-host") ts.set_ruleset( "service_label_rules", [ ({ "label1": "val1" }, [], config.ALL_HOSTS, ["CPU load$"], {}), ({ "label2": "val2" }, [], config.ALL_HOSTS, ["CPU load$"], {}), ], ) ts.apply(monkeypatch) assert automation.execute(["service", "test-host", "CPU load"]) == GetLabelsOfResult({ "labels": { "label1": "val1", "label2": "val2" }, "label_sources": { "label1": "ruleset", "label2": "ruleset" }, })
def test_lookup_mgmt_board_ip_address_unresolveable( monkeypatch: MonkeyPatch, tags: Dict[str, str], family: socket.AddressFamily) -> None: hostname = HostName("unresolveable-hostname") ts = Scenario() ts.add_host(hostname, tags=tags) ts.apply(monkeypatch) host_config = config.get_config_cache().get_host_config(hostname) assert config.lookup_mgmt_board_ip_address(host_config) is None
def test_ruleset_matcher_get_host_ruleset_values_tags( monkeypatch: MonkeyPatch, hostname: HostName, expected_result: Sequence[str], ) -> None: ts = Scenario() ts.add_host( HostName("host1"), tags={ "criticality": "prod", "agent": "cmk-agent", "networking": "lan", }, ) ts.add_host( HostName("host2"), tags={ "criticality": "test", "networking": "wan", }, ) ts.add_host( HostName("host3"), tags={ "criticality": "test", "networking": "dmz", }, ) config_cache = ts.apply(monkeypatch) matcher = config_cache.ruleset_matcher assert ( list( matcher.get_host_ruleset_values( RulesetMatchObject(host_name=hostname, service_description=None), ruleset=tag_ruleset, is_binary=False, ) ) == expected_result )
def test_attribute_defaults(mode, monkeypatch): hostname = HostName("testhost") Scenario().add_host(hostname).apply(monkeypatch) host_config = config.get_config_cache().get_host_config(hostname) ipaddress = config.lookup_mgmt_board_ip_address(host_config) source = IPMISource(hostname, ipaddress) assert source.hostname == hostname assert source.ipaddress == ipaddress assert source.description == "Management board - IPMI" assert source.source_type is SourceType.MANAGEMENT assert source.summarize(result.OK(AgentHostSections()), mode=mode) == (0, "Version: unknown") assert source.id == "mgmt_ipmi"