def test_fetch_from_io_non_empty(self, monkeypatch: MonkeyPatch, fetcher: SNMPFetcher) -> None: table = [["1"]] monkeypatch.setattr( snmp_table, "get_snmp_table", lambda *_, **__: table, ) section_name = SectionName("pim") monkeypatch.setattr( fetcher, "sections", { section_name: SectionMeta( checking=True, disabled=False, redetect=False, fetch_interval=None, ), }, ) assert fetcher.fetch(Mode.INVENTORY) == result.OK({}) # 'pim' is not an inventory section assert fetcher.fetch(Mode.CHECKING) == result.OK({section_name: [table]}) monkeypatch.setattr( snmp, "gather_available_raw_section_names", lambda *_, **__: {SectionName("pim")}, ) assert fetcher.fetch(Mode.DISCOVERY) == result.OK({section_name: [table]})
def test_fetch_from_io_non_empty(self, monkeypatch, fetcher): table = [['1']] monkeypatch.setattr( snmp_table, "get_snmp_table", lambda *_, **__: table, ) section_name = SectionName('pim') fetcher.configured_snmp_sections = {section_name} assert fetcher.fetch(Mode.INVENTORY) == result.OK({}) # 'pim' is not an inventory section assert fetcher.fetch(Mode.CHECKING) == result.OK({section_name: [table]})
def test_multiple_sources_from_different_hosts( self, hostname, ipaddress, config_cache, host_config ): sources = [ ProgramSource.ds(HostName(f"{hostname}0"), ipaddress, template=""), TCPSource(HostName(f"{hostname}1"), ipaddress), TCPSource(HostName(f"{hostname}2"), ipaddress), ] host_sections = _collect_host_sections( fetched=[ ( source, FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ), ) for source in sources ], file_cache_max_age=file_cache.MaxAge.none(), selected_sections=NO_SELECTION, )[0] assert set(host_sections) == { HostKey(HostName(f"{hostname}0"), ipaddress, SourceType.HOST), HostKey(HostName(f"{hostname}1"), ipaddress, SourceType.HOST), HostKey(HostName(f"{hostname}2"), ipaddress, SourceType.HOST), } for source in sources: assert host_sections[ HostKey(source.hostname, source.ipaddress, SourceType.HOST) ].sections[SectionName(f"section_name_{source.hostname}")] == [["section_content"]]
def test_one_snmp_source(self, hostname, ipaddress, config_cache, host_config): raw_data: SNMPRawData = {} host_sections = _collect_host_sections( fetched=[ ( SNMPSource.snmp( hostname, ipaddress, selected_sections=NO_SELECTION, force_cache_refresh=False, on_scan_error=OnError.RAISE, ), FetcherMessage.from_raw_data( result.OK(raw_data), Snapshot.null(), FetcherType.SNMP, ), ) ], file_cache_max_age=file_cache.MaxAge.none(), selected_sections=NO_SELECTION, )[0] assert len(host_sections) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in host_sections section = host_sections[key] assert len(section.sections) == 1 assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
def test_from_raw_data_standard(self, agent_raw_data, stats, fetcher_type): raw_data: result.Result[AgentRawData, Exception] = result.OK(agent_raw_data) message = FetcherMessage.from_raw_data(raw_data, stats, fetcher_type) assert message.header.fetcher_type is fetcher_type assert message.header.payload_type is PayloadType.AGENT assert message.raw_data == raw_data
def test_from_raw_data_snmp(self, snmp_raw_data): raw_data: result.Result[SNMPRawData, Exception] = result.OK(snmp_raw_data) message = FetcherMessage.from_raw_data(raw_data, FetcherType.SNMP) assert message.header.fetcher_type is FetcherType.SNMP assert message.header.payload_type is PayloadType.SNMP assert message.raw_data == raw_data
def test_from_raw_data_tcp(self, agent_raw_data): raw_data: result.Result[AgentRawData, Exception] = result.OK(agent_raw_data) message = FetcherMessage.from_raw_data(raw_data, FetcherType.TCP) assert message.header.fetcher_type is FetcherType.TCP assert message.header.payload_type is PayloadType.AGENT assert message.raw_data == raw_data
def test_no_sources(self, cluster, nodes, config_cache, host_config): sources = make_cluster_sources(config_cache, host_config) host_sections = _collect_host_sections( fetched=[ ( source, FetcherMessage.from_raw_data( result.OK(AgentRawData(b"")), Snapshot.null(), FetcherType.PIGGYBACK, ), ) for source in sources ], file_cache_max_age=file_cache.MaxAge.none(), selected_sections=NO_SELECTION, )[0] assert len(host_sections) == len(nodes) key_clu = HostKey(cluster, None, SourceType.HOST) assert key_clu not in host_sections for hostname, addr in nodes.items(): key = HostKey(hostname, addr, SourceType.HOST) assert key in host_sections section = host_sections[key] assert section.sections[SectionName("section_name_%s" % hostname)] == [ ["section_content_%s" % hostname] ] assert not section.cache_info assert not section.piggybacked_raw_data
def test_data_source_preselected(monkeypatch, source, kwargs): selected_sections = {SectionName("keep")} # <- this is what we care about # a lot of hocus pocus to instantiate a source: make_scenario("hostname", {}).apply(monkeypatch) monkeypatch.setattr(config, "special_agent_info", {None: lambda *a: []}) source_inst = source( "hostname", "127.0.0.1", **kwargs, ) parse_result = source_inst.parse( result.OK(b"<<<dismiss>>>\n" b"this is not\n" b"a preselected section\n" b"<<<keep>>>\n" b"but this is!\n"), selection=selected_sections, ) assert parse_result.is_ok() sections = parse_result.value(None).sections assert set(sections) == selected_sections
def test_multiple_sources_from_the_same_host( self, hostname, ipaddress, config_cache, host_config, ): sources = [ ProgramSource.ds(hostname, ipaddress, template=""), TCPSource(hostname, ipaddress), ] host_sections = _collect_host_sections( sources=sources, file_cache_max_age=file_cache.MaxAge.none(), fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for source in sources ], selected_sections=NO_SELECTION, )[0] assert len(host_sections) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in host_sections section = host_sections[key] assert len(section.sections) == 1 assert section.sections[SectionName( "section_name_%s" % hostname)] == len(sources) * [["section_content"]]
def test_no_sources(self, cluster, nodes, config_cache, host_config): made_nodes = make_nodes(config_cache, host_config, None, sources=()) host_sections = _collect_host_sections( nodes=made_nodes, file_cache_max_age=file_cache.MaxAge.none(), fetcher_messages=[ # We do not pass sources explicitly but still append Piggyback. FetcherMessage.from_raw_data( result.OK(AgentRawData(b"")), Snapshot.null(), FetcherType.PIGGYBACK, ) for _n in made_nodes ], selected_sections=NO_SELECTION, )[0] assert len(host_sections) == len(nodes) key_clu = HostKey(cluster, None, SourceType.HOST) assert key_clu not in host_sections for hostname, addr in nodes.items(): key = HostKey(hostname, addr, SourceType.HOST) assert key in host_sections section = host_sections[key] # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == [["section_content_%s" % hostname]]) assert not section.cache_info assert not section.piggybacked_raw_data
def test_persist_option_populates_cache_info_and_persisted_sections( self, hostname, logger, monkeypatch, ): time_time = 1000 time_delta = 50 monkeypatch.setattr(time, "time", lambda: time_time) raw_data = b"\n".join(( b"<<<section:persist(%i)>>>" % (time_time + time_delta), b"first line", b"second line", )) ahs = AgentParser(hostname, Path(""), logger).parse(result.OK(raw_data)).ok assert ahs.sections == { SectionName("section"): [["first", "line"], ["second", "line"]] } assert ahs.cache_info == { SectionName("section"): (time_time, time_delta) } assert ahs.piggybacked_raw_data == {} assert ahs.persisted_sections == { SectionName("section"): (1000, 1050, [["first", "line"], ["second", "line"]]), }
def test_one_nonsnmp_source(self, hostname, ipaddress, config_cache, host_config, source): source = source(hostname, ipaddress) assert source.source_type is SourceType.HOST host_sections = _collect_host_sections( nodes=make_nodes( config_cache, host_config, ipaddress, sources=[source], ), file_cache_max_age=file_cache.MaxAge.none(), fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ), ], selected_sections=NO_SELECTION, )[0] assert len(host_sections) == 1 key = HostKey(hostname, ipaddress, source.source_type) assert key in host_sections section = host_sections[key] assert len(section.sections) == 1 assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
def test_multiple_sources_from_different_hosts(self, hostname, ipaddress, config_cache, host_config): sources = [ ProgramSource.ds(hostname + "0", ipaddress, template=""), TCPSource(hostname + "1", ipaddress), TCPSource(hostname + "2", ipaddress), ] nodes = make_nodes(config_cache, host_config, ipaddress, sources=sources) host_sections = _collect_host_sections( nodes=nodes, file_cache_max_age=file_cache.MaxAge.none(), fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for _h, _i, sources in nodes for source in sources ], selected_sections=NO_SELECTION, )[0] assert len(host_sections) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in host_sections section = host_sections[key] assert len(section.sections) == len(sources) for source in sources: # yapf: disable assert ( section.sections[SectionName("section_name_%s" % source.hostname)] == [["section_content"]])
def test_fetch_from_io_partially_empty( self, monkeypatch: MonkeyPatch, fetcher: SNMPFetcher ) -> None: section_name = SectionName("pum") monkeypatch.setattr( fetcher, "sections", { section_name: SectionMeta( checking=True, disabled=False, redetect=False, fetch_interval=None, ), }, ) table = [["1"]] monkeypatch.setattr( snmp_table, "get_snmp_table", lambda tree, **__: table if tree.base == fetcher.plugin_store[section_name].trees[0].base else [], ) assert fetcher.fetch(Mode.CHECKING) == result.OK({section_name: [table, []]})
def test_raw_data_tcp_standard(self, agent_raw_data, duration, fetcher_type): raw_data: result.Result[AgentRawData, Exception] = result.OK(agent_raw_data) message = FetcherMessage.from_raw_data(raw_data, duration, fetcher_type) assert message.raw_data == raw_data
def patch_io(self, monkeypatch): class DummyHostSection(HostSections): def _extend_section(self, section_name, section_content): pass for fetcher in (IPMIFetcher, PiggybackFetcher, ProgramFetcher, SNMPFetcher, TCPFetcher): monkeypatch.setattr(fetcher, "__enter__", lambda self: self) monkeypatch.setattr( fetcher, "fetch", lambda self, mode, fetcher=fetcher: {} if fetcher is SNMPFetcher else b"", ) monkeypatch.setattr( Source, "parse", lambda self, raw_data, *, selection: result.OK( DummyHostSection( sections={ SectionName("section_name_%s" % self.hostname): [["section_content"]] }, cache_info={}, piggybacked_raw_data={}, )), )
def test_mode_checking_not_do_status_data_inventory(self, set_sections, monkeypatch, fetcher): monkeypatch.setattr(fetcher, "do_status_data_inventory", False) monkeypatch.setattr( snmp, "gather_available_raw_section_names", lambda *_, **__: fetcher._get_detected_sections(Mode.CHECKING), ) assert fetcher.fetch(Mode.CHECKING) == result.OK({})
def fetch(self, mode: Mode) -> result.Result[TRawData, Exception]: """Return the data from the source, either cached or from IO.""" try: return result.OK(self._fetch(mode)) except Exception as exc: if cmk.utils.debug.enabled(): raise return result.Error(exc)
def test_mode_inventory_not_do_status_data_inventory(self, set_sections, monkeypatch, fetcher): table = set_sections monkeypatch.setattr(fetcher, "do_status_data_inventory", False) monkeypatch.setattr( snmp, "gather_available_raw_section_names", lambda *_, **__: fetcher._get_detected_sections(Mode.INVENTORY), ) assert fetcher.fetch(Mode.INVENTORY) == result.OK({SectionName('pim'): [table]})
def test_multiple_sources_from_the_same_host( self, hostname, ipaddress, mode, config_cache, host_config, ): sources = [ ProgramSource.ds( hostname, ipaddress, mode=mode, preselected_sections=AUTO_DETECT, template="", ), TCPSource( hostname, ipaddress, mode=mode, preselected_sections=AUTO_DETECT, ), ] mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=sources, ), max_cachefile_age=0, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for source in sources ], ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) assert len(section.sections) == 1 # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == len(sources) * [["section_content"]])
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_defaults(self, ipaddress, mode, monkeypatch): hostname = "testhost" Scenario().add_host(hostname).apply(monkeypatch) source = TCPSource(hostname, ipaddress, mode=mode) assert source.summarize(result.OK(AgentHostSections())) == ( 0, "Version: unknown, OS: unknown", [], )
def test_mode_checking_do_status_data_inventory( self, set_sections: List[List[str]], monkeypatch: MonkeyPatch, fetcher: SNMPFetcher ) -> None: table = set_sections monkeypatch.setattr(fetcher, "do_status_data_inventory", True) monkeypatch.setattr( snmp, "gather_available_raw_section_names", lambda *_, **__: fetcher._get_detected_sections(Mode.CHECKING), ) assert fetcher.fetch(Mode.CHECKING) == result.OK({SectionName("pim"): [table]})
def test_fetch_from_io_partially_empty(self, monkeypatch, fetcher): section_name = SectionName('pum') table = [['1']] monkeypatch.setattr( snmp_table, "get_snmp_table", lambda _, oid_info, **__: table if oid_info.base == fetcher.snmp_plugin_store[section_name].trees[0].base else [], ) fetcher.configured_snmp_sections = {section_name} assert fetcher.fetch(Mode.CHECKING) == result.OK({section_name: [table, []]})
def test_multiple_sources_from_the_same_host( self, hostname, ipaddress, mode, config_cache, host_config, ): sources = [ ProgramSource.ds( hostname, ipaddress, mode=mode, template="", ), TCPSource( hostname, ipaddress, mode=mode, ), ] broker = ParsedSectionsBroker() update_host_sections( broker, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=sources, ), max_cachefile_age=0, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for source in sources ], selected_sections=NO_SELECTION, ) assert len(broker) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in broker section = broker[key] assert len(section.sections) == 1 # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == len(sources) * [["section_content"]])
def test_attribute_defaults(monkeypatch, ipaddress, mode): hostname = "testhost" Scenario().add_host(hostname).apply(monkeypatch) source = PiggybackSource(hostname, ipaddress, mode=mode) assert source.hostname == hostname assert source.ipaddress == ipaddress assert source.mode is mode assert source.description.startswith("Process piggyback data from") assert source.summarize(result.OK(AgentHostSections())) == (0, "", []) assert source.id == "piggyback"
def test_fetch_from_io_empty(self, monkeypatch: MonkeyPatch, fetcher: SNMPFetcher) -> None: monkeypatch.setattr( snmp_table, "get_snmp_table", lambda *_, **__: [], ) monkeypatch.setattr( snmp, "gather_available_raw_section_names", lambda *_, **__: {SectionName("pam")}, ) assert fetcher.fetch(Mode.DISCOVERY) == result.OK({SectionName("pam"): [[]]})
def parse( self, raw_data: result.Result[TRawData, Exception], ) -> result.Result[THostSections, Exception]: if raw_data.is_error(): return result.Error(raw_data.error) try: return result.OK(self._parse(raw_data.ok)) except Exception as exc: if cmk.utils.debug.enabled(): raise return result.Error(exc)
def test_fetch_from_io_empty(self, monkeypatch, fetcher): monkeypatch.setattr( snmp_table, "get_snmp_table", lambda *_, **__: [], ) monkeypatch.setattr( snmp, "gather_available_raw_section_names", lambda *_, **__: {SectionName('pam')}, ) assert fetcher.fetch(Mode.DISCOVERY) == result.OK({})