def test_check_data(self): """Check Data modify TrayIcon Actions""" # TrayIcon and Dashboard for notifier tray_icon = TrayIcon(self.icon) dashboard = Dashboard() dashboard.initialize() under_test = AppNotifier() under_test.initialize(self.backend, tray_icon, dashboard) tray_icon.build_menu(self.backend, dashboard) # Start notifier under_test.set_interval() # Check Actions are pending self.assertEqual( 'Hosts UP, Wait...', under_test.tray_icon.qaction_factory.get('hosts_up').text()) self.assertEqual( 'Services OK, Wait...', under_test.tray_icon.qaction_factory.get('services_ok').text()) # Check data... under_test.check_data() # ...so menu actions should be update self.assertNotEqual( 'Hosts UP, Wait...', under_test.tray_icon.qaction_factory.get('hosts_up').text()) self.assertNotEqual( 'Services OK, Wait...', under_test.tray_icon.qaction_factory.get('services_ok').text())
def test_about_action(self): """About QAction is created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_about_action() self.assertIsNotNone(under_test.qaction_factory) self.assertIsInstance(under_test.qaction_factory.get('about'), QAction)
def test_host_actions(self): """Hosts QActions are created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_hosts_actions() self.assertIsInstance(under_test.qaction_factory.get('hosts_up'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_down'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_unreachable'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_acknowledge'), QAction) self.assertIsInstance(under_test.qaction_factory.get('hosts_downtime'), QAction)
def test_services_actions(self): """Services QActions are created""" under_test = TrayIcon(TestTrayIcon.icon) self.assertFalse(under_test.qaction_factory.actions) under_test.create_services_actions() self.assertIsInstance(under_test.qaction_factory.get('services_ok'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_warning'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_critical'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_unknown'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_acknowledge'), QAction) self.assertIsInstance(under_test.qaction_factory.get('services_downtime'), QAction)
def run(self, app_backend=None): # pragma: no cover """ Start all Alignak-app processes and create AppBackend if connection by config file. :param app_backend: AppBackend object :type app_backend: alignak_app.core.backend.AppBackend | None """ # If not login form, app try anyway to connect by token if not app_backend: app_backend = AppBackend() connect = app_backend.login() if connect: username = app_backend.get_user(projection=['name'])['name'] send_banner('OK', 'Welcome %s, you are connected to Alignak Backend' % username) else: self.display_error_msg() if 'token' not in app_backend.user: app_backend.user['token'] = app_backend.backend.token # Dashboard self.dashboard = Dashboard() self.dashboard.initialize() # TrayIcon self.tray_icon = TrayIcon(QIcon(get_image_path('icon'))) self.tray_icon.build_menu(app_backend, self.dashboard) self.tray_icon.show() app_backend.app = self start = bool(app_backend.get_user(projection=['name'])) if start: # Notifier self.notifier = AppNotifier() self.notifier.initialize(app_backend, self.tray_icon, self.dashboard) self.notifier_timer.start(self.notifier.interval) self.notifier_timer.timeout.connect(self.notifier.check_data) self.reconnecting.connect(self.reconnect_to_backend) else: # In case of... self.display_error_msg()
def test_states_change(self): """States and Notify Changes""" self.backend = AppBackend() self.backend.login() # TrayIcon and Dashboard for notifier dashboard = Dashboard() dashboard.initialize() tray_icon = TrayIcon(self.icon) tray_icon.build_menu(self.backend, dashboard) # Initialize Notifier under_test = AppNotifier() under_test.initialize(self.backend, tray_icon, dashboard) # Changes are True, first_start is True self.assertFalse(under_test.changes) self.assertTrue(under_test.first_start) self.assertIsNone(under_test.old_synthesis)
def test_build_menu(self): """Build Menu add QActions""" under_test = TrayIcon(TestTrayIcon.icon) dashboard_test = Dashboard() # Assert no actions in Menu self.assertFalse(under_test.menu.actions()) self.assertIsNone(under_test.app_about) self.assertIsNone(under_test.synthesis) self.assertIsNone(under_test.alignak_status) self.assertIsNotNone(under_test.qaction_factory) under_test.build_menu(self.backend, dashboard_test) # Assert actions are added in Menu self.assertTrue(under_test.menu.actions()) self.assertIsNotNone(under_test.app_about) self.assertIsNotNone(under_test.synthesis) self.assertIsNotNone(under_test.alignak_status) self.assertIsNotNone(under_test.qaction_factory)
def test_other_objects_do_not_modify_notifier(self): """Other objects do not Modify Notifier""" # TrayIcon and Dashboard for notifier tray_icon = TrayIcon(self.icon) dashboard = Dashboard() dashboard.initialize() under_test = AppNotifier() under_test.initialize(self.backend, tray_icon, dashboard) self.assertIsNotNone(under_test.tray_icon) self.assertIsNotNone(under_test.app_backend) self.assertIsNotNone(under_test.dashboard) self.assertFalse(under_test.changes) tray_icon.build_menu(self.backend, dashboard) self.assertIsNotNone(under_test.tray_icon) self.assertIsNotNone(under_test.app_backend) self.assertIsNotNone(under_test.dashboard) self.assertFalse(under_test.changes)
def test_diff_last_state(self): """Diff Last Backend SState""" self.backend = AppBackend() self.backend.login() # TrayIcon and Dashboard for notifier tray_icon_test = TrayIcon(self.icon) dashboard_test = Dashboard() notifier_test = AppNotifier() notifier_test.app_backend = self.backend notifier_test.tray_icon = tray_icon_test notifier_test.dashboard = dashboard_test # Notifier check data to get first synthesys counts notifier_test.check_data() # Get synthesis test to test diff between check synthesis = self.backend.synthesis_count() under_test = notifier_test.diff_last_states(synthesis) fields_test = { 'hosts': { 'up': 0, 'downtime': 0, 'down': 0, 'acknowledge': 0, 'unreachable': 0 }, 'services': { 'ok': 0, 'acknowledge': 0, 'unknown': 0, 'critical': 0, 'downtime': 0, 'unreachable': 0, 'warning': 0 } } self.assertTrue(under_test) self.assertTrue('hosts' in under_test) self.assertTrue('services' in under_test) for state in fields_test['hosts']: self.assertTrue(state in under_test['hosts']) self.assertTrue(isinstance(under_test['hosts'][state], int)) for state in fields_test['services']: self.assertTrue(state in under_test['services']) self.assertTrue(isinstance(under_test['services'][state], int))
def test_tray_icon(self): """Init TrayIcon and QMenu""" under_test = TrayIcon(TestTrayIcon.icon) self.assertIsInstance(under_test.menu, QMenu)
def test_update_menus_actions(self): """Update Menu QActions""" under_test = TrayIcon(TestTrayIcon.icon) dashboard_test = Dashboard() under_test.build_menu(self.backend, dashboard_test) self.assertEqual('Hosts UP, Wait...', under_test.qaction_factory.get('hosts_up').text()) self.assertEqual('Hosts DOWN, Wait...', under_test.qaction_factory.get('hosts_down').text()) self.assertEqual('Hosts UNREACHABLE, Wait...', under_test.qaction_factory.get('hosts_unreachable').text()) self.assertEqual('Services OK, Wait...', under_test.qaction_factory.get('services_ok').text()) self.assertEqual('Services WARNING, Wait...', under_test.qaction_factory.get('services_warning').text()) self.assertEqual('Services CRITICAL, Wait...', under_test.qaction_factory.get('services_critical').text()) self.assertEqual('Services UNKNOWN, Wait...', under_test.qaction_factory.get('services_unknown').text()) synthesis = { 'hosts': { 'up': 1, 'down': 2, 'unreachable': 3, 'acknowledge': 4, 'downtime': 5, }, 'services': { 'ok': 4, 'warning': 5, 'critical': 6, 'unknown': 7, 'unreachable': 8, 'acknowledge': 9, 'downtime': 10, } } under_test.update_menu_actions(synthesis) self.assertEqual('Hosts UP (1)', under_test.qaction_factory.get('hosts_up').text()) self.assertEqual('Hosts DOWN (2)', under_test.qaction_factory.get('hosts_down').text()) self.assertEqual('Hosts UNREACHABLE (3)', under_test.qaction_factory.get('hosts_unreachable').text()) self.assertEqual('Hosts ACKNOWLEDGE (4)', under_test.qaction_factory.get('hosts_acknowledge').text()) self.assertEqual('Hosts DOWNTIME (5)', under_test.qaction_factory.get('hosts_downtime').text()) self.assertEqual('Services OK (4)', under_test.qaction_factory.get('services_ok').text()) self.assertEqual('Services WARNING (5)', under_test.qaction_factory.get('services_warning').text()) self.assertEqual('Services CRITICAL (6)', under_test.qaction_factory.get('services_critical').text()) self.assertEqual('Services UNKNOWN (7)', under_test.qaction_factory.get('services_unknown').text()) self.assertEqual('Services UNREACHABLE (8)', under_test.qaction_factory.get('services_unreachable').text()) self.assertEqual('Services ACKNOWLEDGE (9)', under_test.qaction_factory.get('services_acknowledge').text()) self.assertEqual('Services DOWNTIME (10)', under_test.qaction_factory.get('services_downtime').text())
class AlignakApp(QObject): """ Class who build Alignak-app and initialize configuration, notifier and systray icon. """ reconnecting = pyqtSignal(AppBackend, str, name='reconnecting') def __init__(self, parent=None): super(AlignakApp, self).__init__(parent) self.tray_icon = None self.notifier = None self.notifier_timer = QTimer() self.reconnect_mode = False self.dashboard = None def start(self): """ The main function of Alignak-App """ # Start BannerManager bannerManager.start() # Define level of logger logger.name = 'alignak_app.app' if get_app_config('Log', 'debug', boolean=True): logger.setLevel(DEBUG) logger.info('Logger Level is: DEBUG') else: logger.setLevel(INFO) logger.info('Logger Level is: INFO') logger.info('App WorkDir = %s', get_app_workdir()) logger.info('App MainDir = %s', get_main_folder()) # If not app_backend url, stop application if get_app_config('Alignak', 'backend'): # If not username and password, create login form, else connect with config data. if not get_app_config('Alignak', 'username') and \ not get_app_config('Alignak', 'password'): # pragma: no cover - Not testable login = AppLogin() login.create_widget() if login.exec_() == QDialog.Accepted: self.run(login.app_backend) else: logger.info('Alignak-App closes...') sys.exit(0) elif get_app_config('Alignak', 'username') and \ not get_app_config('Alignak', 'password'): self.run() elif get_app_config('Alignak', 'username') and \ get_app_config('Alignak', 'password'): self.run() else: self.display_error_msg() else: self.display_error_msg() def reconnect_to_backend(self, app_backend, error): # pragma: no cover """ Set AlignakApp in reconnect mode and try to login to Backend :param app_backend: AppBackend object :type app_backend: AppBackend :param error: string error to display in banner :type error: str """ self.reconnect_mode = True logger.warning('Application reconnecting MODE: %s', self.reconnecting) send_banner('ERROR', 'Alignak Backend seems unreachable ! %s' % error, duration=5000) timer = QTimer(self) def connect_to_backend(): """Try to log in to Backend""" try: connect = app_backend.login() assert connect # If connect, reconnecting is disable timer.stop() logger.info('Connection restored : %s', connect) send_banner( 'OK', 'Connection with the Backend has been restored ! You are logged in again', duration=5000 ) self.reconnect_mode = False except AssertionError: send_banner( 'ERROR', 'Backend is still unreachable... Alignak-app try to reconnect', duration=5000 ) logger.error('Backend is still unreachable...') if timer.isActive(): pass else: timer.start(10000) timer.timeout.connect(connect_to_backend) def run(self, app_backend=None): # pragma: no cover """ Start all Alignak-app processes and create AppBackend if connection by config file. :param app_backend: AppBackend object :type app_backend: alignak_app.core.backend.AppBackend | None """ # If not login form, app try anyway to connect by token if not app_backend: app_backend = AppBackend() connect = app_backend.login() if connect: username = app_backend.get_user(projection=['name'])['name'] send_banner('OK', 'Welcome %s, you are connected to Alignak Backend' % username) else: self.display_error_msg() if 'token' not in app_backend.user: app_backend.user['token'] = app_backend.backend.token # Dashboard self.dashboard = Dashboard() self.dashboard.initialize() # TrayIcon self.tray_icon = TrayIcon(QIcon(get_image_path('icon'))) self.tray_icon.build_menu(app_backend, self.dashboard) self.tray_icon.show() app_backend.app = self start = bool(app_backend.get_user(projection=['name'])) if start: # Notifier self.notifier = AppNotifier() self.notifier.initialize(app_backend, self.tray_icon, self.dashboard) self.notifier_timer.start(self.notifier.interval) self.notifier_timer.timeout.connect(self.notifier.check_data) self.reconnecting.connect(self.reconnect_to_backend) else: # In case of... self.display_error_msg() @staticmethod def display_error_msg(): # pragma: no cover """ Display a QMessageBox error in case app fail to start """ logger.error('Something seems wrong in your configuration.' 'Please configure Alignak-app before starting it.') QMessageBox.critical( None, 'Configuration / Connection ERROR', 'Something seems wrong in your configuration.' 'Please configure Alignak-app before starting it.' ) sys.exit()