diff --git a/checks.d/docker.py b/checks.d/docker.py index 44aed36804..3d74d44ce0 100644 --- a/checks.d/docker.py +++ b/checks.d/docker.py @@ -109,8 +109,8 @@ def unix_open(self, req): class Docker(AgentCheck): """Collect metrics and events from Docker API and cgroups""" - def __init__(self, name, init_config, agentConfig): - AgentCheck.__init__(self, name, init_config, agentConfig) + def __init__(self, name, init_config, agentConfig, instances=None): + AgentCheck.__init__(self, name, init_config, agentConfig, instances) # Initialize a HTTP opener with Unix socket support socket_timeout = int(init_config.get('socket_timeout', 0)) or DEFAULT_SOCKET_TIMEOUT @@ -415,11 +415,13 @@ def _get_cgroup_file(self, cgroup, container_id, filename): def _find_cgroup(self, hierarchy, docker_root): """Finds the mount point for a specified cgroup hierarchy. Works with old style and new style mounts.""" + fp = None try: fp = open(os.path.join(docker_root, "/proc/mounts")) mounts = map(lambda x: x.split(), fp.read().splitlines()) finally: - fp.close() + if fp is not None: + fp.close() cgroup_mounts = filter(lambda x: x[2] == "cgroup", mounts) if len(cgroup_mounts) == 0: raise Exception("Can't find mounted cgroups. If you run the Agent inside a container," diff --git a/tests/common.py b/tests/common.py index 41e8ed1310..cdc78fc4e8 100644 --- a/tests/common.py +++ b/tests/common.py @@ -11,6 +11,26 @@ from config import get_checksd_path from util import get_os, get_hostname +def get_check_class(name): + checksd_path = get_checksd_path(get_os()) + if checksd_path not in sys.path: + sys.path.append(checksd_path) + + check_module = __import__(name) + check_class = None + classes = inspect.getmembers(check_module, inspect.isclass) + for _, clsmember in classes: + if clsmember == AgentCheck: + continue + if issubclass(clsmember, AgentCheck): + check_class = clsmember + if AgentCheck in clsmember.__bases__: + continue + else: + break + + return check_class + def load_check(name, config, agentConfig): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: diff --git a/tests/test_docker.py b/tests/test_docker.py new file mode 100644 index 0000000000..3d1d927b77 --- /dev/null +++ b/tests/test_docker.py @@ -0,0 +1,77 @@ +import unittest + +from mock import patch + +from tests.common import get_check_class + +def _mocked_find_cgroup(*args, **kwargs): + return + +class DockerCheckTest(unittest.TestCase): + def test_tag_exclude_all(self): + """ exclude all, except ubuntu and debian. """ + instance = { + 'include': [ + 'docker_image:ubuntu', + 'docker_image:debian', + ], + 'exclude': ['.*'], + } + + klass = get_check_class('docker') + # NO-OP but loads the check + with patch.object(klass, '_find_cgroup', _mocked_find_cgroup): + check = klass('docker', {}, {}) + + check._prepare_filters(instance) + self.assertEquals(len(instance['exclude_patterns']), 1) + self.assertEquals(len(instance['include_patterns']), 2) + + truth_table_exclusion = { + 'some_tag': True, + 'debian:ubuntu': True, + 'docker_image:centos': True, + 'docker_image:ubuntu': False, + 'docker_image:debian': False, + } + + for tag, val in truth_table_exclusion.iteritems(): + self.assertEquals( + check._is_container_excluded(instance, [tag]), + val, + "{0} expected {1} but is not".format(tag, val) + ) + + def test_tag_include_all(self): + """ exclude all, except ubuntu and debian. """ + instance = { + 'include': [], + 'exclude': [ + 'docker_image:ubuntu', + 'docker_image:debian', + ], + } + + klass = get_check_class('docker') + # NO-OP but loads the check + with patch.object(klass, '_find_cgroup', _mocked_find_cgroup): + check = klass('docker', {}, {}) + + check._prepare_filters(instance) + self.assertEquals(len(instance['exclude_patterns']), 2) + self.assertEquals(len(instance['include_patterns']), 0) + + truth_table_exclusion = { + 'some_tag': False, + 'debian:ubuntu': False, + 'docker_image:centos': False, + 'docker_image:ubuntu': True, + 'docker_image:debian': True, + } + + for tag, val in truth_table_exclusion.iteritems(): + self.assertEquals( + check._is_container_excluded(instance, [tag]), + val, + "{0} expected {1} but is not".format(tag, val) + )