Skip to content

Commit

Permalink
Prepare for raw edition based testing
Browse files Browse the repository at this point in the history
* Move CEE specific tests to cee related directory

* Split expected items lists in plugin registration checks
  to edition specific lists

* Make tests only read edition specific paths in CEE/CME
  checkouts (the ones with enterprise or managed sub directory)

* Make check unit tests work with timezone different than CET

  Several unit fake the system time during unit tests and output
  some local time output. All these tests now correctly fake the
  time and timezone to get deterministic results.

Change-Id: I1ee66f963dc98036a2b58569bdcc1a8cf713bd79
  • Loading branch information
LarsMichelsen committed Oct 28, 2019
1 parent 679d844 commit 9137fb2
Show file tree
Hide file tree
Showing 29 changed files with 636 additions and 514 deletions.
8 changes: 6 additions & 2 deletions tests-py3/find-python-files
Expand Up @@ -13,10 +13,14 @@ SEARCH+=" checks"
SEARCH+=" cmk"
SEARCH+=" cmk_base"
SEARCH+=" doc"
SEARCH+=" enterprise"
if [ -d "$REPO_PATH/enterprise" ]; then
SEARCH+=" enterprise"
fi
SEARCH+=" inventory"
SEARCH+=" livestatus"
SEARCH+=" managed"
if [ -d "$REPO_PATH/managed" ]; then
SEARCH+=" managed"
fi
SEARCH+=" locale"
SEARCH+=" notifications"
# Do not search whole omd/ because it may contain unpacked sub-packages
Expand Down
22 changes: 13 additions & 9 deletions tests/find-python-files
Expand Up @@ -13,10 +13,14 @@ SEARCH+=" checks"
SEARCH+=" cmk"
SEARCH+=" cmk_base"
SEARCH+=" doc"
SEARCH+=" enterprise"
if [ -d "$REPO_PATH/enterprise" ]; then
SEARCH+=" enterprise"
fi
SEARCH+=" inventory"
SEARCH+=" livestatus"
SEARCH+=" managed"
if [ -d "$REPO_PATH/managed" ]; then
SEARCH+=" managed"
fi
SEARCH+=" notifications"
# Do not search whole omd/ because it may contain unpacked sub-packages
SEARCH+=" omd/packages/appliance"
Expand All @@ -32,13 +36,13 @@ REAL_SEARCH=$(realpath $SEARCH)

# while read F is used to deal with files containing whitespaces
find $REAL_SEARCH \
-name .mypy_cache -prune -o \
-name .venv -prune -o \
-name test_docker_parse_node_images.py -prune -o \
-name typeshed -prune -o \
-name run-clang-tidy.py -prune -o \
-name chroot -prune -o \
-type f -print | sort | while read F; do
-name .mypy_cache -prune -o \
-name .venv -prune -o \
-name test_docker_parse_node_images.py -prune -o \
-name typeshed -prune -o \
-name run-clang-tidy.py -prune -o \
-name chroot -prune -o \
-type f -print | sort | while read F; do
if [[ "$F" == *.py ]] || head -n 1 "$F" | grep -q '^#!.*python$' >/dev/null 2>&1; then
echo "$F"
fi
Expand Down
60 changes: 35 additions & 25 deletions tests/pylint/test_pylint.py
Expand Up @@ -8,7 +8,12 @@
import shutil
import pytest # type: ignore

from testlib import cmk_path, repo_path
from testlib import (
cmk_path,
repo_path,
is_enterprise_repo,
is_managed_repo,
)
import testlib.pylint_cmk as pylint_cmk


Expand Down Expand Up @@ -41,37 +46,38 @@ def test_pylint(pylint_test_dir):
modules_or_packages = []
else:
modules_or_packages = [
# OMD
"omd/packages/omd/omdlib",
"livestatus/api/python/livestatus.py",

# Check_MK base
"cmk_base",
# TODO: Check if this kind of "overlay" really works.
# TODO: Why do we have e.g. a symlink cmk_base/cee -> enterprise/cmk_base/cee?
"enterprise/cmk_base/automations/cee.py",
"enterprise/cmk_base/cee",
"enterprise/cmk_base/default_config/cee.py",
"enterprise/cmk_base/modes/cee.py",
"managed/cmk_base/default_config/cme.py",

# cmk module level
# TODO: This checks the whole cmk hierarchy, including things like
# cmk.gui.plugins.cron etc. Do we really want that here?
# TODO: Funny links there, see above.
"cmk",
"enterprise/cmk/cee",

# GUI specific
"web/app/index.wsgi",
"enterprise/cmk/gui/cee",
"managed/cmk/gui/cme",
]

if is_enterprise_repo():
modules_or_packages += [
# TODO: Check if this kind of "overlay" really works.
# TODO: Why do we have e.g. a symlink cmk_base/cee -> enterprise/cmk_base/cee?
"enterprise/cmk_base/automations/cee.py",
"enterprise/cmk_base/cee",
"enterprise/cmk_base/default_config/cee.py",
"enterprise/cmk_base/modes/cee.py",
# TODO: Funny links there, see above.
"enterprise/cmk/cee",
"enterprise/cmk/gui/cee",
]

if is_managed_repo():
modules_or_packages += [
"managed/cmk_base/default_config/cme.py",
"managed/cmk/gui/cme",
]

# Add the compiled files for things that are no modules yet
open(pylint_test_dir + "/__init__.py", "w")
_compile_check_and_inventory_plugins(pylint_test_dir)
_compile_bakery_plugins(pylint_test_dir)

if is_enterprise_repo():
_compile_bakery_plugins(pylint_test_dir)

# Not checking compiled check, inventory, bakery plugins with Python 3
if sys.version_info[0] == 2:
Expand All @@ -87,11 +93,15 @@ def test_pylint(pylint_test_dir):
"agents/plugins",
"agents/special",
"active_checks",
"enterprise/agents/plugins",
"enterprise/bin",
"enterprise/misc",
]

if is_enterprise_repo():
search_paths += [
"enterprise/agents/plugins",
"enterprise/bin",
"enterprise/misc",
]

for path in search_paths:
abs_path = cmk_path() + "/" + path
for fname in pylint_cmk.get_pylint_files(abs_path, "*"):
Expand Down
16 changes: 15 additions & 1 deletion tests/testlib/__init__.py
Expand Up @@ -13,6 +13,7 @@
import ast
import abc
import tempfile
import datetime
from contextlib import contextmanager
import six

Expand All @@ -37,6 +38,8 @@
is_running_as_site_user,
site_id,
add_python_paths,
is_enterprise_repo,
is_managed_repo,
)
from testlib.fixtures import web, ec
from testlib.site import Site, SiteFactory
Expand Down Expand Up @@ -75,7 +78,15 @@ def fake_version_and_paths():
tmp_dir = tempfile.mkdtemp(prefix="pytest_cmk_")

import cmk
monkeypatch.setattr(cmk, "omd_version", lambda: "%s.cee" % cmk.__version__)

# TODO: handle CME case
#if is_managed_repo():
# monkeypatch.setattr(cmk, "omd_version", lambda: "%s.cee" % cmk.__version__)
#elif is_enterprise_repo():
if is_enterprise_repo():
monkeypatch.setattr(cmk, "omd_version", lambda: "%s.cee" % cmk.__version__)
else:
monkeypatch.setattr(cmk, "omd_version", lambda: "%s.cre" % cmk.__version__)

monkeypatch.setattr("cmk.utils.paths.agents_dir", "%s/agents" % cmk_path())
monkeypatch.setattr("cmk.utils.paths.checks_dir", "%s/checks" % cmk_path())
Expand Down Expand Up @@ -374,6 +385,9 @@ def __init__(self, name):
@contextmanager
def on_time(utctime, timezone):
"""Set the time and timezone for the test"""
if isinstance(utctime, (int, float)):
utctime = datetime.datetime.utcfromtimestamp(utctime)

os.environ['TZ'] = timezone
time.tzset()
with freezegun.freeze_time(utctime):
Expand Down
8 changes: 8 additions & 0 deletions tests/testlib/utils.py
Expand Up @@ -39,6 +39,14 @@ def cme_path():
return repo_path() + "/managed"


def is_enterprise_repo():
return os.path.exists(cmc_path())


def is_managed_repo():
return os.path.exists(cme_path())


def virtualenv_path():
venv = subprocess.check_output(["pipenv", "--bare", "--venv"])
if not isinstance(venv, six.text_type):
Expand Down
102 changes: 0 additions & 102 deletions tests/unit/agents/plugins/test_mk_logwatch_bakery.py

This file was deleted.

8 changes: 4 additions & 4 deletions tests/unit/checks/test_generic_datasets.py
Expand Up @@ -16,15 +16,15 @@
regression test dataset as described in ''checks/generictests/regression.py''
"""
from importlib import import_module
from pathlib2 import Path
import pytest # type: ignore
from testlib import cmk_path
import testlib
import generictests

pytestmark = pytest.mark.checks


@pytest.mark.parametrize("datasetname", generictests.DATASET_NAMES)
def test_dataset(check_manager, datasetname):
dataset = import_module("generictests.datasets.%s" % datasetname)
generictests.run(check_manager, dataset)
with testlib.on_time(1572247138, "CET"):
dataset = import_module("generictests.datasets.%s" % datasetname)
generictests.run(check_manager, dataset)
32 changes: 17 additions & 15 deletions tests/unit/checks/test_ps.py
@@ -1,10 +1,12 @@
# yapf: disable
from collections import namedtuple
from six.moves import zip_longest
import pytest
import pytest # type: ignore
import datetime
from cmk_base.check_api import MKGeneralException
from cmk_base.discovered_labels import DiscoveredHostLabels, HostLabel
from checktestlib import CheckResult, assertCheckResultsEqual
from testlib import on_time

pytestmark = pytest.mark.checks

Expand Down Expand Up @@ -699,12 +701,12 @@ def test_check_ps_common(check_manager, monkeypatch, inv_item, reference):
check = check_manager.get_check("ps")
parsed = sum([check.context['parse_ps'](info)[1] for info in generate_inputs()], [])
total_ram = 1024**3 if "emacs" in inv_item[0] else None
monkeypatch.setattr('time.time', lambda: 1540375342)
factory_defaults = {"levels": (1, 1, 99999, 99999)}
factory_defaults.update(inv_item[1])
test_result = CheckResult(check.context["check_ps_common"](
inv_item[0], factory_defaults, parsed, total_ram=total_ram))
assertCheckResultsEqual(test_result, reference)
with on_time(1540375342, "CET"):
factory_defaults = {"levels": (1, 1, 99999, 99999)}
factory_defaults.update(inv_item[1])
test_result = CheckResult(check.context["check_ps_common"](
inv_item[0], factory_defaults, parsed, total_ram=total_ram))
assertCheckResultsEqual(test_result, reference)


cpu_config = namedtuple("CPU_config", "name agent_info cputime cpu_cores exp_load cpu_rescale_max")
Expand Down Expand Up @@ -742,11 +744,11 @@ def test_check_ps_common_cpu(check_manager, monkeypatch, data):
check = check_manager.get_check("ps")

def time_info(agent_info, check_time, cputime, cpu_cores):
monkeypatch.setattr('time.time', lambda: check_time)
parsed = check.context['parse_ps'](splitter(agent_info.format(cputime)))[1]
with on_time(datetime.datetime.utcfromtimestamp(check_time), "CET"):
parsed = check.context['parse_ps'](splitter(agent_info.format(cputime)))[1]

return CheckResult(check.context["check_ps_common"](
inv_item[0], inv_item[1], parsed, cpu_cores=cpu_cores))
return CheckResult(check.context["check_ps_common"](
inv_item[0], inv_item[1], parsed, cpu_cores=cpu_cores))

inv_item = (
"test",
Expand Down Expand Up @@ -880,14 +882,14 @@ def test_cpu_util_single_process_levels(check_manager, monkeypatch, cpu_cores):
}

def run_check_ps_common_with_elapsed_time(check_time, cputime):
monkeypatch.setattr('time.time', lambda: check_time)
agent_info = """(on,2275004,434008,00:00:49/26:58,25576) firefox
with on_time(check_time, "CET"):
agent_info = """(on,2275004,434008,00:00:49/26:58,25576) firefox
(on,1869920,359836,00:01:23/6:57,25664) firefox
(on,7962644,229660,00:00:10/26:56,25758) firefox
(on,1523536,83064,00:{:02}:00/26:55,25898) firefox"""
parsed = check.context['parse_ps'](splitter(agent_info.format(cputime)))[1]
parsed = check.context['parse_ps'](splitter(agent_info.format(cputime)))[1]

return CheckResult(check.context["check_ps_common"](
return CheckResult(check.context["check_ps_common"](
'firefox', params, parsed, cpu_cores=cpu_cores))

# CPU utilization is a counter, initialize it
Expand Down

0 comments on commit 9137fb2

Please sign in to comment.