From 20360840093ba01a14ea3ad3b72cd125db1a5fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 13:23:40 +0200 Subject: [PATCH 01/16] Hostgroup members (#110) and tests refactoring --- alignak/objects/hostgroup.py | 17 ++- test/_old/etc/alignak_hostgroup_no_host.cfg | 23 --- .../_old/etc/alignak_hostgroup_with_space.cfg | 74 --------- test/_old/test_hostgroup_no_host.py | 63 -------- test/_old/test_hostgroup_with_space.py | 66 -------- test/_old/test_hostgroup_with_void_member.py | 61 -------- .../hostgroup/alignak_hostgroup_members.cfg | 8 + .../hostgroup/alignak_hostgroup_no_host.cfg | 6 + .../alignak_hostgroup_with_space.cfg | 13 ++ .../alignak_hostgroup_with_void_member.cfg | 2 + test/test_hostgroup.py | 141 ++++++++++++++++++ 11 files changed, 179 insertions(+), 295 deletions(-) delete mode 100644 test/_old/etc/alignak_hostgroup_no_host.cfg delete mode 100644 test/_old/etc/alignak_hostgroup_with_space.cfg delete mode 100644 test/_old/test_hostgroup_no_host.py delete mode 100644 test/_old/test_hostgroup_with_space.py delete mode 100644 test/_old/test_hostgroup_with_void_member.py create mode 100755 test/cfg/hostgroup/alignak_hostgroup_members.cfg create mode 100755 test/cfg/hostgroup/alignak_hostgroup_no_host.cfg create mode 100755 test/cfg/hostgroup/alignak_hostgroup_with_space.cfg rename test/{_old/etc => cfg/hostgroup}/alignak_hostgroup_with_void_member.cfg (95%) mode change 100644 => 100755 create mode 100755 test/test_hostgroup.py diff --git a/alignak/objects/hostgroup.py b/alignak/objects/hostgroup.py index 9dd0b5923..c59dcf86d 100644 --- a/alignak/objects/hostgroup.py +++ b/alignak/objects/hostgroup.py @@ -70,14 +70,15 @@ class Hostgroup(Itemgroup): properties = Itemgroup.properties.copy() properties.update({ - 'uuid': StringProp(default='', fill_brok=['full_status']), - 'hostgroup_name': StringProp(fill_brok=['full_status']), - 'alias': StringProp(fill_brok=['full_status']), - 'notes': StringProp(default='', fill_brok=['full_status']), - 'notes_url': StringProp(default='', fill_brok=['full_status']), - 'action_url': StringProp(default='', fill_brok=['full_status']), - 'realm': StringProp(default='', fill_brok=['full_status'], - conf_send_preparation=get_obj_name), + 'uuid': StringProp(default='', fill_brok=['full_status']), + 'hostgroup_name': StringProp(fill_brok=['full_status']), + 'alias': StringProp(fill_brok=['full_status']), + 'hostgroup_members': StringProp(fill_brok=['full_status']), + 'notes': StringProp(default='', fill_brok=['full_status']), + 'notes_url': StringProp(default='', fill_brok=['full_status']), + 'action_url': StringProp(default='', fill_brok=['full_status']), + 'realm': StringProp(default='', fill_brok=['full_status'], + conf_send_preparation=get_obj_name), }) macros = { diff --git a/test/_old/etc/alignak_hostgroup_no_host.cfg b/test/_old/etc/alignak_hostgroup_no_host.cfg deleted file mode 100644 index 3dce7c336..000000000 --- a/test/_old/etc/alignak_hostgroup_no_host.cfg +++ /dev/null @@ -1,23 +0,0 @@ -define hostgroup { - hostgroup_name void - alias Void group -} - -define service{ - active_checks_enabled 1 - check_command check_service!ok - check_interval 1 - hostgroup_name void - icon_image ../../docs/images/tip.gif - icon_image_alt icon alt string - notes just a notes string - retry_interval 1 - service_description test_void_no_host - servicegroups servicegroup_01,ok - use generic-service - event_handler eventhandler - notes_url /alignak/wiki/doku.php/$HOSTNAME$/$SERVICEDESC$ - action_url /alignak/pnp/index.php?host=$HOSTNAME$&srv=$SERVICEDESC$ - _custname custvalue -} - diff --git a/test/_old/etc/alignak_hostgroup_with_space.cfg b/test/_old/etc/alignak_hostgroup_with_space.cfg deleted file mode 100644 index 32f7a99b0..000000000 --- a/test/_old/etc/alignak_hostgroup_with_space.cfg +++ /dev/null @@ -1,74 +0,0 @@ -define service{ - active_checks_enabled 1 - check_command check_service!ok - check_interval 1 - hostgroups I love have long name,And Another One - icon_image ../../docs/images/tip.gif?host=$HOSTNAME$&srv=$SERVICEDESC$ - icon_image_alt icon alt string - notes just a notes string - retry_interval 1 - service_description test_With Spaces - servicegroups servicegroup_01,ok - use generic-service - event_handler eventhandler - notes_url /alignak/wiki/doku.php/$HOSTNAME$/$SERVICEDESC$ - action_url /alignak/pnp/index.php?host=$HOSTNAME$&srv=$SERVICEDESC$ - _custname custvalue -} - - - -define service{ - active_checks_enabled 1 - check_command check_service!ok - check_interval 1 - hostgroups I love have long name & And Another One - icon_image ../../docs/images/tip.gif?host=$HOSTNAME$&srv=$SERVICEDESC$ - icon_image_alt icon alt string - notes just a notes string - retry_interval 1 - service_description test_With anoter Spaces - servicegroups servicegroup_01,ok - use generic-service - event_handler eventhandler - notes_url /alignak/wiki/doku.php/$HOSTNAME$/$SERVICEDESC$ - action_url /alignak/pnp/index.php?host=$HOSTNAME$&srv=$SERVICEDESC$ - _custname custvalue -} - - -define service{ - active_checks_enabled 1 - check_command check_service!ok - check_interval 1 - hostgroups With a dot . here&And Another One - icon_image ../../docs/images/tip.gif?host=$HOSTNAME$&srv=$SERVICEDESC$ - icon_image_alt icon alt string - notes just a notes string - retry_interval 1 - service_description test_With dot - servicegroups servicegroup_01,ok - use generic-service - event_handler eventhandler - notes_url /alignak/wiki/doku.php/$HOSTNAME$/$SERVICEDESC$ - action_url /alignak/pnp/index.php?host=$HOSTNAME$&srv=$SERVICEDESC$ - _custname custvalue -} - - -define hostgroup { - hostgroup_name I love have long name - members test_router_0,test_host_0 -} - - -define hostgroup { - hostgroup_name And Another One - members test_router_0,test_host_0 -} - - -define hostgroup { - hostgroup_name With a dot . here - members test_router_0,test_host_0 -} diff --git a/test/_old/test_hostgroup_no_host.py b/test/_old/test_hostgroup_no_host.py deleted file mode 100644 index d924cd75d..000000000 --- a/test/_old/test_hostgroup_no_host.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Hartmut Goebel, h.goebel@goebel-consult.de -# Grégory Starck, g.starck@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestHostGroupNoHost(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_hostgroup_no_host.cfg']) - - def test_hostgroup_wit_no_host(self): - self.assertTrue(self.sched.conf.conf_is_correct) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/_old/test_hostgroup_with_space.py b/test/_old/test_hostgroup_with_space.py deleted file mode 100644 index b2ca6ffa7..000000000 --- a/test/_old/test_hostgroup_with_space.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Grégory Starck, g.starck@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestHostGroupWithSpace(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_hostgroup_with_space.cfg']) - - - def test_hostgroup_with_space(self): - svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "test_With Spaces") - self.assertIsNot(svc, None) - - svc = self.sched.services.find_srv_by_name_and_hostname("test_host_0", 'test_With anoter Spaces') - self.assertIsNot(svc, None) - -if __name__ == '__main__': - unittest.main() diff --git a/test/_old/test_hostgroup_with_void_member.py b/test/_old/test_hostgroup_with_void_member.py deleted file mode 100644 index 5d97928a8..000000000 --- a/test/_old/test_hostgroup_with_void_member.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -# test members property with , at the end -class TestHostgroupAndContactGroupWithVoidMember(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_hostgroup_with_void_member.cfg']) - - def test_me(self): - self.assertTrue(self.sched.conf.is_correct) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/cfg/hostgroup/alignak_hostgroup_members.cfg b/test/cfg/hostgroup/alignak_hostgroup_members.cfg new file mode 100755 index 000000000..ab4615fd1 --- /dev/null +++ b/test/cfg/hostgroup/alignak_hostgroup_members.cfg @@ -0,0 +1,8 @@ +cfg_dir=../default + +define hostgroup { + hostgroup_name allhosts_and_groups + alias All Hosts and groups + members test_router_0,test_host_0 + hostgroup_members router, hostgroup_01, hostgroup_02, hostgroup_03, hostgroup_04 +} diff --git a/test/cfg/hostgroup/alignak_hostgroup_no_host.cfg b/test/cfg/hostgroup/alignak_hostgroup_no_host.cfg new file mode 100755 index 000000000..be675c65a --- /dev/null +++ b/test/cfg/hostgroup/alignak_hostgroup_no_host.cfg @@ -0,0 +1,6 @@ +cfg_dir=../default + +define hostgroup { + hostgroup_name void + alias Void group +} diff --git a/test/cfg/hostgroup/alignak_hostgroup_with_space.cfg b/test/cfg/hostgroup/alignak_hostgroup_with_space.cfg new file mode 100755 index 000000000..15beb8ee4 --- /dev/null +++ b/test/cfg/hostgroup/alignak_hostgroup_with_space.cfg @@ -0,0 +1,13 @@ +cfg_dir=../default + +define hostgroup { + hostgroup_name test_With Spaces + members test_router_0,test_host_0 +} + + +define hostgroup { + hostgroup_name test_With another Spaces + members test_router_0,test_host_0 +} + diff --git a/test/_old/etc/alignak_hostgroup_with_void_member.cfg b/test/cfg/hostgroup/alignak_hostgroup_with_void_member.cfg old mode 100644 new mode 100755 similarity index 95% rename from test/_old/etc/alignak_hostgroup_with_void_member.cfg rename to test/cfg/hostgroup/alignak_hostgroup_with_void_member.cfg index a4a54131c..24a594d9f --- a/test/_old/etc/alignak_hostgroup_with_void_member.cfg +++ b/test/cfg/hostgroup/alignak_hostgroup_with_void_member.cfg @@ -1,3 +1,5 @@ +cfg_dir=../default + define hostgroup{ hostgroup_name MYGROUP members h1,h2, diff --git a/test/test_hostgroup.py b/test/test_hostgroup.py new file mode 100755 index 000000000..9d6f3536d --- /dev/null +++ b/test/test_hostgroup.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors +# +# This file is part of Alignak. +# +# Alignak is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alignak is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Alignak. If not, see . +# +# + +""" +This file test all cases of eventhandler +""" + +import time + +from alignak.objects import Hostgroup +from alignak_test import AlignakTest + + +class TestHostGroup(AlignakTest): + """ + This class tests the hostgroups + """ + + def test_hostgroup(self): + """ + Default configuration has no loading problems ... as of it hostgroups are parsed correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + +class TestHostGroupMembers(AlignakTest): + """ + This class tests the hostgroups + """ + + def test_hostgroup_members(self): + """ + :return: None + """ + self.print_header() + self.setup_with_file('cfg/hostgroup/alignak_hostgroup_members.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a hostgroup named allhosts_and_groups + hg = self.schedulers[0].sched.hostgroups.find_by_name("allhosts_and_groups") + self.assertIsInstance(hg, Hostgroup) + self.assertEqual(hg.get_name(), "allhosts_and_groups") + + self.assertEqual( + len(self.schedulers[0].sched.hostgroups.get_members_by_name("allhosts_and_groups")), + 2 + ) + + self.assertEqual(len(hg.get_hostgroup_members()), 5) + + self.assertEqual(len(hg.get_hosts()), 2) + + +class TestHostGroupNoHost(AlignakTest): + + def test_hostgroup_with_no_host(self): + """ + Allow hostgroups with no hosts + :return: None + """ + self.print_header() + self.setup_with_file('cfg/hostgroup/alignak_hostgroup_no_host.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + # Found a hostgroup named void + hg = self.schedulers[0].sched.hostgroups.find_by_name("void") + self.assertIsInstance(hg, Hostgroup) + self.assertEqual(hg.get_name(), "void") + + self.assertEqual( + len(self.schedulers[0].sched.hostgroups.get_members_by_name("void")), + 0 + ) + + self.assertEqual(len(hg.get_hostgroup_members()), 0) + + self.assertEqual(len(hg.get_hosts()), 0) + + +class TestHostGroupWithSpace(AlignakTest): + + def test_hostgroup_with_space(self): + """ + Test that hostgroups can have a name with spaces + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + self.nb_hostgroups = len(self.schedulers[0].sched.hostgroups) + + self.setup_with_file('cfg/hostgroup/alignak_hostgroup_with_space.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + # Two more groups than the default configuration + self.assertEqual( + len(self.schedulers[0].sched.hostgroups), self.nb_hostgroups + 2 + ) + + self.assertEqual( + self.schedulers[0].sched.hostgroups.find_by_name("test_With Spaces").get_name(), + "test_With Spaces" + ) + self.assertIsNot( + self.schedulers[0].sched.hostgroups.get_members_by_name( + "test_With Spaces" + ), + [] + ) + + self.assertEqual( + self.schedulers[0].sched.hostgroups.find_by_name("test_With another Spaces").get_name(), + "test_With another Spaces" + ) + self.assertIsNot( + self.schedulers[0].sched.hostgroups.get_members_by_name( + "test_With another Spaces" + ), + [] + ) From 7ea1181f0351c1c8296aab06c36b88139b9f82ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 14:05:39 +0200 Subject: [PATCH 02/16] Hostgroup members (#110) and tests refactoring (2) Remove old test test_groups_pickle --- alignak/objects/contactgroup.py | 1 + alignak/objects/servicegroup.py | 12 +-- test/_old/etc/alignak_groups_pickle.cfg | 56 ------------ test/_old/test_groups_pickle.py | 90 ------------------- .../hostgroup/alignak_hostgroup_members.cfg | 2 +- test/test_hostgroup.py | 57 +++++++++++- 6 files changed, 64 insertions(+), 154 deletions(-) delete mode 100644 test/_old/etc/alignak_groups_pickle.cfg delete mode 100644 test/_old/test_groups_pickle.py diff --git a/alignak/objects/contactgroup.py b/alignak/objects/contactgroup.py index 02639dd11..ad21b7148 100644 --- a/alignak/objects/contactgroup.py +++ b/alignak/objects/contactgroup.py @@ -71,6 +71,7 @@ class Contactgroup(Itemgroup): 'uuid': StringProp(default='', fill_brok=['full_status']), 'contactgroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), + 'contactgroup_members': StringProp(fill_brok=['full_status']), }) macros = { diff --git a/alignak/objects/servicegroup.py b/alignak/objects/servicegroup.py index ae7fe42cb..1f4710177 100644 --- a/alignak/objects/servicegroup.py +++ b/alignak/objects/servicegroup.py @@ -66,13 +66,13 @@ class Servicegroup(Itemgroup): properties = Itemgroup.properties.copy() properties.update({ - 'uuid': StringProp(default='', fill_brok=['full_status']), - 'servicegroup_name': StringProp(fill_brok=['full_status']), - 'alias': StringProp(fill_brok=['full_status']), - 'notes': StringProp(default='', fill_brok=['full_status']), - 'notes_url': StringProp(default='', fill_brok=['full_status']), - 'action_url': StringProp(default='', fill_brok=['full_status']), + 'uuid': StringProp(default='', fill_brok=['full_status']), + 'servicegroup_name': StringProp(fill_brok=['full_status']), + 'alias': StringProp(fill_brok=['full_status']), 'servicegroup_members': StringProp(default='', fill_brok=['full_status']), + 'notes': StringProp(default='', fill_brok=['full_status']), + 'notes_url': StringProp(default='', fill_brok=['full_status']), + 'action_url': StringProp(default='', fill_brok=['full_status']), }) macros = { diff --git a/test/_old/etc/alignak_groups_pickle.cfg b/test/_old/etc/alignak_groups_pickle.cfg deleted file mode 100644 index f2942618d..000000000 --- a/test/_old/etc/alignak_groups_pickle.cfg +++ /dev/null @@ -1,56 +0,0 @@ - -define realm{ - realm_name World - default 1 - realm_members R1, R2 -} - - -define realm{ - realm_name R1 -} - -define realm{ - realm_name R2 -} - -define scheduler { - scheduler_name R1 - address localhost - realm R1 -} - - -define scheduler { - scheduler_name world - address localhsot - realm World -} - -define scheduler { - scheduler_name R2 - address localhsot - realm R2 -} - - -define hostgroup{ - hostgroup_name everyone - members * -} - - -define host{ - use generic-host - host_name HR1 - realm R1 - hostgroups everyone -} - - -define host{ - use generic-host - host_name HR2 - realm R2 - hostgroups everyone -} diff --git a/test/_old/test_groups_pickle.py b/test/_old/test_groups_pickle.py deleted file mode 100644 index fc5165828..000000000 --- a/test/_old/test_groups_pickle.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2010: -# Jean Gabes, naparuba@gmail.com - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestConfig(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_groups_pickle.cfg']) - - def test_dispatch(self): - - - sub_confs = self.conf.confs - print "NB SUB CONFS", len(sub_confs) - - vcfg = None - # Find where hr1 is - for cfg in sub_confs.values(): - if 'HR1' in [h.get_name() for h in cfg.hosts]: - print 'FOUNCED', len(cfg.hosts) - vcfg = cfg - - - # Look ifthe hg in the conf is valid - vhg = vcfg.hostgroups.find_by_name('everyone') - self.assert_(len(vhg.members) == 1) - - hr1 = [h for h in vcfg.hosts if h.get_name() == "HR1"][0] - print hr1.hostgroups - hg1 = None - for hg in hr1.hostgroups: - if vcfg.hostgroups[hg].get_name() == 'everyone': - hg1 = vcfg.hostgroups[hg] - - - - print "Founded hostgroup", hg1 - print 'There should be only one host there' - self.assert_(len(hg1.members) == 1) - print 'and should be the same than the vcfg one!' - self.assert_(hg1 == vhg) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/cfg/hostgroup/alignak_hostgroup_members.cfg b/test/cfg/hostgroup/alignak_hostgroup_members.cfg index ab4615fd1..ec5a906fc 100755 --- a/test/cfg/hostgroup/alignak_hostgroup_members.cfg +++ b/test/cfg/hostgroup/alignak_hostgroup_members.cfg @@ -4,5 +4,5 @@ define hostgroup { hostgroup_name allhosts_and_groups alias All Hosts and groups members test_router_0,test_host_0 - hostgroup_members router, hostgroup_01, hostgroup_02, hostgroup_03, hostgroup_04 + hostgroup_members hostgroup_01, hostgroup_02, hostgroup_03, hostgroup_04 } diff --git a/test/test_hostgroup.py b/test/test_hostgroup.py index 9d6f3536d..2cf4babf9 100755 --- a/test/test_hostgroup.py +++ b/test/test_hostgroup.py @@ -26,6 +26,7 @@ import time +from alignak.objects import Host from alignak.objects import Hostgroup from alignak_test import AlignakTest @@ -51,6 +52,8 @@ class TestHostGroupMembers(AlignakTest): def test_hostgroup_members(self): """ + Test if members are linked from group + :return: None """ self.print_header() @@ -67,9 +70,61 @@ def test_hostgroup_members(self): 2 ) - self.assertEqual(len(hg.get_hostgroup_members()), 5) + self.assertEqual(len(hg.get_hostgroup_members()), 4) + + self.assertEqual(len(hg.get_hosts()), 2) + + def test_members_hostgroup(self): + """ + Test if group is linked from the member + :return: None + """ + self.print_header() + self.setup_with_file('cfg/hostgroup/alignak_hostgroup_members.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a hostgroup named allhosts_and_groups + hg = self.schedulers[0].sched.hostgroups.find_by_name("allhosts_and_groups") + self.assertIsInstance(hg, Hostgroup) + self.assertEqual(hg.get_name(), "allhosts_and_groups") + + self.assertEqual( + len(self.schedulers[0].sched.hostgroups.get_members_by_name("allhosts_and_groups")), + 2 + ) self.assertEqual(len(hg.get_hosts()), 2) + print("List hostgroup hosts:") + for host_id in hg.members: + host = self.schedulers[0].sched.hosts[host_id] + print("Host: %s" % host) + self.assertIsInstance(host, Host) + + if host.get_name() == 'test_router_0': + self.assertEqual(len(host.get_hostgroups()), 3) + for group_id in host.hostgroups: + group = self.schedulers[0].sched.hostgroups[group_id] + print("Group: %s" % group) + self.assertIn(group.get_name(), [ + 'router', 'allhosts', 'allhosts_and_groups' + ]) + + if host.get_name() == 'test_host_0': + self.assertEqual(len(host.get_hostgroups()), 4) + for group_id in host.hostgroups: + group = self.schedulers[0].sched.hostgroups[group_id] + print("Group: %s" % group) + self.assertIn(group.get_name(), [ + 'allhosts', 'allhosts_and_groups', 'up', 'hostgroup_01' + ]) + + print("List hostgroup groups:") + self.assertEqual(len(hg.get_hostgroup_members()), 4) + for group in hg.get_hostgroup_members(): + print("Group: %s" % group) + self.assertIn(group, [ + 'hostgroup_01', 'hostgroup_02', 'hostgroup_03', 'hostgroup_04' + ]) class TestHostGroupNoHost(AlignakTest): From 037c949e1dcb29047f533f7ca60094c2940e7865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 14:14:17 +0200 Subject: [PATCH 03/16] Hostgroup members (#110) and tests refactoring (2) Remove old test testgroups_with_no_alias --- test/_old/test_groups_with_no_alias.py | 77 ------------------- .../alignak_groups_with_no_alias.cfg | 0 test/test_hostgroup.py | 16 ++++ 3 files changed, 16 insertions(+), 77 deletions(-) delete mode 100644 test/_old/test_groups_with_no_alias.py rename test/{_old/etc => cfg/hostgroup}/alignak_groups_with_no_alias.cfg (100%) diff --git a/test/_old/test_groups_with_no_alias.py b/test/_old/test_groups_with_no_alias.py deleted file mode 100644 index 6c8defb51..000000000 --- a/test/_old/test_groups_with_no_alias.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Hartmut Goebel, h.goebel@goebel-consult.de -# Grégory Starck, g.starck@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestGroupwithNoAlias(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_groups_with_no_alias.cfg']) - - def test_look_for_alias(self): - # - # Config is not correct because of a wrong relative path - # in the main config file - # - print "Get the hosts and services" - now = time.time() - hg = self.sched.hostgroups.find_by_name("NOALIAS") - self.assertIsNot(hg, None) - print hg.__dict__ - self.assertEqual("NOALIAS", hg.alias) - - sg = self.sched.servicegroups.find_by_name("NOALIAS") - self.assertIsNot(sg, None) - print sg.__dict__ - self.assertEqual("NOALIAS", sg.alias) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/_old/etc/alignak_groups_with_no_alias.cfg b/test/cfg/hostgroup/alignak_groups_with_no_alias.cfg similarity index 100% rename from test/_old/etc/alignak_groups_with_no_alias.cfg rename to test/cfg/hostgroup/alignak_groups_with_no_alias.cfg diff --git a/test/test_hostgroup.py b/test/test_hostgroup.py index 2cf4babf9..ec20bf12a 100755 --- a/test/test_hostgroup.py +++ b/test/test_hostgroup.py @@ -45,6 +45,22 @@ def test_hostgroup(self): self.setup_with_file('cfg/cfg_default.cfg') self.assertTrue(self.schedulers[0].conf.conf_is_correct) + def test_look_for_alias(self): + """ + Default configuration has no loading problems ... as of it hostgroups are parsed correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/hostgroup/alignak_groups_with_no_alias.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a hostgroup named NOALIAS + hg = self.schedulers[0].sched.hostgroups.find_by_name("NOALIAS") + self.assertIsInstance(hg, Hostgroup) + self.assertEqual(hg.get_name(), "NOALIAS") + self.assertEqual(hg.alias, "NOALIAS") + + class TestHostGroupMembers(AlignakTest): """ This class tests the hostgroups From 2166b17de84ffa3bba4083ecbb61f7f41512b0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 15:01:44 +0200 Subject: [PATCH 04/16] Make service and service group have interface similar to host / hostgroup --- alignak/objects/service.py | 8 ++++++++ alignak/objects/servicegroup.py | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/alignak/objects/service.py b/alignak/objects/service.py index b9054cfff..3bcd7e284 100644 --- a/alignak/objects/service.py +++ b/alignak/objects/service.py @@ -301,6 +301,14 @@ def get_name(self): return self.name return 'SERVICE-DESCRIPTION-MISSING' + def get_servicegroups(self): + """Accessor to servicegroups attribute + + :return: servicegroup list object of host + :rtype: list + """ + return self.servicegroups + def get_groupnames(self, sgs): """Get servicegroups list diff --git a/alignak/objects/servicegroup.py b/alignak/objects/servicegroup.py index 1f4710177..a1a121164 100644 --- a/alignak/objects/servicegroup.py +++ b/alignak/objects/servicegroup.py @@ -113,7 +113,10 @@ def get_servicegroup_members(self): """ # TODO: a Servicegroup instance should always have its servicegroup_members defined. if hasattr(self, 'servicegroup_members'): - return [m.strip() for m in self.servicegroup_members.split(',')] + sg_members = [m.strip() for m in self.servicegroup_members.split(',')] + if len(sg_members) == 1 and not sg_members[0]: + return [] + return sg_members else: return [] From 651670562113d5a64fb95fcfe40e306998bee153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 15:27:35 +0200 Subject: [PATCH 05/16] Partial commit for service groups --- AUTHORS | 235 +++++++++++++++++- alignak/objects/hostgroup.py | 25 +- alignak/objects/servicegroup.py | 19 +- .../alignak_groups_with_no_alias.cfg | 8 + .../alignak_servicegroup_members.cfg | 7 + .../alignak_servicegroup_no_service.cfg | 6 + .../alignak_servicegroup_with_space.cfg | 13 + .../alignak_servicegroup_with_void_member.cfg | 35 +++ test/test_hostgroup.py | 1 + test/test_servicegroup.py | 208 ++++++++++++++++ 10 files changed, 528 insertions(+), 29 deletions(-) create mode 100644 test/cfg/servicegroup/alignak_groups_with_no_alias.cfg create mode 100755 test/cfg/servicegroup/alignak_servicegroup_members.cfg create mode 100755 test/cfg/servicegroup/alignak_servicegroup_no_service.cfg create mode 100755 test/cfg/servicegroup/alignak_servicegroup_with_space.cfg create mode 100755 test/cfg/servicegroup/alignak_servicegroup_with_void_member.cfg create mode 100755 test/test_servicegroup.py diff --git a/AUTHORS b/AUTHORS index 912e5766b..38e0db88e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,227 @@ -Main developpers: - +5c077yP +Alexander Springer +Alexander Springer +Alexandre Boisvert +Alexandre Viau +Andreas Karfusehr +Andreas Karfusehr +Andreas Paul +Andrew McGilvray +Andrus Viik +Arthur Gautier +Arthur Gautier +Bruno Clermont +Charlie Andrews +Charlie Root +Christian Posch +Christophe SIMON +Christophe Simon +Claneys Skyne +DUVAL +DUVAL Kévin +Daniel Hokka Zakrisson +Daniel Widerin +Danijel Tasov David Durieux - - - -Contributors: - - - +David GUENAUL +David GUENAULT +David GUENAULT +David GUENAULT +David Gil +David Gil +David Laval +David Moreau Simard +David- +Davide Franco +Davide Franco +Demelziraptor +Denetariko +Denis Sacchet +Dessai.Imrane +DessaiImrane +Driskell +Durieux David +Eric Herot +FORLOT Romain +Florentin Raud +Forlot Romain +Forlot Romain +François Lafont +Fred MOHIER +Frescha +Frescha +FrogX +FrogX +Frédéric MOHIER +Frédéric MOHIER +Frédéric Pégé +Frédéric Pégé +Frédéric Pégé +Frédéric Vachon +GAULUPEAU Jonathan +GAULUPEAU Jonathan +Gabes Jean +Gabès Jean +Gabès Jean +Gerhard Lausser +Gerhard Lausser +Grégory Starck +Grégory Starck +Grégory Starck +Guillaume Bour +Guillaume Bour +H4wkmoon +H4wkmoon +Hannes Körber +Hartmut Goebel +Hartmut Goebel +Henry Bakker +Hermann.Lauer@iwr.uni-heidelberg.de +Httqm +Hubert +Jan Ulferts +Jean +Jean Gabes +Jean Remond +Jean-Charles +Jean-Claude Computing +Jean-Maxime LEBLANC +Joaquim Roy +Johan Svensson +John Hurliman +Jonathan GAULUPEAU +Konstantin Shalygin +Laurent Ollagnier +Laurent Ollagnier +Litrin Jiang +Luke L +Magnus Appelquist +Marc MAURICE +Mathias Fussenegger +Mathieu MD +Mathieu Parent +Matthieu Caneill +Michael Leinartas +Mickael FALCK +Morkxy +Naparuba +Naparuba +Nicolas Brisac +Nicolas DUPEUX +Nicolas DUPEUX +Nicolas Dupeux +Nicolas Limage +Nicolas Pichon +Olivier H +Olivier Hanesse +Olivier LI-KIANG-CHEONG +Pavel Volkovitskiy +Peter Woodman +Philippe Pepos Petitclerc +Philippe Pépos Petitclerc +Pradeep Jindal +Raphaël Doursenaud +Rich Trott +Robin Gloster +Romain Forlot +Romain LE DISEZ +Romain LE DISEZ +Romain THERRAT +Ryan Davis +Rémi SAUVAT +Samuel Milette-Lacombe +Sebastien Coavoux +Sebastien Coavoux +Sebastien Coavoux +Sebastien Coavoux +Sismic +Sispheor +Socketubs +Squiz +Steve Schnepp +Stéphane Duchesneau +Sylvain Boureau +Sébastein Coavoux +Sébastien +Sébastien +Sébastien Coavoux +Sébastien Coavoux +S�bastien Coavoux +The Gitter Badger +Thibault Cohen +Thibault Cohen +Thibautg16 +Thomas Cellerier +Thomas Meson +ThomasWaldmann +Tim Adam +Timo Veith +Valentin Brajon +Victor Igumnov +Zoran Zaric +andrewmcgilvray +anonimoose +aurelien +aviau +baoboa +brightdroid +cedef +chris81 +claneys +colourmeamused +cyrilleJ +david hannequin +david-guenault +dhannequin +fgth +fhoubart +flaf +foomip +frescha +fsoyer +gmat +h4wkmoon +hvad +itxx00 +jean-francois BUTKIEWICZ +jfbutkiewicz +jmartignago +jmcollongette +jogaulupeau +k0ste +lafont +nagios +nagios +nap +nap +naparuba +naparuba +nerocide +ning.xie +odyssey4me +olivierHa +openglx +pydubreucq +raphaeltr +rasoso +root +root +root +root +root +root +root +shinken +shinken +smilingsubnode +spil-brensen +system +system +system +t0xicCode +t0xicCode +thomascellerier +xkilian +yam +yol +yol diff --git a/alignak/objects/hostgroup.py b/alignak/objects/hostgroup.py index c59dcf86d..ec7a15fa1 100644 --- a/alignak/objects/hostgroup.py +++ b/alignak/objects/hostgroup.py @@ -57,7 +57,7 @@ from alignak.objects.itemgroup import Itemgroup, Itemgroups from alignak.util import get_obj_name -from alignak.property import StringProp +from alignak.property import StringProp, ListProp from alignak.log import logger @@ -73,7 +73,9 @@ class Hostgroup(Itemgroup): 'uuid': StringProp(default='', fill_brok=['full_status']), 'hostgroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), - 'hostgroup_members': StringProp(fill_brok=['full_status']), + 'test': StringProp(fill_brok=['full_status']), + 'hostgroup_members': ListProp(default=[], fill_brok=['full_status'], + merging='join', split_on_coma=True), 'notes': StringProp(default='', fill_brok=['full_status']), 'notes_url': StringProp(default='', fill_brok=['full_status']), 'action_url': StringProp(default='', fill_brok=['full_status']), @@ -117,15 +119,16 @@ def get_hostgroup_members(self): :return: list of hosts :rtype: list """ - # TODO: consistency : a Hostgroup instance should always - # have its hostgroup_members attribute defined, even if the empty list - if hasattr(self, 'hostgroup_members'): - # consistency: any Hostgroup instance's hostgroup_members attribute - # should already be decoded/parsed: - # this should already be in its list form. - return [m.strip() for m in self.hostgroup_members.split(',')] - else: - return [] + # # TODO: consistency : a Hostgroup instance should always + # # have its hostgroup_members attribute defined, even if the empty list + # if hasattr(self, 'hostgroup_members'): + # # consistency: any Hostgroup instance's hostgroup_members attribute + # # should already be decoded/parsed: + # # this should already be in its list form. + # return [m.strip() for m in self.hostgroup_members.split(',')] + # else: + # return [] + return self.hostgroup_members def get_hosts_by_explosion(self, hostgroups): """ diff --git a/alignak/objects/servicegroup.py b/alignak/objects/servicegroup.py index a1a121164..463edf70f 100644 --- a/alignak/objects/servicegroup.py +++ b/alignak/objects/servicegroup.py @@ -69,7 +69,7 @@ class Servicegroup(Itemgroup): 'uuid': StringProp(default='', fill_brok=['full_status']), 'servicegroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), - 'servicegroup_members': StringProp(default='', fill_brok=['full_status']), + 'servicegroup_members': StringProp(fill_brok=['full_status']), 'notes': StringProp(default='', fill_brok=['full_status']), 'notes_url': StringProp(default='', fill_brok=['full_status']), 'action_url': StringProp(default='', fill_brok=['full_status']), @@ -111,14 +111,15 @@ def get_servicegroup_members(self): :return: list of services (members) :rtype: list | str """ - # TODO: a Servicegroup instance should always have its servicegroup_members defined. - if hasattr(self, 'servicegroup_members'): - sg_members = [m.strip() for m in self.servicegroup_members.split(',')] - if len(sg_members) == 1 and not sg_members[0]: - return [] - return sg_members - else: - return [] + # # TODO: a Servicegroup instance should always have its servicegroup_members defined. + # if hasattr(self, 'servicegroup_members'): + # sg_members = [m.strip() for m in self.servicegroup_members.split(',')] + # if len(sg_members) == 1 and not sg_members[0]: + # return [] + # return sg_members + # else: + # return [] + return self.servicegroup_members def get_services_by_explosion(self, servicegroups): """ diff --git a/test/cfg/servicegroup/alignak_groups_with_no_alias.cfg b/test/cfg/servicegroup/alignak_groups_with_no_alias.cfg new file mode 100644 index 000000000..e6e4967d8 --- /dev/null +++ b/test/cfg/servicegroup/alignak_groups_with_no_alias.cfg @@ -0,0 +1,8 @@ + +define servicegroup { + servicegroup_name NOALIAS +} + +define hostgroup { + hostgroup_name NOALIAS +} diff --git a/test/cfg/servicegroup/alignak_servicegroup_members.cfg b/test/cfg/servicegroup/alignak_servicegroup_members.cfg new file mode 100755 index 000000000..045e711a4 --- /dev/null +++ b/test/cfg/servicegroup/alignak_servicegroup_members.cfg @@ -0,0 +1,7 @@ +cfg_dir=../default + +define servicegroup { + servicegroup_name allservices_and_groups + members test_host_0,test_ok_0 +; servicegroup_members servicegroup_01, servicegroup_02, servicegroup_03, servicegroup_04 +} diff --git a/test/cfg/servicegroup/alignak_servicegroup_no_service.cfg b/test/cfg/servicegroup/alignak_servicegroup_no_service.cfg new file mode 100755 index 000000000..c6f74111e --- /dev/null +++ b/test/cfg/servicegroup/alignak_servicegroup_no_service.cfg @@ -0,0 +1,6 @@ +cfg_dir=../default + +define servicegroup { + servicegroup_name void + alias Void group +} diff --git a/test/cfg/servicegroup/alignak_servicegroup_with_space.cfg b/test/cfg/servicegroup/alignak_servicegroup_with_space.cfg new file mode 100755 index 000000000..3108b200d --- /dev/null +++ b/test/cfg/servicegroup/alignak_servicegroup_with_space.cfg @@ -0,0 +1,13 @@ +cfg_dir=../default + +define servicegroup { + servicegroup_name test_With Spaces + members test_host_0,test_ok_0 +} + + +define servicegroup { + servicegroup_name test_With another Spaces + members test_host_0,test_ok_0 +} + diff --git a/test/cfg/servicegroup/alignak_servicegroup_with_void_member.cfg b/test/cfg/servicegroup/alignak_servicegroup_with_void_member.cfg new file mode 100755 index 000000000..24a594d9f --- /dev/null +++ b/test/cfg/servicegroup/alignak_servicegroup_with_void_member.cfg @@ -0,0 +1,35 @@ +cfg_dir=../default + +define hostgroup{ + hostgroup_name MYGROUP + members h1,h2, +} + + +define host{ + host_name h1 + use generic-host +} + +define host{ + host_name h2 + use generic-host +} + + + +define contactgroup{ + contactgroup_name SPACEMARINES + members m1 , m2 , +} + + +define contact{ + contact_name m1 + use generic-contact +} + +define contact{ + contact_name m2 + use generic-contact +} \ No newline at end of file diff --git a/test/test_hostgroup.py b/test/test_hostgroup.py index ec20bf12a..67a8b588d 100755 --- a/test/test_hostgroup.py +++ b/test/test_hostgroup.py @@ -86,6 +86,7 @@ def test_hostgroup_members(self): 2 ) + self.assertEqual(len(hg.hostgroup_members), 4) self.assertEqual(len(hg.get_hostgroup_members()), 4) self.assertEqual(len(hg.get_hosts()), 2) diff --git a/test/test_servicegroup.py b/test/test_servicegroup.py new file mode 100755 index 000000000..95ec6931e --- /dev/null +++ b/test/test_servicegroup.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors +# +# This file is part of Alignak. +# +# Alignak is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alignak is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Alignak. If not, see . +# +# + +""" +This file test all cases of eventhandler +""" + +import time + +from alignak.objects import Service +from alignak.objects import Servicegroup +from alignak_test import AlignakTest + + +class TestServiceGroup(AlignakTest): + """ + This class tests the servicegroups + """ + + def test_servicegroup(self): + """ + Default configuration has no loading problems ... as of it servicegroups are parsed + correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + def test_look_for_alias(self): + """ + Default configuration has no loading problems ... as of it servicegroups are parsed correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/servicegroup/alignak_groups_with_no_alias.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a servicegroup named NOALIAS + sg = self.schedulers[0].sched.servicegroups.find_by_name("NOALIAS") + self.assertIsInstance(sg, Servicegroup) + self.assertEqual(sg.get_name(), "NOALIAS") + self.assertEqual(sg.alias, "NOALIAS") + + +class TestServiceGroupMembers(AlignakTest): + """ + This class tests the servicegroups + """ + + def test_servicegroup_members(self): + """ + Test if members are linked from group + + :return: None + """ + self.print_header() + self.setup_with_file('cfg/servicegroup/alignak_servicegroup_members.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a servicegroup named allhosts_and_groups + sg = self.schedulers[0].sched.servicegroups.find_by_name("allhosts_and_groups") + self.assertIsInstance(sg, Servicegroup) + self.assertEqual(sg.get_name(), "allhosts_and_groups") + + self.assertEqual( + len(self.schedulers[0].sched.servicegroups.get_members_by_name("allhosts_and_groups")), + 2 + ) + + self.assertEqual(len(sg.get_servicegroup_members()), 4) + + self.assertEqual(len(sg.get_hosts()), 2) + + def test_members_servicegroup(self): + """ + Test if group is linked from the member + :return: None + """ + self.print_header() + self.setup_with_file('cfg/servicegroup/alignak_servicegroup_members.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a servicegroup named allhosts_and_groups + sg = self.schedulers[0].sched.servicegroups.find_by_name("allservices_and_groups") + self.assertIsInstance(sg, Servicegroup) + self.assertEqual(sg.get_name(), "allservices_and_groups") + + self.assertEqual( + len(self.schedulers[0].sched.servicegroups.get_members_by_name( + "allservices_and_groups" + )), + 1 + ) + + self.assertEqual(len(sg.get_services()), 1) + print("List servicegroup services:") + for service_id in sg.members: + service = self.schedulers[0].sched.services[service_id] + print("Service: %s" % service) + self.assertIsInstance(service, Service) + + if service.get_name() == 'test_ok_0': + self.assertEqual(len(service.get_servicegroups()), 4) + for group_id in service.servicegroups: + group = self.schedulers[0].sched.servicegroups[group_id] + print("Group: %s" % group) + self.assertIn(group.get_name(), [ + 'ok', 'servicegroup_01', 'servicegroup_02', 'allservices_and_groups' + ]) + + print("List servicegroup groups:") + self.assertEqual(len(sg.get_servicegroup_members()), 4) + for group in sg.get_servicegroup_members(): + print("Group: %s" % group) + self.assertIn(group, [ + 'servicegroup_01', 'servicegroup_02', 'servicegroup_03', 'servicegroup_04' + ]) + + +class TestServiceGroupNoHost(AlignakTest): + + def test_servicegroup_with_no_service(self): + """ + Allow servicegroups with no hosts + :return: None + """ + self.print_header() + self.setup_with_file('cfg/servicegroup/alignak_servicegroup_no_service.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + # Found a servicegroup named void + sg = self.schedulers[0].sched.servicegroups.find_by_name("void") + self.assertIsInstance(sg, Servicegroup) + self.assertEqual(sg.get_name(), "void") + + self.assertEqual( + len(self.schedulers[0].sched.servicegroups.get_members_by_name("void")), + 0 + ) + + print("Services: %s" % sg.get_servicegroup_members()) + self.assertEqual(len(sg.get_servicegroup_members()), 0) + + print("Services: %s" % sg.get_services()) + self.assertEqual(len(sg.get_services()), 0) + + +class TestServiceGroupWithSpace(AlignakTest): + + def test_servicegroup_with_space(self): + """ + Test that servicegroups can have a name with spaces + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + self.nb_servicegroups = len(self.schedulers[0].sched.servicegroups) + + self.setup_with_file('cfg/servicegroup/alignak_servicegroup_with_space.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + # Two more groups than the default configuration + self.assertEqual( + len(self.schedulers[0].sched.servicegroups), self.nb_servicegroups + 2 + ) + + self.assertEqual( + self.schedulers[0].sched.servicegroups.find_by_name("test_With Spaces").get_name(), + "test_With Spaces" + ) + self.assertIsNot( + self.schedulers[0].sched.servicegroups.get_members_by_name( + "test_With Spaces" + ), + [] + ) + + self.assertEqual( + self.schedulers[0].sched.servicegroups.find_by_name("test_With another Spaces").get_name(), + "test_With another Spaces" + ) + self.assertIsNot( + self.schedulers[0].sched.servicegroups.get_members_by_name( + "test_With another Spaces" + ), + [] + ) From 67115bfbf199d1250d2c38232b89dae67202f1bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 15:41:48 +0200 Subject: [PATCH 06/16] Partial commit for service groups share for testing --- alignak/objects/hostgroup.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/alignak/objects/hostgroup.py b/alignak/objects/hostgroup.py index ec7a15fa1..a2aca05af 100644 --- a/alignak/objects/hostgroup.py +++ b/alignak/objects/hostgroup.py @@ -74,7 +74,7 @@ class Hostgroup(Itemgroup): 'hostgroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), 'test': StringProp(fill_brok=['full_status']), - 'hostgroup_members': ListProp(default=[], fill_brok=['full_status'], + 'hostgroup_members': ListProp(default=['a'], fill_brok=['full_status'], merging='join', split_on_coma=True), 'notes': StringProp(default='', fill_brok=['full_status']), 'notes_url': StringProp(default='', fill_brok=['full_status']), @@ -121,13 +121,16 @@ def get_hostgroup_members(self): """ # # TODO: consistency : a Hostgroup instance should always # # have its hostgroup_members attribute defined, even if the empty list - # if hasattr(self, 'hostgroup_members'): - # # consistency: any Hostgroup instance's hostgroup_members attribute - # # should already be decoded/parsed: - # # this should already be in its list form. - # return [m.strip() for m in self.hostgroup_members.split(',')] - # else: - # return [] + if hasattr(self, 'hostgroup_members'): + return self.hostgroup_members + # consistency: any Hostgroup instance's hostgroup_members attribute + # should already be decoded/parsed: + # this should already be in its list form. + return [m.strip() for m in self.hostgroup_members.split(',')] + else: + return [] + if not hasattr(self, 'hostgroup_members'): + return [] return self.hostgroup_members def get_hosts_by_explosion(self, hostgroups): From 7b2d16389690a30a68a019d97e369f880cf8adc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 15:56:52 +0200 Subject: [PATCH 07/16] All hostgroup tests in one test class --- test/test_hostgroup.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/test_hostgroup.py b/test/test_hostgroup.py index 67a8b588d..9b8fd2de1 100755 --- a/test/test_hostgroup.py +++ b/test/test_hostgroup.py @@ -60,12 +60,6 @@ def test_look_for_alias(self): self.assertEqual(hg.get_name(), "NOALIAS") self.assertEqual(hg.alias, "NOALIAS") - -class TestHostGroupMembers(AlignakTest): - """ - This class tests the hostgroups - """ - def test_hostgroup_members(self): """ Test if members are linked from group @@ -143,9 +137,6 @@ def test_members_hostgroup(self): 'hostgroup_01', 'hostgroup_02', 'hostgroup_03', 'hostgroup_04' ]) - -class TestHostGroupNoHost(AlignakTest): - def test_hostgroup_with_no_host(self): """ Allow hostgroups with no hosts @@ -169,9 +160,6 @@ def test_hostgroup_with_no_host(self): self.assertEqual(len(hg.get_hosts()), 0) - -class TestHostGroupWithSpace(AlignakTest): - def test_hostgroup_with_space(self): """ Test that hostgroups can have a name with spaces From 9da76c68d71733613a784dceccf9dc336fb77c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 19:02:00 +0200 Subject: [PATCH 08/16] Refactor test for service groups --- alignak/objects/itemgroup.py | 5 +- alignak/objects/servicegroup.py | 35 ++++---- .../etc/alignak_servicegroups_generated.cfg | 55 ------------- test/_old/test_servicegroups.py | 80 ------------------- .../alignak_servicegroup_members.cfg | 2 +- .../alignak_servicegroups_generated.cfg | 57 +++++++++++++ test/test_hostgroup.py | 2 +- test/test_servicegroup.py | 58 +++++++++----- 8 files changed, 119 insertions(+), 175 deletions(-) delete mode 100644 test/_old/etc/alignak_servicegroups_generated.cfg delete mode 100644 test/_old/test_servicegroups.py create mode 100644 test/cfg/servicegroup/alignak_servicegroups_generated.cfg diff --git a/alignak/objects/itemgroup.py b/alignak/objects/itemgroup.py index ccf8aaba5..4c5d4162a 100644 --- a/alignak/objects/itemgroup.py +++ b/alignak/objects/itemgroup.py @@ -129,6 +129,9 @@ def add_string_member(self, member): :type member: str :return: None """ + # Avoid empty elements in lists ... + if not member: + return add_fun = list.extend if isinstance(member, list) else list.append if not hasattr(self, "members"): self.members = [] @@ -168,7 +171,7 @@ def is_correct(self): if self.unknown_members: for member in self.unknown_members: - logger.error("[itemgroup::%s] as %s, got unknown member %s", + logger.error("[itemgroup::%s] as %s, got unknown member '%s'", self.get_name(), self.__class__.my_type, member) res = False diff --git a/alignak/objects/servicegroup.py b/alignak/objects/servicegroup.py index 463edf70f..598bfa5d7 100644 --- a/alignak/objects/servicegroup.py +++ b/alignak/objects/servicegroup.py @@ -51,7 +51,7 @@ This module provide Servicegroup and Servicegroups classes used to group services """ -from alignak.property import StringProp +from alignak.property import StringProp, ListProp from alignak.log import logger from .itemgroup import Itemgroup, Itemgroups @@ -69,7 +69,8 @@ class Servicegroup(Itemgroup): 'uuid': StringProp(default='', fill_brok=['full_status']), 'servicegroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), - 'servicegroup_members': StringProp(fill_brok=['full_status']), + 'servicegroup_members': ListProp(default=[], fill_brok=['full_status'], + merging='join', split_on_coma=True), 'notes': StringProp(default='', fill_brok=['full_status']), 'notes_url': StringProp(default='', fill_brok=['full_status']), 'action_url': StringProp(default='', fill_brok=['full_status']), @@ -106,20 +107,16 @@ def get_name(self): def get_servicegroup_members(self): """ - Get list of members of this servicegroup + Get list of groups members of this servicegroup - :return: list of services (members) + :return: list of services :rtype: list | str """ - # # TODO: a Servicegroup instance should always have its servicegroup_members defined. - # if hasattr(self, 'servicegroup_members'): - # sg_members = [m.strip() for m in self.servicegroup_members.split(',')] - # if len(sg_members) == 1 and not sg_members[0]: - # return [] - # return sg_members - # else: - # return [] - return self.servicegroup_members + if hasattr(self, 'servicegroup_members'): + print("SG groups members: " % self.servicegroup_members) + return self.servicegroup_members + else: + return [] def get_services_by_explosion(self, servicegroups): """ @@ -154,6 +151,7 @@ def get_services_by_explosion(self, servicegroups): if servicegroup is not None: value = servicegroup.get_services_by_explosion(servicegroups) if value is not None: + print("SG string member: %s" % value) self.add_string_member(value) if hasattr(self, 'members'): @@ -258,22 +256,23 @@ def explode(self): :return: None """ - # We do not want a same hg to be explode again and again + # We do not want a same service group to be exploded again and again # so we tag it - for servicegroup in self: + for servicegroup in self.items.values(): servicegroup.already_explode = False - for servicegroup in self: + for servicegroup in self.items.values(): + print("SG: %s" % servicegroup) if hasattr(servicegroup, 'servicegroup_members') and not \ servicegroup.already_explode: # get_services_by_explosion is a recursive # function, so we must tag hg so we do not loop - for sg2 in self: + for sg2 in self.items.values(): sg2.rec_tag = False servicegroup.get_services_by_explosion(self) # We clean the tags - for servicegroup in self: + for servicegroup in self.items.values(): try: del servicegroup.rec_tag except AttributeError: diff --git a/test/_old/etc/alignak_servicegroups_generated.cfg b/test/_old/etc/alignak_servicegroups_generated.cfg deleted file mode 100644 index 0dceef483..000000000 --- a/test/_old/etc/alignak_servicegroups_generated.cfg +++ /dev/null @@ -1,55 +0,0 @@ -define host { - host_name fake host - alias fake host - address 192.168.50.43 - business_impact 4 - icon_image_alt Linux - icon_image base/linux40.gif - statusmap_image base/linux40.gd2 - check_command _echo - check_period 24x7 - notification_period 24x7 - #use Template_Host_Generic - use generic-host - contact_groups - check_interval 1555 - retry_interval 1555 -} - -define service{ - host_name fake host - service_description fake svc1 - use generic-service - check_command _echo - check_interval 5 - retry_interval 5 -} - -define service{ - host_name fake host - service_description fake svc2 - use generic-service - check_command _echo - check_interval 5 - retry_interval 5 -} - -define service{ - host_name fake host - service_description fake svc3 - use generic-service - check_command _echo - servicegroups MYSVCGP, MYSVCGP2 - check_interval 5 - retry_interval 5 -} - -define service{ - host_name fake host - service_description fake svc4 - use generic-service - check_command _echo - servicegroups MYSVCGP3,MYSVCGP4 - check_interval 5 - retry_interval 5 -} diff --git a/test/_old/test_servicegroups.py b/test/_old/test_servicegroups.py deleted file mode 100644 index c0cacd4d0..000000000 --- a/test/_old/test_servicegroups.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Grégory Starck, g.starck@gmail.com -# Jean Gabes, naparuba@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -import copy -from alignak_test import * - - -class TestServicegroup(AlignakTest): - def setUp(self): - self.setup_with_file(["etc/alignak_servicegroups_generated.cfg"]) - - - def test_servicegroup(self): - self.assertEqual(True, self.conf.conf_is_correct) - sgs = [] - for name in ["MYSVCGP", "MYSVCGP2", "MYSVCGP3", "MYSVCGP4"]: - sg = self.sched.servicegroups.find_by_name(name) - sgs.append(sg) - self.assertIsNot(sg, None) - - svc3 = self.sched.services.find_srv_by_name_and_hostname("fake host", "fake svc3") - svc4 = self.sched.services.find_srv_by_name_and_hostname("fake host", "fake svc4") - self.assertIn(svc3.uuid, sgs[0].members) - self.assertIn(svc3.uuid, sgs[1].members) - self.assertIn(svc4.uuid, sgs[2].members) - self.assertIn(svc4.uuid, sgs[3].members) - - self.assertIn(sgs[0].uuid, svc3.servicegroups) - self.assertIn(sgs[1].uuid, svc3.servicegroups) - self.assertIn(sgs[2].uuid, svc4.servicegroups) - self.assertIn(sgs[3].uuid, svc4.servicegroups) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/cfg/servicegroup/alignak_servicegroup_members.cfg b/test/cfg/servicegroup/alignak_servicegroup_members.cfg index 045e711a4..cdde2a4e6 100755 --- a/test/cfg/servicegroup/alignak_servicegroup_members.cfg +++ b/test/cfg/servicegroup/alignak_servicegroup_members.cfg @@ -3,5 +3,5 @@ cfg_dir=../default define servicegroup { servicegroup_name allservices_and_groups members test_host_0,test_ok_0 -; servicegroup_members servicegroup_01, servicegroup_02, servicegroup_03, servicegroup_04 + servicegroup_members servicegroup_01, servicegroup_02, servicegroup_03, servicegroup_04 } diff --git a/test/cfg/servicegroup/alignak_servicegroups_generated.cfg b/test/cfg/servicegroup/alignak_servicegroups_generated.cfg new file mode 100644 index 000000000..f85e754b5 --- /dev/null +++ b/test/cfg/servicegroup/alignak_servicegroups_generated.cfg @@ -0,0 +1,57 @@ +cfg_dir=../default + +define host { + host_name fake host + alias fake host + address 192.168.50.43 + business_impact 4 + icon_image_alt Linux + icon_image base/linux40.gif + statusmap_image base/linux40.gd2 + check_command _echo + check_period 24x7 + notification_period 24x7 + #use Template_Host_Generic + use generic-host + contact_groups + check_interval 1555 + retry_interval 1555 +} + +define service{ + host_name fake host + service_description fake svc1 + use generic-service + check_command _echo + check_interval 5 + retry_interval 5 +} + +define service{ + host_name fake host + service_description fake svc2 + use generic-service + check_command _echo + check_interval 5 + retry_interval 5 +} + +define service{ + host_name fake host + service_description fake svc3 + use generic-service + check_command _echo + servicegroups MYSVCGP, MYSVCGP2 + check_interval 5 + retry_interval 5 +} + +define service{ + host_name fake host + service_description fake svc4 + use generic-service + check_command _echo + servicegroups MYSVCGP3,MYSVCGP4 + check_interval 5 + retry_interval 5 +} diff --git a/test/test_hostgroup.py b/test/test_hostgroup.py index 9b8fd2de1..786f91ad8 100755 --- a/test/test_hostgroup.py +++ b/test/test_hostgroup.py @@ -129,8 +129,8 @@ def test_members_hostgroup(self): 'allhosts', 'allhosts_and_groups', 'up', 'hostgroup_01' ]) - print("List hostgroup groups:") self.assertEqual(len(hg.get_hostgroup_members()), 4) + print("List hostgroup groups:") for group in hg.get_hostgroup_members(): print("Group: %s" % group) self.assertIn(group, [ diff --git a/test/test_servicegroup.py b/test/test_servicegroup.py index 95ec6931e..be1126efa 100755 --- a/test/test_servicegroup.py +++ b/test/test_servicegroup.py @@ -61,12 +61,6 @@ def test_look_for_alias(self): self.assertEqual(sg.get_name(), "NOALIAS") self.assertEqual(sg.alias, "NOALIAS") - -class TestServiceGroupMembers(AlignakTest): - """ - This class tests the servicegroups - """ - def test_servicegroup_members(self): """ Test if members are linked from group @@ -78,18 +72,18 @@ def test_servicegroup_members(self): self.assertTrue(self.schedulers[0].conf.conf_is_correct) #  Found a servicegroup named allhosts_and_groups - sg = self.schedulers[0].sched.servicegroups.find_by_name("allhosts_and_groups") + sg = self.schedulers[0].sched.servicegroups.find_by_name("allservices_and_groups") self.assertIsInstance(sg, Servicegroup) - self.assertEqual(sg.get_name(), "allhosts_and_groups") + self.assertEqual(sg.get_name(), "allservices_and_groups") self.assertEqual( - len(self.schedulers[0].sched.servicegroups.get_members_by_name("allhosts_and_groups")), - 2 + len(self.schedulers[0].sched.servicegroups.get_members_by_name("allservices_and_groups")), + 1 ) - self.assertEqual(len(sg.get_servicegroup_members()), 4) + self.assertEqual(len(sg.get_services()), 1) - self.assertEqual(len(sg.get_hosts()), 2) + self.assertEqual(len(sg.get_servicegroup_members()), 4) def test_members_servicegroup(self): """ @@ -128,17 +122,14 @@ def test_members_servicegroup(self): 'ok', 'servicegroup_01', 'servicegroup_02', 'allservices_and_groups' ]) - print("List servicegroup groups:") self.assertEqual(len(sg.get_servicegroup_members()), 4) + print("List servicegroup groups:") for group in sg.get_servicegroup_members(): print("Group: %s" % group) self.assertIn(group, [ 'servicegroup_01', 'servicegroup_02', 'servicegroup_03', 'servicegroup_04' ]) - -class TestServiceGroupNoHost(AlignakTest): - def test_servicegroup_with_no_service(self): """ Allow servicegroups with no hosts @@ -164,9 +155,6 @@ def test_servicegroup_with_no_service(self): print("Services: %s" % sg.get_services()) self.assertEqual(len(sg.get_services()), 0) - -class TestServiceGroupWithSpace(AlignakTest): - def test_servicegroup_with_space(self): """ Test that servicegroups can have a name with spaces @@ -206,3 +194,35 @@ def test_servicegroup_with_space(self): ), [] ) + + def test_servicegroups_generated(self): + """ + Test that servicegroups can have a name with spaces + :return: None + """ + self.print_header() + self.setup_with_file('cfg/servicegroup/alignak_servicegroups_generated.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + self.nb_servicegroups = len(self.schedulers[0].sched.servicegroups) + + sgs = [] + for name in ["MYSVCGP", "MYSVCGP2", "MYSVCGP3", "MYSVCGP4"]: + sg = self.schedulers[0].sched.servicegroups.find_by_name(name) + self.assertIsNot(sg, None) + sgs.append(sg) + + svc3 = self.schedulers[0].sched.services.find_srv_by_name_and_hostname("fake host", "fake svc3") + svc4 = self.schedulers[0].sched.services.find_srv_by_name_and_hostname("fake host", "fake svc4") + self.assertIn(svc3.uuid, sgs[0].members) + self.assertIn(svc3.uuid, sgs[1].members) + self.assertIn(svc4.uuid, sgs[2].members) + self.assertIn(svc4.uuid, sgs[3].members) + + self.assertIn(sgs[0].uuid, svc3.servicegroups) + self.assertIn(sgs[1].uuid, svc3.servicegroups) + self.assertIn(sgs[2].uuid, svc4.servicegroups) + self.assertIn(sgs[3].uuid, svc4.servicegroups) + + +if __name__ == '__main__': + unittest.main() From d57303930fb7c1e920d87e7a54bc1476cb720ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 19:02:28 +0200 Subject: [PATCH 09/16] Clean hostgroups tests --- alignak/objects/hostgroup.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/alignak/objects/hostgroup.py b/alignak/objects/hostgroup.py index a2aca05af..2cb3c0fde 100644 --- a/alignak/objects/hostgroup.py +++ b/alignak/objects/hostgroup.py @@ -74,7 +74,7 @@ class Hostgroup(Itemgroup): 'hostgroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), 'test': StringProp(fill_brok=['full_status']), - 'hostgroup_members': ListProp(default=['a'], fill_brok=['full_status'], + 'hostgroup_members': ListProp(default=[], fill_brok=['full_status'], merging='join', split_on_coma=True), 'notes': StringProp(default='', fill_brok=['full_status']), 'notes_url': StringProp(default='', fill_brok=['full_status']), @@ -114,24 +114,15 @@ def get_hosts(self): def get_hostgroup_members(self): """ - Get hostgroup members + Get list of groups members of this hostgroup :return: list of hosts :rtype: list """ - # # TODO: consistency : a Hostgroup instance should always - # # have its hostgroup_members attribute defined, even if the empty list if hasattr(self, 'hostgroup_members'): return self.hostgroup_members - # consistency: any Hostgroup instance's hostgroup_members attribute - # should already be decoded/parsed: - # this should already be in its list form. - return [m.strip() for m in self.hostgroup_members.split(',')] else: return [] - if not hasattr(self, 'hostgroup_members'): - return [] - return self.hostgroup_members def get_hosts_by_explosion(self, hostgroups): """ @@ -310,10 +301,11 @@ def explode(self): :return: None """ - # We do not want a same hg to be explode again and again + # We do not want a same hostgroup to be exploded again and again # so we tag it for tmp_hg in self.items.values(): tmp_hg.already_explode = False + for hostgroup in self.items.values(): if hasattr(hostgroup, 'hostgroup_members') and not \ hostgroup.already_explode: From 251fe69c004ba160ce1927212f90b9dc94063436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 19:16:05 +0200 Subject: [PATCH 10/16] Remove forgotten debug print --- alignak/objects/servicegroup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/alignak/objects/servicegroup.py b/alignak/objects/servicegroup.py index 598bfa5d7..e8d56db8b 100644 --- a/alignak/objects/servicegroup.py +++ b/alignak/objects/servicegroup.py @@ -262,7 +262,6 @@ def explode(self): servicegroup.already_explode = False for servicegroup in self.items.values(): - print("SG: %s" % servicegroup) if hasattr(servicegroup, 'servicegroup_members') and not \ servicegroup.already_explode: # get_services_by_explosion is a recursive From 03be436098d2e23229936a61affb7a64a0b6da13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 20:21:03 +0200 Subject: [PATCH 11/16] Improve contactgroup tests --- alignak/objects/contactgroup.py | 16 +- .../etc/alignak_contactgroup_nomembers.cfg | 11 - test/_old/test_contactgroup_nomembers.py | 69 ---- .../test_contactgroups_plus_inheritance.py | 120 ------- .../alignak_contactgroup_members.cfg | 22 ++ .../alignak_contactgroup_no_contact.cfg | 6 + .../alignak_contactgroup_with_space.cfg | 6 + .../alignak_contactgroup_with_void_member.cfg | 35 ++ ...alignak_contactgroups_plus_inheritance.cfg | 2 + .../alignak_groups_with_no_alias.cfg | 4 + test/test_contactgroup.py | 312 ++++++++++++++++++ 11 files changed, 393 insertions(+), 210 deletions(-) delete mode 100644 test/_old/etc/alignak_contactgroup_nomembers.cfg delete mode 100644 test/_old/test_contactgroup_nomembers.py delete mode 100644 test/_old/test_contactgroups_plus_inheritance.py create mode 100755 test/cfg/contactgroup/alignak_contactgroup_members.cfg create mode 100755 test/cfg/contactgroup/alignak_contactgroup_no_contact.cfg create mode 100755 test/cfg/contactgroup/alignak_contactgroup_with_space.cfg create mode 100755 test/cfg/contactgroup/alignak_contactgroup_with_void_member.cfg rename test/{_old/etc => cfg/contactgroup}/alignak_contactgroups_plus_inheritance.cfg (99%) create mode 100755 test/cfg/contactgroup/alignak_groups_with_no_alias.cfg create mode 100755 test/test_contactgroup.py diff --git a/alignak/objects/contactgroup.py b/alignak/objects/contactgroup.py index ad21b7148..734e052dc 100644 --- a/alignak/objects/contactgroup.py +++ b/alignak/objects/contactgroup.py @@ -56,7 +56,7 @@ """ from alignak.objects.itemgroup import Itemgroup, Itemgroups -from alignak.property import StringProp +from alignak.property import StringProp, ListProp from alignak.log import logger @@ -71,7 +71,8 @@ class Contactgroup(Itemgroup): 'uuid': StringProp(default='', fill_brok=['full_status']), 'contactgroup_name': StringProp(fill_brok=['full_status']), 'alias': StringProp(fill_brok=['full_status']), - 'contactgroup_members': StringProp(fill_brok=['full_status']), + 'contactgroup_members': ListProp(default=[], fill_brok=['full_status'], + merging='join', split_on_coma=True) }) macros = { @@ -102,18 +103,13 @@ def get_name(self): def get_contactgroup_members(self): """ - Get contactgroup members + Get list of groups members of this contactgroup - :return: list of hosts + :return: list of contacts :rtype: list """ - # TODO: imho a Contactgroup instance should always have defined - # its contactgroup_members attribute, even if it's empty / the empty list. if hasattr(self, 'contactgroup_members'): - # more over: it should already be in the list form, - # not anymore in the "bare" string from as read - # from configuration (files or db or whatever) - return [m.strip() for m in self.contactgroup_members.split(',')] + return self.contactgroup_members else: return [] diff --git a/test/_old/etc/alignak_contactgroup_nomembers.cfg b/test/_old/etc/alignak_contactgroup_nomembers.cfg deleted file mode 100644 index 13309f180..000000000 --- a/test/_old/etc/alignak_contactgroup_nomembers.cfg +++ /dev/null @@ -1,11 +0,0 @@ -define contactgroup{ - contactgroup_name test_contact_nomember - alias test_contacts_alias_nomember -} - -define host{ - contact_groups test_contact,test_contact_nomember - name generic-host_nomember - register 0 - -} diff --git a/test/_old/test_contactgroup_nomembers.py b/test/_old/test_contactgroup_nomembers.py deleted file mode 100644 index b0b55666e..000000000 --- a/test/_old/test_contactgroup_nomembers.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Hartmut Goebel, h.goebel@goebel-consult.de -# Grégory Starck, g.starck@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestContactgroupWitoutMembers(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_contactgroup_nomembers.cfg']) - - # It seems that a contact group with no member cause some crash for the arbiter. - # should fix it :) - def test_contactgroup_nomember(self): - # Look for the members of the test_contact_nomember - cg = self.sched.conf.contactgroups.find_by_name('test_contact_nomember') - self.assertIsNot(cg, None) - print cg.members - self.assertEqual([], cg.members) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/_old/test_contactgroups_plus_inheritance.py b/test/_old/test_contactgroups_plus_inheritance.py deleted file mode 100644 index 984fef0af..000000000 --- a/test/_old/test_contactgroups_plus_inheritance.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Olivier Hanesse, olivier.hanesse@gmail.com -# Grégory Starck, g.starck@gmail.com -# Hartmut Goebel, h.goebel@goebel-consult.de -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test attribute inheritance and the right order -# - -from alignak_test import * - - -class TestPlusInInheritance(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_contactgroups_plus_inheritance.cfg']) - - def _dump(self, h): - print "Dumping host", h.get_name() - print h.contact_groups - for c in h.contacts: - print "->", self.sched.contacts[c].get_name() - - def _dump_svc(self,s): - print "Dumping Service", s.get_name() - print " contact_groups : %s " % s.contact_groups - for c in s.contacts: - print "->", self.sched.contacts[c].get_name() - - def test_contactgroups_plus_inheritance(self): - host0 = self.sched.hosts.find_by_name("test_host_0") - # HOST 1 should have 2 group of contacts - # WARNING, it's a string, not the real objects! - self._dump(host0) - - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in host0.contacts]) - self.assertIn("test_contact_2", [self.sched.contacts[c].get_name() for c in host0.contacts]) - - host2 = self.sched.hosts.find_by_name("test_host_2") - self._dump(host2) - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in host2.contacts]) - - host3 = self.sched.hosts.find_by_name("test_host_3") - self._dump(host3) - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in host3.contacts]) - self.assertIn("test_contact_2", [self.sched.contacts[c].get_name() for c in host3.contacts]) - - host4 = self.sched.hosts.find_by_name("test_host_4") - self._dump(host4) - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in host4.contacts]) - - host5 = self.sched.hosts.find_by_name("test_host_5") - self._dump(host5) - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in host5.contacts]) - self.assertIn("test_contact_2", [self.sched.contacts[c].get_name() for c in host5.contacts]) - - - host6 = self.sched.hosts.find_by_name("test_host_6") - self._dump(host6) - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in host6.contacts]) - self.assertIn("test_contact_2", [self.sched.contacts[c].get_name() for c in host6.contacts]) - - # Now Let's check service inheritance - - svc1 = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "svc_tmplA") - self._dump_svc(svc1) - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in svc1.contacts]) - - svc2 = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "svc_tmplB") - self._dump_svc(svc2) - self.assertIn("test_contact_2", [self.sched.contacts[c].get_name() for c in svc2.contacts]) - - svc3 = self.sched.services.find_srv_by_name_and_hostname("test_host_0", "svc_tmplA_tmplB") - self.assertIn("test_contact_1", [self.sched.contacts[c].get_name() for c in svc3.contacts]) - self.assertIn("test_contact_2", [self.sched.contacts[c].get_name() for c in svc3.contacts]) - self._dump_svc(svc3) - -if __name__ == '__main__': - unittest.main() diff --git a/test/cfg/contactgroup/alignak_contactgroup_members.cfg b/test/cfg/contactgroup/alignak_contactgroup_members.cfg new file mode 100755 index 000000000..9044ab6d3 --- /dev/null +++ b/test/cfg/contactgroup/alignak_contactgroup_members.cfg @@ -0,0 +1,22 @@ +cfg_dir=../default + +define contact{ + contact_name test_contact_2 + alias Second contact alias + service_notification_period 24x7 + host_notification_period 24x7 + service_notification_options w,u,c,r,f + host_notification_options d,u,r,f,s + service_notification_commands notify-service + host_notification_commands notify-host + email nobody@localhost + can_submit_commands 0 + ; contactgroups another_contact_test +} + +define contactgroup { + contactgroup_name allcontacts_and_groups + alias All: Contacts and groups + members test_contact, test_contact_2 + contactgroup_members test_contact +} diff --git a/test/cfg/contactgroup/alignak_contactgroup_no_contact.cfg b/test/cfg/contactgroup/alignak_contactgroup_no_contact.cfg new file mode 100755 index 000000000..7c9bb30a6 --- /dev/null +++ b/test/cfg/contactgroup/alignak_contactgroup_no_contact.cfg @@ -0,0 +1,6 @@ +cfg_dir=../default + +define contactgroup { + contactgroup_name void + alias Void group +} diff --git a/test/cfg/contactgroup/alignak_contactgroup_with_space.cfg b/test/cfg/contactgroup/alignak_contactgroup_with_space.cfg new file mode 100755 index 000000000..2e9b09442 --- /dev/null +++ b/test/cfg/contactgroup/alignak_contactgroup_with_space.cfg @@ -0,0 +1,6 @@ +cfg_dir=../default + +define contactgroup { + contactgroup_name test_With Spaces + members test_contact +} diff --git a/test/cfg/contactgroup/alignak_contactgroup_with_void_member.cfg b/test/cfg/contactgroup/alignak_contactgroup_with_void_member.cfg new file mode 100755 index 000000000..24a594d9f --- /dev/null +++ b/test/cfg/contactgroup/alignak_contactgroup_with_void_member.cfg @@ -0,0 +1,35 @@ +cfg_dir=../default + +define hostgroup{ + hostgroup_name MYGROUP + members h1,h2, +} + + +define host{ + host_name h1 + use generic-host +} + +define host{ + host_name h2 + use generic-host +} + + + +define contactgroup{ + contactgroup_name SPACEMARINES + members m1 , m2 , +} + + +define contact{ + contact_name m1 + use generic-contact +} + +define contact{ + contact_name m2 + use generic-contact +} \ No newline at end of file diff --git a/test/_old/etc/alignak_contactgroups_plus_inheritance.cfg b/test/cfg/contactgroup/alignak_contactgroups_plus_inheritance.cfg similarity index 99% rename from test/_old/etc/alignak_contactgroups_plus_inheritance.cfg rename to test/cfg/contactgroup/alignak_contactgroups_plus_inheritance.cfg index c70a221e7..83b7be3c5 100644 --- a/test/_old/etc/alignak_contactgroups_plus_inheritance.cfg +++ b/test/cfg/contactgroup/alignak_contactgroups_plus_inheritance.cfg @@ -1,3 +1,5 @@ +cfg_dir=../default + define contactgroup{ contactgroup_name test_contact_1 alias test_contacts_alias_1 diff --git a/test/cfg/contactgroup/alignak_groups_with_no_alias.cfg b/test/cfg/contactgroup/alignak_groups_with_no_alias.cfg new file mode 100755 index 000000000..a7acb3ee2 --- /dev/null +++ b/test/cfg/contactgroup/alignak_groups_with_no_alias.cfg @@ -0,0 +1,4 @@ + +define contactgroup { + contactgroup_name NOALIAS +} diff --git a/test/test_contactgroup.py b/test/test_contactgroup.py new file mode 100755 index 000000000..312765aad --- /dev/null +++ b/test/test_contactgroup.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors +# +# This file is part of Alignak. +# +# Alignak is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alignak is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Alignak. If not, see . +# +# + +""" +This file test all cases of eventhandler +""" + +import time + +from alignak.objects import Contact +from alignak.objects import Contactgroup +from alignak_test import AlignakTest + + +class TestContactGroup(AlignakTest): + """ + This class tests the contactgroups + """ + + def test_contactgroup(self): + """ + Default configuration has no loading problems ... as of it contactgroups are parsed + correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + def test_look_for_alias(self): + """ + Default configuration has no loading problems ... as of it contactgroups are parsed correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/contactgroup/alignak_groups_with_no_alias.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a contactgroup named NOALIAS + cg = self.schedulers[0].sched.contactgroups.find_by_name("NOALIAS") + self.assertIsInstance(cg, Contactgroup) + self.assertEqual(cg.get_name(), "NOALIAS") + self.assertEqual(cg.alias, "NOALIAS") + + def test_contactgroup_members(self): + """ + Test if members are linked from group + + :return: None + """ + self.print_header() + self.setup_with_file('cfg/contactgroup/alignak_contactgroup_members.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a contactgroup named allhosts_and_groups + cg = self.schedulers[0].sched.contactgroups.find_by_name("allcontacts_and_groups") + self.assertIsInstance(cg, Contactgroup) + self.assertEqual(cg.get_name(), "allcontacts_and_groups") + + self.assertEqual( + len(self.schedulers[0].sched.contactgroups.get_members_by_name("allcontacts_and_groups")), + 2 + ) + + self.assertEqual(len(cg.get_contacts()), 2) + + self.assertEqual(len(cg.get_contactgroup_members()), 1) + + def test_members_contactgroup(self): + """ + Test if group is linked from the member + :return: None + """ + self.print_header() + self.setup_with_file('cfg/contactgroup/alignak_contactgroup_members.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + #  Found a contactgroup named allhosts_and_groups + cg = self.schedulers[0].sched.contactgroups.find_by_name("allcontacts_and_groups") + self.assertIsInstance(cg, Contactgroup) + self.assertEqual(cg.get_name(), "allcontacts_and_groups") + + self.assertEqual( + len(self.schedulers[0].sched.contactgroups.get_members_by_name( + "allcontacts_and_groups" + )), + 2 + ) + + self.assertEqual(len(cg.get_contacts()), 2) + print("List contactgroup contacts:") + for contact_id in cg.members: + contact = self.schedulers[0].sched.contacts[contact_id] + print("Contact: %s" % contact) + self.assertIsInstance(contact, Contact) + + if contact.get_name() == 'test_ok_0': + self.assertEqual(len(contact.get_contactgroups()), 4) + for group_id in contact.contactgroups: + group = self.schedulers[0].sched.contactgroups[group_id] + print("Group: %s" % group) + self.assertIn(group.get_name(), [ + 'ok', 'contactgroup_01', 'contactgroup_02', 'allcontacts_and_groups' + ]) + + self.assertEqual(len(cg.get_contactgroup_members()), 1) + print("List contactgroup groups:") + for group in cg.get_contactgroup_members(): + print("Group: %s" % group) + self.assertIn(group, [ + 'test_contact' + ]) + + def test_contactgroup_with_no_contact(self): + """ + Allow contactgroups with no hosts + :return: None + """ + self.print_header() + self.setup_with_file('cfg/contactgroup/alignak_contactgroup_no_contact.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + self.assertEqual( + len(self.schedulers[0].sched.contactgroups), + 3 + ) + + for group in self.schedulers[0].sched.contactgroups: + # contactgroups property returns an object list ... unlike the hostgroups property + # of an host group ... + # group = self.schedulers[0].sched.contactgroups[group_id] + print("Group: %s" % group) + + # Found a contactgroup named void + cg = self.schedulers[0].sched.contactgroups.find_by_name("void") + print("cg: %s" % cg) + self.assertIsInstance(cg, Contactgroup) + self.assertEqual(cg.get_name(), "void") + + self.assertEqual( + len(self.schedulers[0].sched.contactgroups.get_members_by_name("void")), + 0 + ) + + print("Contacts: %s" % cg.get_contactgroup_members()) + self.assertEqual(len(cg.get_contactgroup_members()), 0) + + print("Contacts: %s" % cg.get_contacts()) + self.assertEqual(len(cg.get_contacts()), 0) + + def test_contactgroup_with_space(self): + """ + Test that contactgroups can have a name with spaces + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + self.nb_contactgroups = len(self.schedulers[0].sched.contactgroups) + + self.setup_with_file('cfg/contactgroup/alignak_contactgroup_with_space.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + # Two more groups than the default configuration + self.assertEqual( + len(self.schedulers[0].sched.contactgroups), self.nb_contactgroups + 1 + ) + + self.assertEqual( + self.schedulers[0].sched.contactgroups.find_by_name("test_With Spaces").get_name(), + "test_With Spaces" + ) + self.assertIsNot( + self.schedulers[0].sched.contactgroups.get_members_by_name( + "test_With Spaces" + ), + [] + ) + + def _dump_host(self, h): + print "Dumping host", h.get_name() + print h.contact_groups + for c in h.contacts: + print "->", self.schedulers[0].sched.contacts[c].get_name() + + def _dump_svc(self, s): + print "Dumping Service", s.get_name() + print " contact_groups : %s " % s.contact_groups + for c in s.contacts: + print "->", self.schedulers[0].sched.contacts[c].get_name() + + def test_contactgroups_plus_inheritance(self): + """ + Test that contactgroups correclty manage inheritance + :return: None + """ + self.print_header() + self.setup_with_file('cfg/contactgroup/alignak_contactgroups_plus_inheritance.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + host0 = self.schedulers[0].sched.hosts.find_by_name("test_host_0") + # HOST 1 should have 2 group of contacts + # WARNING, it's a string, not the real objects! + self._dump_host(host0) + + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in host0.contacts] + ) + self.assertIn( + "test_contact_2", + [self.schedulers[0].sched.contacts[c].get_name() for c in host0.contacts] + ) + + host2 = self.schedulers[0].sched.hosts.find_by_name("test_host_2") + self._dump_host(host2) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in host2.contacts] + ) + + host3 = self.schedulers[0].sched.hosts.find_by_name("test_host_3") + self._dump_host(host3) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in host3.contacts] + ) + self.assertIn( + "test_contact_2", + [self.schedulers[0].sched.contacts[c].get_name() for c in host3.contacts] + ) + + host4 = self.schedulers[0].sched.hosts.find_by_name("test_host_4") + self._dump_host(host4) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in host4.contacts] + ) + + host5 = self.schedulers[0].sched.hosts.find_by_name("test_host_5") + self._dump_host(host5) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in host5.contacts] + ) + self.assertIn( + "test_contact_2", + [self.schedulers[0].sched.contacts[c].get_name() for c in host5.contacts] + ) + + host6 = self.schedulers[0].sched.hosts.find_by_name("test_host_6") + self._dump_host(host6) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in host6.contacts] + ) + self.assertIn( + "test_contact_2", + [self.schedulers[0].sched.contacts[c].get_name() for c in host6.contacts] + ) + + # Now Let's check service inheritance + + svc1 = self.schedulers[0].sched.services.find_srv_by_name_and_hostname( + "test_host_0", "svc_tmplA" + ) + self._dump_svc(svc1) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in svc1.contacts] + ) + + svc2 = self.schedulers[0].sched.services.find_srv_by_name_and_hostname( + "test_host_0", "svc_tmplB" + ) + self._dump_svc(svc2) + self.assertIn( + "test_contact_2", + [self.schedulers[0].sched.contacts[c].get_name() for c in svc2.contacts] + ) + + svc3 = self.schedulers[0].sched.services.find_srv_by_name_and_hostname( + "test_host_0", "svc_tmplA_tmplB" + ) + self.assertIn( + "test_contact_1", + [self.schedulers[0].sched.contacts[c].get_name() for c in svc3.contacts] + ) + self.assertIn( + "test_contact_2", + [self.schedulers[0].sched.contacts[c].get_name() for c in svc3.contacts] + ) + self._dump_svc(svc3) From e1225458ac6084b0d5913077940e2111865e0ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 12 Sep 2016 20:31:57 +0200 Subject: [PATCH 12/16] Fix pylint :/ --- alignak/objects/servicegroup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/alignak/objects/servicegroup.py b/alignak/objects/servicegroup.py index e8d56db8b..bf681b2d2 100644 --- a/alignak/objects/servicegroup.py +++ b/alignak/objects/servicegroup.py @@ -113,7 +113,6 @@ def get_servicegroup_members(self): :rtype: list | str """ if hasattr(self, 'servicegroup_members'): - print("SG groups members: " % self.servicegroup_members) return self.servicegroup_members else: return [] @@ -151,7 +150,6 @@ def get_services_by_explosion(self, servicegroups): if servicegroup is not None: value = servicegroup.get_services_by_explosion(servicegroups) if value is not None: - print("SG string member: %s" % value) self.add_string_member(value) if hasattr(self, 'members'): From 327b4ce9028b42513a3ac57374b8fdb38ac53ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Tue, 13 Sep 2016 07:23:31 +0200 Subject: [PATCH 13/16] Refactore hostdependency tests --- .../etc/alignak_hostdep_withno_depname.cfg | 22 --- test/_old/test_hostdep_with_multiple_names.py | 75 ---------- test/_old/test_hostdep_withno_depname.py | 76 ---------- .../alignak_hostdep_with_multiple_names.cfg | 2 +- .../alignak_hostdep_with_no_depname.cfg | 29 ++++ test/test_hostdependency.py | 133 ++++++++++++++++++ 6 files changed, 163 insertions(+), 174 deletions(-) delete mode 100644 test/_old/etc/alignak_hostdep_withno_depname.cfg delete mode 100644 test/_old/test_hostdep_with_multiple_names.py delete mode 100644 test/_old/test_hostdep_withno_depname.py rename test/{_old/etc => cfg/hostdependency}/alignak_hostdep_with_multiple_names.cfg (99%) create mode 100644 test/cfg/hostdependency/alignak_hostdep_with_no_depname.cfg create mode 100755 test/test_hostdependency.py diff --git a/test/_old/etc/alignak_hostdep_withno_depname.cfg b/test/_old/etc/alignak_hostdep_withno_depname.cfg deleted file mode 100644 index 86203e385..000000000 --- a/test/_old/etc/alignak_hostdep_withno_depname.cfg +++ /dev/null @@ -1,22 +0,0 @@ - -define hostdependency { - host_name test_host_0 - dependent_hostgroup_name flap -} - - - -define host{ - address 127.0.0.1 - alias up_0 - check_command check-host-alive-parent!up!$HOSTSTATE:test_router_0$ - event_handler eventhandler - check_period 24x7 - host_name test_host_1 - hostgroups flap - parents test_router_0 - use generic-host - criticity 5 - _ostype gnulinux - _oslicense gpl -} \ No newline at end of file diff --git a/test/_old/test_hostdep_with_multiple_names.py b/test/_old/test_hostdep_with_multiple_names.py deleted file mode 100644 index 641c30bd9..000000000 --- a/test/_old/test_hostdep_with_multiple_names.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Hartmut Goebel, h.goebel@goebel-consult.de -# Grégory Starck, g.starck@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestHostDepWithMultipleNames(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_hostdep_with_multiple_names.cfg']) - - def test_DepWithMultipleNames(self): - for n in ['svn1', 'svn2', 'svn3', 'svn4', 'nas1', 'nas2', 'nas3']: - val = globals()[n] = self.sched.hosts.find_by_name(n) - self.assertIsNot(val, None) - # We check that nas3 is a father of svn4, the simple case - self.assertIn(nas3.uuid, [e[0] for e in svn4.act_depend_of]) - - # Now the more complex one - for son in [svn1, svn2, svn3]: - for father in [nas1, nas2]: - print 'Checking if', father.get_name(), 'is the father of', son.get_name() - print son.act_depend_of - for e in son.act_depend_of: - print self.sched.find_item_by_id(e[0]).get_name() - self.assertIn(father.uuid, [e[0] for e in son.act_depend_of]) - -if __name__ == '__main__': - unittest.main() diff --git a/test/_old/test_hostdep_withno_depname.py b/test/_old/test_hostdep_withno_depname.py deleted file mode 100644 index b1a700ff3..000000000 --- a/test/_old/test_hostdep_withno_depname.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors -# -# This file is part of Alignak. -# -# Alignak is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alignak is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Alignak. If not, see . -# -# -# This file incorporates work covered by the following copyright and -# permission notice: -# -# Copyright (C) 2009-2014: -# Jean Gabes, naparuba@gmail.com -# Hartmut Goebel, h.goebel@goebel-consult.de -# Grégory Starck, g.starck@gmail.com -# Sebastien Coavoux, s.coavoux@free.fr - -# This file is part of Shinken. -# -# Shinken is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Shinken is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Shinken. If not, see . - -# -# This file is used to test reading and processing of config files -# - -from alignak_test import * - - -class TestHostDepWithNodepname(AlignakTest): - - def setUp(self): - self.setup_with_file(['etc/alignak_hostdep_withno_depname.cfg']) - - def test_hostdep_withno_depname(self): - # - # Config is not correct because of a wrong relative path - # in the main config file - # - print "Get the hosts and services" - now = time.time() - host = self.sched.hosts.find_by_name("test_host_0") - h2 = self.sched.hosts.find_by_name("test_host_1") - self.assertIsNot(h2, None) - # Should got a link between host and h2 - print h2.act_depend_of - self.assertGreater(len(h2.act_depend_of), 0) - l = h2.act_depend_of[0] - h = l[0] # the host that h2 depend on - self.assertIs(host.uuid, h) - -if __name__ == '__main__': - unittest.main() diff --git a/test/_old/etc/alignak_hostdep_with_multiple_names.cfg b/test/cfg/hostdependency/alignak_hostdep_with_multiple_names.cfg similarity index 99% rename from test/_old/etc/alignak_hostdep_with_multiple_names.cfg rename to test/cfg/hostdependency/alignak_hostdep_with_multiple_names.cfg index 1addbf87d..c6cd9e451 100644 --- a/test/_old/etc/alignak_hostdep_with_multiple_names.cfg +++ b/test/cfg/hostdependency/alignak_hostdep_with_multiple_names.cfg @@ -1,4 +1,4 @@ - +cfg_dir=../default define host{ diff --git a/test/cfg/hostdependency/alignak_hostdep_with_no_depname.cfg b/test/cfg/hostdependency/alignak_hostdep_with_no_depname.cfg new file mode 100644 index 000000000..9647cebca --- /dev/null +++ b/test/cfg/hostdependency/alignak_hostdep_with_no_depname.cfg @@ -0,0 +1,29 @@ +cfg_dir=../default + +# 0 depends upon 1 +define hostdependency { + host_name test_host_1 + dependent_hostname test_host_0 +} + +# All host from flap group depends upon 0 +define hostdependency { + host_name test_host_0 + dependent_hostgroup_name flap +} + +# test_router_0 is a parent of test_host_1 +define host{ + address 127.0.0.1 + alias up_0 + check_command check-host-alive-parent!up!$HOSTSTATE:test_router_0$ + event_handler eventhandler + check_period 24x7 + host_name test_host_1 + hostgroups flap + parents test_router_0 + use generic-host + criticity 5 + _ostype gnulinux + _oslicense gpl +} \ No newline at end of file diff --git a/test/test_hostdependency.py b/test/test_hostdependency.py new file mode 100755 index 000000000..13cd13459 --- /dev/null +++ b/test/test_hostdependency.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors +# +# This file is part of Alignak. +# +# Alignak is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alignak is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Alignak. If not, see . +# +# + +""" +This file test all cases of eventhandler +""" + +import time + +from alignak.objects import Host +from alignak.objects import Hostgroup +from alignak_test import AlignakTest + + +class TestHostDependency(AlignakTest): + """ + This class tests the hostdependency + """ + + def test_hostdependencies(self): + """ + Default configuration has no loading problems ... as of it hosts + dependencies are parsed correctly + :return: None + """ + self.print_header() + self.setup_with_file('cfg/cfg_default.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + def test_hostdep_simple(self): + """ + test_host_1 dependes upon test_host_0 + test_router_0 is parent of test_host_1 + all the hosts in flap group dependes upon test_host_0 + :return: + """ + self.print_header() + self.setup_with_file('cfg/hostdependency/alignak_hostdep_with_no_depname.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + print("Get the hosts and services") + test_router_0 = self.schedulers[0].sched.hosts.find_by_name("test_router_0") + self.assertIsNotNone(test_router_0) + print("test_router_0 is: %s" % test_router_0.uuid) + print("test_router_0 'parents': %s" % test_router_0.act_depend_of) + print("test_router_0 'children': %s" % test_router_0.act_depend_of_me) + + test_host_0 = self.schedulers[0].sched.hosts.find_by_name("test_host_0") + self.assertIsNotNone(test_host_0) + print("test_host_0 is: %s" % test_host_0.uuid) + print("test_host_0 'parents': %s" % test_host_0.act_depend_of) + print("test_host_0 'children': %s" % test_host_0.act_depend_of_me) + + svc_0 = self.schedulers[0].sched.services.find_srv_by_name_and_hostname( + "test_host_0", "test_ok_0" + ) + + test_host_1 = self.schedulers[0].sched.hosts.find_by_name("test_host_1") + self.assertIsNotNone(test_host_1) + print("test_host_1 is: %s" % test_host_1.uuid) + print("test_host_1 'parents': %s" % test_host_1.act_depend_of) + print("test_host_1 'children': %s" % test_host_1.act_depend_of_me) + + # test_router_0 is a dependency of test_host_0 and test_host_1 + self.assertEqual(len(test_router_0.act_depend_of_me), 2) + for link in test_router_0.act_depend_of_me: + item_id = link[0] + self.assertIn(item_id, [test_host_0.uuid, test_host_1.uuid]) + + # test_host_0 depends upon test_router_0 + self.assertEqual(len(test_host_0.act_depend_of), 1) + for link in test_host_0.act_depend_of: + item_id = link[0] + self.assertIn(item_id, [test_router_0.uuid]) + + # test_host_0 is a dependency of test_host_1 and of a service + self.assertEqual(len(test_host_0.act_depend_of_me), 2) + for link in test_host_0.act_depend_of_me: + item_id = link[0] + self.assertIn(item_id, [test_host_1.uuid, svc_0.uuid]) + + # test_host_1 depends upon test_host_0 and test_router_0 + self.assertEqual(len(test_host_1.act_depend_of), 2) + for link in test_host_1.act_depend_of: + item_id = link[0] + self.assertIn(item_id, [test_host_0.uuid, test_router_0.uuid]) + + def test_hostdep_complex(self): + """ + test_host_1 dependes upon test_host_0 + test_router_0 is parent of test_host_1 + all the hosts in flap group dependes upon test_host_0 + :return: + """ + self.print_header() + self.setup_with_file('cfg/hostdependency/alignak_hostdep_with_multiple_names.cfg') + self.assertTrue(self.schedulers[0].conf.conf_is_correct) + + for n in ['svn1', 'svn2', 'svn3', 'svn4', 'nas1', 'nas2', 'nas3']: + host = globals()[n] = self.schedulers[0].sched.hosts.find_by_name(n) + self.assertIsNotNone(host) + + # We check that nas3 is a father of svn4, the simple case + self.assertIn(nas3.uuid, [e[0] for e in svn4.act_depend_of]) + + # Now the more complex one + for son in [svn1, svn2, svn3]: + for father in [nas1, nas2]: + print 'Checking if', father.get_name(), 'is the father of', son.get_name() + print son.act_depend_of + for e in son.act_depend_of: + print self.schedulers[0].sched.find_item_by_id(e[0]).get_name() + self.assertIn(father.uuid, [e[0] for e in son.act_depend_of]) + From 7612cfdd733721de548c24476073e81c933ffff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Tue, 13 Sep 2016 10:50:57 +0200 Subject: [PATCH 14/16] AlignakTest: clean broks and logs. @ddurieux: have a look please --- test/alignak_test.py | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/test/alignak_test.py b/test/alignak_test.py index f86ac1ee6..ce52f6eac 100755 --- a/test/alignak_test.py +++ b/test/alignak_test.py @@ -147,6 +147,8 @@ def setup_with_file(self, configuration_file): :type configuration_file: str :return: None """ + self.broks = {} + self.schedulers = [] self.arbiter = None self.arbiter = Arbiter([configuration_file], False, False, False, False, @@ -159,7 +161,6 @@ def setup_with_file(self, configuration_file): self.arbiter.dispatcher = Dispatcher(self.arbiter.conf, self.arbiter.myself) self.arbiter.dispatcher.prepare_dispatch() - self.schedulers = [] for scheduler in self.arbiter.dispatcher.schedulers: sched = Alignak([], False, False, True, '/tmp/scheduler.log') # logger.setLevel('DEBUG') @@ -174,7 +175,7 @@ def add(self, b): self.broks[b.uuid] = b return if isinstance(b, ExternalCommand): - self.sched.run_external_command(b.cmd_line) + self.schedulers[0].run_external_command(b.cmd_line) def fake_check(self, ref, exit_status, output="OK"): # print "fake", ref @@ -267,10 +268,10 @@ def worker_loop(self, verbose=True): def show_logs(self): print "--- logs <<<----------------------------------" - if hasattr(self.scheduler, "sched"): - broks = self.scheduler.sched.broks - else: - broks = self.broks + broks = self.broks + if hasattr(self, "schedulers") and self.schedulers and hasattr(self.schedulers[0], "sched"): + broks = self.schedulers[0].sched.broks + for brok in sorted(broks.values(), lambda x, y: cmp(x.uuid, y.uuid)): if brok.type == 'log': brok.prepare() @@ -308,8 +309,8 @@ def show_and_clear_actions(self): self.clear_actions() def count_logs(self): - if hasattr(self.scheduler, "sched"): - broks = self.scheduler.sched.broks + if hasattr(self, "schedulers") and self.schedulers and hasattr(self.schedulers[0], "sched"): + broks = self.schedulers[0].sched.broks else: broks = self.broks return len([b for b in broks.values() if b.type == 'log']) @@ -322,10 +323,10 @@ def count_actions(self): return len(actions.values()) def clear_logs(self): - if hasattr(self.scheduler, "sched"): - broks = self.scheduler.sched.broks - else: - broks = self.broks + broks = self.broks + if hasattr(self, "schedulers") and self.schedulers and hasattr(self.schedulers[0], "sched"): + broks = self.schedulers[0].sched.broks + id_to_del = [] for b in broks.values(): if b.type == 'log': @@ -394,7 +395,10 @@ def assert_log_match(self, index, pattern): """ regex = re.compile(pattern) log_num = 1 - broks = sorted(self.schedulers[0].sched.broks.values(), key=lambda x: x.creation_time) + broks = self.broks + if hasattr(self, "schedulers") and self.schedulers and hasattr(self.schedulers[0], "sched"): + broks = self.schedulers[0].sched.broks + found = False for brok in broks: if brok.type == 'log': @@ -457,8 +461,10 @@ def assert_checks_match(self, index, pattern, field): def _any_log_match(self, pattern, assert_not): regex = re.compile(pattern) - broks = getattr(self, 'sched', self).broks - broks = sorted(broks.values(), lambda x, y: cmp(x.uuid, y.uuid)) + broks = self.broks + if hasattr(self, "schedulers") and self.schedulers and hasattr(self.schedulers[0], "sched"): + broks = self.schedulers[0].sched.broks + for brok in broks: if brok.type == 'log': brok.prepare() @@ -480,7 +486,11 @@ def assert_no_log_match(self, pattern): def get_log_match(self, pattern): regex = re.compile(pattern) res = [] - for brok in sorted(self.sched.broks.values(), lambda x, y: cmp(x.uuid, y.uuid)): + broks = self.broks + if hasattr(self, "schedulers") and self.schedulers and hasattr(self.schedulers[0], "sched"): + broks = self.schedulers[0].sched.broks + + for brok in broks: if brok.type == 'log': if re.search(regex, brok.data['log']): res.append(brok.data['log']) From 55e0d269c35cc48ea2bf842cfc585eeadf605cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Tue, 13 Sep 2016 15:12:26 +0200 Subject: [PATCH 15/16] Alignak, loading configuration - dump warnings and errors after configuration failed message --- alignak/daemons/arbiterdaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alignak/daemons/arbiterdaemon.py b/alignak/daemons/arbiterdaemon.py index c96b4fa97..417cbb1da 100644 --- a/alignak/daemons/arbiterdaemon.py +++ b/alignak/daemons/arbiterdaemon.py @@ -370,9 +370,9 @@ def load_config_file(self): # pylint: disable=R0915 # The conf can be incorrect here if the cut into parts see errors like # a realm with hosts and not schedulers for it if not self.conf.conf_is_correct: - self.conf.show_errors() err = "Configuration is incorrect, sorry, I bail out" logger.error(err) + self.conf.show_errors() sys.exit(err) logger.info('Things look okay - No serious problems were detected ' From faf137ed4a92e5b0a1c79a8ea644b1a69a527705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Tue, 13 Sep 2016 15:13:47 +0200 Subject: [PATCH 16/16] Configuration check: correctly handle warnings and errors --- alignak/objects/config.py | 40 ++++++++++++++-- alignak/objects/host.py | 23 +++++---- alignak/objects/item.py | 77 +++++++++++++++++++---------- alignak/objects/schedulingitem.py | 80 ++++++++++++++++++++----------- 4 files changed, 154 insertions(+), 66 deletions(-) diff --git a/alignak/objects/config.py b/alignak/objects/config.py index 3b06273dc..2102e905f 100644 --- a/alignak/objects/config.py +++ b/alignak/objects/config.py @@ -888,8 +888,11 @@ def load_params(self, params): # it's a macro or a useless now param, we don't touch this val = value else: - logger.warning("Guessing the property %s type because it is not in " - "%s object properties", key, self.__class__.__name__) + msg = "Guessing the property %s type because it is not in %s object properties" % ( + key, self.__class__.__name__ + ) + self.configuration_warnings.append(msg) + logger.warning(msg) val = ToGuessProp.pythonize(clean_params[key]) setattr(self, key, val) @@ -2106,7 +2109,14 @@ def is_correct(self): # pylint: disable=R0912 cur = getattr(self, obj) if not cur.is_correct(): valid = False + self.configuration_errors += cur.configuration_errors logger.error("\t%s conf incorrect!!", obj) + logger.error("\t%s configuration errors: %d, total: %d", obj, len(cur.configuration_errors), len(self.configuration_errors)) + if cur.configuration_warnings: + self.configuration_warnings += cur.configuration_warnings + logger.error("\t%s configuration warnings: %d, total: %d", obj, + len(cur.configuration_warnings), len(self.configuration_warnings)) + if self.read_config_silent == 0: logger.info('\tChecked %d %s', len(cur), obj) @@ -2121,7 +2131,15 @@ def is_correct(self): # pylint: disable=R0912 logger.info('Checking %s...', obj) if not cur.is_correct(): valid = False + self.configuration_errors += cur.configuration_errors logger.error("\t%s conf incorrect!!", obj) + logger.error("\t%s configuration errors: %d, total: %d", obj, + len(cur.configuration_errors), len(self.configuration_errors)) + if cur.configuration_warnings: + self.configuration_warnings += cur.configuration_warnings + logger.error("\t%s configuration warnings: %d, total: %d", obj, + len(cur.configuration_warnings), len(self.configuration_warnings)) + if self.read_config_silent == 0: logger.info('\tChecked %d %s', len(cur), obj) @@ -2234,12 +2252,24 @@ def add_error(self, txt): self.conf_is_correct = False def show_errors(self): - """Loop over configuration_errors and log them + """ + Loop over configuration warnings and log them as INFO log + Loop over configuration errors and log them as INFO log + + Note that the warnings and errors are logged on the fly during the configuration parsing. + It is not necessary to log as WARNING and ERROR in this function which is used as a sum-up + on the end of configuration parsing when an error has been detected. :return: None """ - for err in self.configuration_errors: - logger.error(err) + if self.configuration_warnings: + logger.info("Configuration warnings:") + for msg in self.configuration_warnings: + logger.info(msg) + if self.configuration_errors: + logger.info("Configuration errors:") + for msg in self.configuration_errors: + logger.info(msg) def create_packs(self, nb_packs): # pylint: disable=R0915,R0914,R0912,W0613 """Create packs of hosts and services (all dependencies are resolved) diff --git a/alignak/objects/host.py b/alignak/objects/host.py index 48c0ca775..f94bd56f3 100644 --- a/alignak/objects/host.py +++ b/alignak/objects/host.py @@ -281,17 +281,20 @@ def is_correct(self): :return: True if the configuration is correct, otherwise False :rtype: bool """ - state = super(Host, self).is_correct() - cls = self.__class__ + state = True + # Internal checks before executing inherited function... + cls = self.__class__ if hasattr(self, 'host_name'): - for char in cls.illegal_object_name_chars: - if char in self.host_name: - logger.error("[%s::%s] host_name got an illegal character: %s", - self.my_type, self.get_name(), char) + for c in cls.illegal_object_name_chars: + if c in self.host_name: + msg = "[%s::%s] host_name got an illegal character: %s" % ( + self.my_type, self.get_name(), c + ) + self.configuration_errors.append(msg) state = False - return state + return super(Host, self).is_correct() or state def get_services(self): """Get all services for this host @@ -1297,7 +1300,7 @@ def is_correct(self): :return: True if the configuration is correct, False otherwise :rtype: bool """ - valid = super(Hosts, self).is_correct() + state = True loop = self.no_loop_in_parents("self", "parents") if len(loop) > 0: logger.error("Loop detected while checking hosts ") @@ -1309,6 +1312,6 @@ def is_correct(self): elif elem in item.parents: logger.error("Host %s is child in dependency defined in %s", self[elem].get_name(), self[elem].imported_from) - return False + state = False - return valid + return super(Hosts, self).is_correct() or state diff --git a/alignak/objects/item.py b/alignak/objects/item.py index 8e9fb3dde..2ae244bc6 100644 --- a/alignak/objects/item.py +++ b/alignak/objects/item.py @@ -412,23 +412,35 @@ def is_correct(self): """ Check if this object is correct + This function: + - checks if the required properties are defined + - logs the previously found warnings and errors + :return: True if it's correct, otherwise False :rtype: bool """ state = True properties = self.__class__.properties - # Raised all previously saw errors like unknown contacts and co - if self.configuration_errors != []: - state = False - for err in self.configuration_errors: - logger.error("[item::%s] %s", self.get_name(), err) - for prop, entry in properties.items(): if not hasattr(self, prop) and entry.required: - logger.error("[item::%s] %s property is missing", self.get_name(), prop) + msg = "[%s::%s] %s property is missing" % ( + self.my_type, self.get_name(), prop + ) + self.configuration_errors.append(msg) state = False + # Log all previously sawn warnings + if self.configuration_warnings: + for msg in self.configuration_warnings: + logger.warning("*** CFG *** [%s::%s] %s", self.my_type, self.get_name(), msg) + + # Raise all previously sawn errors + if self.configuration_errors: + state = False + for msg in self.configuration_errors: + logger.error("*** CFG *** [%s::%s] %s", self.my_type, self.get_name(), msg) + return state def old_properties_names_to_new(self): @@ -1106,8 +1118,9 @@ def is_correct(self): :return: True if correct, otherwise False :rtype: bool """ - # we are ok at the beginning. Hope we still ok at the end... + # we are ok at the beginning. Hope we are still ok at the end... valid = True + # Some class do not have twins, because they do not have names # like servicedependencies twins = getattr(self, 'twins', None) @@ -1115,21 +1128,13 @@ def is_correct(self): # Ok, look at no twins (it's bad!) for t_id in twins: i = self.items[t_id] - logger.warning("[items] %s.%s is duplicated from %s", - i.__class__.my_type, - i.get_name(), - getattr(i, 'imported_from', "unknown source")) - - # Then look if we have some errors in the conf - # Juts print warnings, but raise errors - for err in self.configuration_warnings: - logger.warning("[items] %s", err) - - for err in self.configuration_errors: - logger.error("[items] %s", err) - valid = False + msg = "[items] %s.%s is duplicated from %s" % ( + i.__class__.my_type, i.get_name(), + getattr(i, 'imported_from', "unknown source") + ) + self.configuration_warnings.append(msg) - # Then look for individual ok + # Better check individual items before displaying the global items list errors and warnings for i in self: # Alias and display_name hook hook prop_name = getattr(self.__class__, 'name_property', None) @@ -1140,9 +1145,33 @@ def is_correct(self): # Now other checks if not i.is_correct(): - source = getattr(i, 'imported_from', "unknown source") - logger.error("[items] In %s is incorrect ; from %s", i.get_name(), source) valid = False + source = getattr(i, 'imported_from', "unknown source") + msg = "Configuration in %s::%s is incorrect; from: %s" % ( + i.my_type, i.get_name(), source + ) + self.configuration_errors.append(msg) + + # The is_correct method of an item already makes the logs... + # for msg in i.configuration_warnings: + # logger.warning("[W] -> %s", msg) + # self.configuration_warnings.append(msg) + # + # for msg in i.configuration_errors: + # logger.error("[E] -> %s", msg) + # self.configuration_errors.append(msg) + # valid = False + + # Log all previously sawn warnings + if self.configuration_warnings: + for msg in self.configuration_warnings: + logger.warning("[items] %s", msg) + + # Raise all previously sawn errors + if self.configuration_errors: + valid = False + for msg in self.configuration_errors: + logger.error("[items] %s", msg) return valid diff --git a/alignak/objects/schedulingitem.py b/alignak/objects/schedulingitem.py index 3c84e9892..1c785d4bb 100644 --- a/alignak/objects/schedulingitem.py +++ b/alignak/objects/schedulingitem.py @@ -2987,25 +2987,35 @@ def notification_is_blocked_by_contact(self, notifways, timeperiods, cdowntimes, pass def is_correct(self): + """ + Check if this object is correct - state = True + This function: + - control some specific properties + - call the parent object check function (checks required properties + and log warnings and errors) - for prop, entry in self.__class__.properties.items(): - if not entry.special and not hasattr(self, prop) and entry.required: - logger.error("[%s::%s] %s property not set", - self.my_type, self.get_name(), prop) - state = False + :return: + """ - # Then look if we have some errors in the conf - # Juts print warnings, but raise errors - for err in self.configuration_warnings: - logger.warning("[%s::%s] %s", self.my_type, self.get_name(), err) + state = True - # Raised all previously saw errors like unknown contacts and co - if self.configuration_errors != []: - state = False - for err in self.configuration_errors: - logger.error("[%s::%s] %s", self.my_type, self.get_name(), err) + # for prop, entry in self.__class__.properties.items(): + # if not entry.special and not hasattr(self, prop) and entry.required: + # logger.error("[%s::%s] %s property not set", + # self.my_type, self.get_name(), prop) + # state = False + # + # # Then look if we have some errors in the conf + # # Juts print warnings, but raise errors + # for err in self.configuration_warnings: + # logger.warning("[%s::%s] %s", self.my_type, self.get_name(), err) + # + # # Raised all previously saw errors like unknown contacts and co + # if self.configuration_errors != []: + # state = False + # for err in self.configuration_errors: + # logger.error("[%s::%s] %s", self.my_type, self.get_name(), err) # If no notif period, set it to None, mean 24x7 if not hasattr(self, 'notification_period'): @@ -3013,42 +3023,58 @@ def is_correct(self): # Ok now we manage special cases... if self.notifications_enabled and self.contacts == []: - logger.warning("[%s::%s] no contacts nor contact_groups property", - self.my_type, self.get_name()) + msg = "[%s::%s] no contacts nor contact_groups property" % ( + self.my_type, self.get_name() + ) + self.configuration_warnings.append(msg) # If we got an event handler, it should be valid if getattr(self, 'event_handler', None) and not self.event_handler.is_valid(): - logger.error("[%s::%s] event_handler '%s' is invalid", - self.my_type, self.get_name(), self.event_handler.command) + msg = "[%s::%s] event_handler '%s' is invalid" % ( + self.my_type, self.get_name(), self.event_handler.command + ) + self.configuration_errors.append(msg) state = False if not hasattr(self, 'check_command'): - logger.error("[%s::%s] no check_command", self.my_type, self.get_name()) + msg = "[%s::%s] no check_command" % ( + self.my_type, self.get_name() + ) + self.configuration_errors.append(msg) state = False # Ok got a command, but maybe it's invalid else: if not self.check_command.is_valid(): - logger.error("[%s::%s] check_command '%s' invalid", - self.my_type, self.get_name(), self.check_command.command) + msg = "[%s::%s] check_command '%s' invalid" % ( + self.my_type, self.get_name(), self.check_command.command + ) + self.configuration_errors.append(msg) state = False if self.got_business_rule: if not self.business_rule.is_valid(): - logger.error("[%s::%s] business_rule invalid", - self.my_type, self.get_name()) + msg = "[%s::%s] business_rule invalid" % ( + self.my_type, self.get_name() + ) + self.configuration_errors.append(msg) for bperror in self.business_rule.configuration_errors: - logger.error("[%s::%s]: %s", self.my_type, self.get_name(), bperror) + msg = "[%s::%s]: %s" % (self.my_type, self.get_name(), bperror) + self.configuration_errors.append(msg) state = False if not hasattr(self, 'notification_interval') \ and self.notifications_enabled is True: - logger.error("[%s::%s] no notification_interval but notifications enabled", - self.my_type, self.get_name()) + msg = "[%s::%s] no notification_interval but notifications enabled" % ( + self.my_type, self.get_name() + ) + self.configuration_errors.append(msg) state = False # if no check_period, means 24x7, like for services if not hasattr(self, 'check_period'): self.check_period = None + state = super(SchedulingItem, self).is_correct() + return state