def test_post_disabled(self, mock_post): """Test for `post` method, case: Slack disabled""" slack = Slack() slack.logger = mock.MagicMock() slack.post("This is a test!") mock_post.assert_not_called() slack.logger.warning.assert_has_calls( [mock.call("Slack request ignored (disabled in settings).")])
def test_post_enabled_custom_channel(self, mock_post): """Test for `post` method, case: Slack enabled, custom channel""" slack = Slack() slack.logger = mock.MagicMock() slack.post("This is a test!", channel="dev") mock_post.assert_called_once_with( "https://fake-chat.slack.com/services/hooks/slackbot?" "token=sLaCkTokEn&channel=%23dev", data=force_bytes("This is a test!"), timeout=7, )
def test_post_failed(self, mock_post): """Test for `post` method, case: Slack enabled, request failed""" slack = Slack() slack.logger = mock.MagicMock() slack.post("This is a test!") mock_post.assert_called_once_with( "https://fake-chat.slack.com/services/hooks/slackbot?" "token=sLaCkTokEn&channel=%23cronitor", data=force_bytes("This is a test!"), timeout=7, ) slack.logger.error.assert_has_calls( [mock.call("Slack request failed: ConnectTimeout: msg")])
class SignalNotifier(object): """Class responsible for sending notifications when SIGINT / SIGTERM is received. """ signal_names = ((signal.SIGINT, "SIGINT"), (signal.SIGTERM, "SIGTERM")) def __init__(self, job_name): self.job_name = job_name self.logger = logger self.slack = Slack() self.previous_int_handler = signal.getsignal(signal.SIGINT) self.previous_term_handler = signal.getsignal(signal.SIGTERM) def notify_and_quit(self, signum, frame): """Handles a signal by sending notification and quitting""" message = 'Cron job "{}" killed by {}.'.format( self.job_name, dict(self.signal_names).get(signum, signum)) self.logger.warning(message) self.slack.post(message) sys.exit(signum) def capture(self): """Assigns handlers to signals""" self.previous_int_handler = signal.signal(signal.SIGINT, self.notify_and_quit) self.previous_term_handler = signal.signal(signal.SIGTERM, self.notify_and_quit) def reset(self): """Restores previous signal handlers""" signal.signal(signal.SIGINT, self.previous_int_handler) signal.signal(signal.SIGTERM, self.previous_term_handler) def __enter__(self): self.capture() return self def __exit__(self, *args, **kwargs): self.reset()
class BaseCronObject(object): """Common base class for CronRemoteManager, CronScheduler, CronSpawner, CronWorker. """ def __init__(self, **kwargs): self.data_dir = kwargs.get("data_dir", config("CRONMAN_DATA_DIR")) self.debug = kwargs.get("debug", bool_param(config("CRONMAN_DEBUG"))) self.cronitor = Cronitor() self.sentry = Sentry() self.slack = Slack() ensure_dir(self.data_dir) self.logger = kwargs.get("logger", logger) def warning(self, exception, silent=False): """Handles exception as warning""" message = format_exception(exception) if not silent: self.logger.warning(message) system_name = platform.node() self.slack.post("[{host}] {message}".format(host=system_name, message=message)) return message + "\n" # to be printed on stdout