def _execute_automation( site: Site, cmd, args=None, stdin=None, expect_stdout=None, expect_stderr="", expect_stderr_pattern="", expect_exit_code=0, parse_data=True, ): cmdline = ["cmk", "--automation", cmd] + ([] if args is None else args) print(cmdline) p = site.execute(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate(stdin) error_msg = "Exit code: %d, Output: %r, Error: %r" % (p.wait(), stdout, stderr) assert p.wait() == expect_exit_code, error_msg if expect_stderr_pattern: assert re.match(expect_stderr_pattern, stderr) is not None, error_msg else: assert stderr == expect_stderr, error_msg if expect_stdout is not None: assert stdout == expect_stdout, error_msg if parse_data: return results.result_type_registry[cmd].deserialize(stdout)
def test_run_omd(site: Site): p = site.execute(["omd"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.wait() == 1 assert stderr == "" assert "Usage" in stdout assert "omd COMMAND -h" in stdout
def test_locales(site: Site): p = site.execute(["locale"], stdout=subprocess.PIPE) output = p.communicate()[0] assert "LANG=C.UTF-8" in output or "LANG=C.utf8" in output or "LANG=en_US.utf8" in output assert "LC_ALL=C.UTF-8" in output or "LC_ALL=C.utf8" in output or "LC_ALL=en_US.utf8" in output
def test_run_omd_sites(site: Site): p = site.execute(["omd", "sites"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.wait() == 0 assert stderr == "" assert site.id in stdout
def test_mkbackup_list_unconfigured(site: Site): p = site.execute(["mkbackup", "list"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8") stderr = p.communicate()[1] assert stderr.startswith("mkbackup is not configured yet") assert p.wait() == 3
def test_run_omd_version_bare(site: Site): p = site.execute(["omd", "version", "-b"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.wait() == 0 assert stderr == "" assert stdout.rstrip("\n") == site.version.omd_version()
def test_run_omd_version(site: Site): p = site.execute(["omd", "version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.wait() == 0 assert stderr == "" assert stdout.endswith("%s\n" % site.version.omd_version())
def test_mkbackup_help(site: Site): p = site.execute(["mkbackup"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8") stdout, stderr = p.communicate() assert stderr == "ERROR: Missing operation mode\n" assert stdout.startswith("Usage:") assert p.wait() == 3
def test_simple_check_mkevents_call(site: Site, args): p = site.execute( ["./check_mkevents"] + args + ["somehost"], stdout=subprocess.PIPE, cwd=site.path("lib/nagios/plugins"), ) output = p.stdout.read() if p.stdout else "<NO STDOUT>" assert output == "OK - no events for somehost\n" assert p.wait() == 0
def test_mkbackup_list_jobs(site: Site, test_cfg): p = site.execute(["mkbackup", "jobs"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8") stdout, stderr = p.communicate() assert stderr == "" assert p.wait() == 0 assert "testjob" in stdout assert "Tästjob" in stdout
def test_run_omd_sites_bare(site: Site): p = site.execute(["omd", "sites", "-b"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.wait() == 0 assert stderr == "" sites = stdout.split("\n") assert len(sites) >= 1 assert site.id in sites
def test_run_omd_versions_bare(site: Site): p = site.execute(["omd", "versions", "-b"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert p.wait() == 0 assert stderr == "" versions = stdout.split("\n") assert len(versions) >= 1 assert site.version.omd_version() in versions
def test_mkbackup_list_backups_invalid_target(site: Site, test_cfg): p = site.execute( ["mkbackup", "list", "xxx"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", ) stdout, stderr = p.communicate() assert stderr.startswith("This backup target does not exist") assert p.wait() == 3 assert stdout == ""
def test_automation_discovery_no_host(test_cfg, site: Site): # NOTE: We can't use @raiseerrors here, because this would redirect stderr to /dev/null! p = site.execute( ["cmk", "--automation", "inventory", "@scan", "new"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = p.communicate() assert "Need two arguments:" in stderr assert stdout == "" assert p.wait() == 1
def fixture_protobuf_py(site: Site, test_dir, proto_source_file): p = site.execute([ "protoc", "-I=%s" % test_dir, "--python_out=%s" % test_dir, str(proto_source_file) ]) assert p.wait() == 0 py_file = test_dir / "test_pb2.py" assert py_file.exists() return py_file
def test_mkbackup_list_backups(site: Site, test_cfg): p = site.execute( ["mkbackup", "list", "test-target"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", ) stdout, stderr = p.communicate() assert stderr == "" assert p.wait() == 0 assert "Type" in stdout assert "Details" in stdout
def _execute_backup(site: Site, job_id="testjob"): # Perform the backup p = site.execute( ["mkbackup", "backup", job_id], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", ) stdout, stderr = p.communicate() assert stderr == "" assert p.wait() == 0 assert "Backup completed" in stdout, "Invalid output: %r" % stdout # Check successful backup listing p = site.execute( ["mkbackup", "list", "test-target"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", ) stdout, stderr = p.communicate() assert stderr == "" assert p.wait() == 0 assert "%s-complete" % job_id.replace("-", "+") in stdout if job_id == "testjob-encrypted": assert "C0:4E:D4:4B:B4:AB:8B:3F:B4:09:32:CE:7D:A6:CF:76" in stdout # Extract and return backup id print(stdout) matches = re.search( r"Backup-ID:\s+(Check_MK-[a-zA-Z0-9_+\.-]+-%s-complete)" % job_id.replace("-", "\\+"), stdout, ) assert matches is not None backup_id = matches.groups()[0] return backup_id
def test_03_python_path(site: Site): p = site.execute( ["python3", "-c", "import sys,json; json.dump(sys.path, sys.stdout)"], stdout=subprocess.PIPE, ) sys_path = json.loads(p.stdout.read()) if p.stdout else "<NO STDOUT>" assert sys_path[0] == "" assert site.root + "/local/lib/python3" in sys_path assert site.root + "/lib/python3" in sys_path assert site.root + "/lib/python3.9" in sys_path for path in sys_path: if path != "" and not path.startswith(site.root): raise Exception("Found non site path %s in sys.path" % path)
def test_no_exeption(site: Site): """ The execution of a special agent should not lead to an exception if the agent is called without any arguments. Possible reasons for an exception are e.g. a wrong shebang, import errors or a wrong PYTHONPATH. """ special_agent_dir = Path( site.root) / "share" / "check_mk" / "agents" / "special" for special_agent_path in special_agent_dir.glob("agent_*"): command = [str(special_agent_path)] p = site.execute(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(os.devnull)) stderr = p.communicate()[1] assert "Traceback (most recent call last):" not in stderr
def test_perl_modules(site: Site): # TODO: Complete this list test_modules = [ "Getopt::Long", "File::stat", "File::Find", "File::Path", "SNMP", "Nagios::Plugin", "Test::Simple", "Try::Tiny", "Params::Validate", "Module::Runtime", "Module::Metadata", "Module::Implementation", "Module::Build", "Math::Calc::Units", "Config::Tiny", "Class::Accessor", # Webinject "Carp", "LWP", "URI", "HTTP::Request::Common", "HTTP::Cookies", "XML::Simple", "Time::HiRes", "Crypt::SSLeay", "XML::Parser", "Data::Dumper", "File::Temp", # Check_oracle_health "File::Basename", "IO::File", "File::Copy", "Sys::Hostname", "Data::Dumper", "Net::Ping", ] for module in test_modules: p = site.execute(["perl", "-e", "use %s" % module]) assert p.wait() == 0, "Failed to load module: %s" % module
def _execute_restore(site: Site, backup_id, env=None, restore_site=True): p = site.execute( ["mkbackup", "restore", "test-target", backup_id], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, encoding="utf-8", ) stdout, stderr = p.communicate() try: assert stderr == "" assert "Restore completed" in stdout, "Invalid output: %r" % stdout assert p.wait() == 0 except Exception: if restore_site: # Bring back the site in case the restore test fails which may leave the # site in a stopped state site.start() raise
def test_03_python_path(site: Site): p = site.execute( ["python3", "-c", "import sys,json; json.dump(sys.path, sys.stdout)"], stdout=subprocess.PIPE, ) sys_path = json.loads(p.stdout.read()) if p.stdout else "<NO STDOUT>" assert sys_path[0] == "" ordered_path_elements = [ # there may be more, but these have to occur in this order: site.root + "/local/lib/python3", site.root + "/lib/python3/plus", site.root + "/lib/python3.10", site.root + "/lib/python3", ] assert [s for s in sys_path if s in ordered_path_elements] == ordered_path_elements for path in sys_path[1:]: assert path.startswith( site.root), f"Found non site path {path!r} in sys.path"
def test_test_check_1(request, site: Site, web): host_name = "check-variables-test-host" create_linux_test_host(request, site, host_name) site.write_text_file(f"var/check_mk/agent_output/{host_name}", "<<<test_check_1>>>\n1 2\n") test_check_path = "local/share/check_mk/checks/test_check_1" def cleanup(): if site.file_exists("etc/check_mk/conf.d/test_check_1.mk"): site.delete_file("etc/check_mk/conf.d/test_check_1.mk") site.delete_file(test_check_path) request.addfinalizer(cleanup) site.write_text_file( test_check_path, """ test_check_1_default_levels = 10.0, 20.0 def inventory(info): return [(None, "test_check_1_default_levels")] def check(item, params, info): return 0, "OK - %r" % (test_check_1_default_levels, ) check_info["test_check_1"] = { "check_function" : check, "inventory_function" : inventory, "service_description" : "Testcheck 1", # "default_levels_variable" : "test_check_1_default_levels" } """, ) config.load_checks(check_api.get_check_api_context, ["%s/%s" % (site.root, test_check_path)]) config.load(with_conf_d=False) site.activate_changes_and_wait_for_core_reload() # Verify that the default variable is in the check context and # not in the global checks module context. assert "test_check_1_default_levels" not in config.__dict__ assert "test_check_1" in config._check_contexts assert "test_check_1_default_levels" in config._check_contexts[ "test_check_1"] assert config._check_contexts["test_check_1"][ "test_check_1_default_levels"] == (10.0, 20.0) web.discover_services(host_name) # Replace with RestAPI call, see CMK-9249 # Verify that the discovery worked as expected entries = autochecks.AutochecksStore(HostName(host_name)).read() assert str(entries[0].check_plugin_name) == "test_check_1" assert entries[0].item is None assert entries[0].parameters == (10.0, 20.0) assert entries[0].service_labels == {} # Now execute the check function to verify the variable is available p = site.execute(["cmk", "-nv", host_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert "OK - (10.0, 20.0)" in stdout assert stderr == "" assert p.returncode == 0 # And now overwrite the setting in the config site.write_text_file("etc/check_mk/conf.d/test_check_1.mk", "test_check_1_default_levels = 5.0, 30.1\n") p = site.execute(["cmk", "-nv", host_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert "OK - (10.0, 20.0)" not in stdout assert "OK - (5.0, 30.1)" in stdout assert stderr == "" assert p.returncode == 0 # rediscover with the setting in the config site.delete_file(f"var/check_mk/autochecks/{host_name}.mk") web.discover_services(host_name) # Replace with RestAPI call, see CMK-9249 entries = autochecks.AutochecksStore(HostName(host_name)).read() assert entries[0].parameters == (5.0, 30.1)
def test_03_pip_interpreter_version(site: Site): p = site.execute(["pip3", "-V"], stdout=subprocess.PIPE) version = p.stdout.read() if p.stdout else "<NO STDOUT>" assert version.startswith("pip 21.2.4")
def test_02_pip_path(site: Site): p = site.execute(["which", "pip3"], stdout=subprocess.PIPE) path = p.stdout.read().strip() if p.stdout else "<NO STDOUT>" assert path == "/omd/sites/%s/bin/pip3" % site.id
def test_03_python_interpreter_version(site: Site): p = site.execute(["python3", "-V"], stdout=subprocess.PIPE) version = p.stdout.read() if p.stdout else "<NO STDOUT>" assert version.startswith("Python 3.9.10")
def test_dcd_version(site: Site): p = site.execute(["dcd", "-V"], stdout=subprocess.PIPE) version = p.stdout.read() if p.stdout else "<NO STDOUT>" assert version.startswith("dcd version %s" % site.version.version)
def test_dcd_daemon(site: Site): p = site.execute(["omd", "status", "--bare", "dcd"], stdout=subprocess.PIPE) assert p.wait() == 0 assert p.stdout.read() == "dcd 0\nOVERALL 0\n" if p.stdout else False
def test_check_factory_settings(request, site: Site, web): host_name = "check-variables-test-host" create_linux_test_host(request, site, host_name) site.write_text_file(f"var/check_mk/agent_output/{host_name}", "<<<test_check_3>>>\n1 2\n") test_check_path = "local/share/check_mk/checks/test_check_3" def cleanup(): if site.file_exists("etc/check_mk/conf.d/test_check_3.mk"): site.delete_file("etc/check_mk/conf.d/test_check_3.mk") site.delete_file(test_check_path) request.addfinalizer(cleanup) site.write_text_file( test_check_path, """ factory_settings["test_check_3_default_levels"] = { "param1": 123, } def inventory(info): return [(None, {})] def check(item, params, info): return 0, "OK - %r" % (params, ) check_info["test_check_3"] = { "check_function" : check, "inventory_function" : inventory, "service_description" : "Testcheck 3", "group" : "asd", "default_levels_variable" : "test_check_3_default_levels", } """, ) config.load_checks(check_api.get_check_api_context, ["%s/%s" % (site.root, test_check_path)]) config.load(with_conf_d=False) site.activate_changes_and_wait_for_core_reload() # Verify that the default variable is in the check context and # not in the global checks module context assert "test_check_3_default_levels" not in config.__dict__ assert "test_check_3" in config._check_contexts assert "test_check_3_default_levels" in config._check_contexts[ "test_check_3"] web.discover_services(host_name) # Replace with RestAPI call, see CMK-9249 # Verify that the discovery worked as expected entries = autochecks.AutochecksStore(HostName(host_name)).read() assert str(entries[0].check_plugin_name) == "test_check_3" assert entries[0].item is None assert entries[0].parameters == {} assert entries[0].service_labels == {} # Now execute the check function to verify the variable is available p = site.execute(["cmk", "-nv", host_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert "OK - {'param1': 123}\n" in stdout, stdout assert stderr == "" assert p.returncode == 0 # And now overwrite the setting in the config site.write_text_file( "etc/check_mk/conf.d/test_check_3.mk", """ checkgroup_parameters.setdefault('asd', []) checkgroup_parameters['asd'] = [ ( {'param2': 'xxx'}, [], ALL_HOSTS, {} ), ] + checkgroup_parameters['asd'] """, ) # And execute the check again to check for the parameters p = site.execute(["cmk", "-nv", host_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert "'param1': 123" in stdout assert "'param2': 'xxx'" in stdout assert stderr == "" assert p.returncode == 0