def test_emit(self, mock_generate_event, mock_format, mock_write): """Tests that emitting a message works as expected.""" # setup mocks event, message = mock.Mock(), mock.Mock() mock_generate_event.return_value = event mock_format.return_value = message # test reference = Logger("arbitrarylogger", level=Levels.INFO) # test that a message won't be emitted with an unknown level self.assertFalse(reference.emit(Level("UNKNOWN", 999), "message")) mock_generate_event.assert_not_called() mock_format.assert_not_called() mock_write.assert_not_called() # test that a message won't be emitted with a level below the set level self.assertFalse(reference.emit(Levels.DEBUG, "message")) mock_generate_event.assert_not_called() mock_format.assert_not_called() mock_write.assert_not_called() # test that a righteous logging event will get through self.assertTrue(reference.emit(Levels.INFO, "message")) mock_generate_event.assert_called_with(Levels.INFO, "message") mock_format.assert_called_with(event) mock_write.assert_called_with(message)
def test_get_timestamp(self, mock_datetime): """Tests getting the current formatted timestamp.""" mock_utcnow = mock.Mock() mock_datetime.utcnow.return_value = mock_utcnow reference = Logger("arbitrarylogger") reference.get_timestamp() mock_utcnow.strftime.assert_called_with("%Y-%m-%dT%H:%M:%SZ")
def test_generate_event(self, mock_get_timestamp): """Tests generating a logging event.""" mock_get_timestamp.return_value = "CUKE" reference = Logger("arbitraryname") expected = { 'level': "ERROR", "message": "the message", "logger": "arbitraryname", "timestamp": "CUKE" } self.assertEqual(reference.generate_event(Levels.ERROR, "the message"), expected)
def test_constructor(self): reference = Logger(name="arbitrarylogger", syslog=True, json=True, level=Levels.INFO) self.assertEqual(reference.name, "arbitrarylogger") self.assertEqual(reference.syslog, True) self.assertEqual(reference.json, True) self.assertEqual(reference.level, Levels.INFO)
def main(): """Main entry point for the script.""" parser = argparse.ArgumentParser(description="Waits for CloudFormation metadata updates and calls hooks on update.") parser.add_argument('--verbose', action="store_true", help="Emit verbose log statements.") parser.add_argument('-l', '--logging-method', type=str, choices=('stdout', 'stdout-json', 'syslog', 'syslog-json'), default="stdout", help="Configure the logging method.\nstdout and stdout-json log to standard output in " + "plaintext and JSON, respectively.\nsyslog and syslog-json log to syslog directly in plaintext and JSON, " + "respectively.") parser.add_argument('-s', '--stack-name', type=str, required=True, help="The CloudFormation logical stack name to check for updates.") parser.add_argument('-R', '--region', type=str, default='us-east-1', help="The AWS region that the CloudFormation stack is in.") parser.add_argument('-r', '--resource', type=str, required=True, help="The CloudFormation logical resource name to check for metadata updates.") parser.add_argument('-d', '--delay', type=int, default=1, help="The frequency, in minutes, of how often to check CloudFormation for updates.") # parse the arguments args = parser.parse_args() # construct the service service = CloudFormationUpdateService( stack_name=args.stack_name, resource=args.resource, region=args.region, delay_minutes=args.delay, logger=Logger( name="cfn-update-service", syslog=args.logging_method in ('syslog', 'syslog-json'), json=args.logging_method in ('stdout-json', 'syslog-json'), level=Levels.DEBUG if args.verbose else Levels.INFO ) ) # start the service try: service.start() except KeyboardInterrupt: # when a keyboard interrupt happens, just exit clean bro. pass
def test_write(self, mock_syslog, mock_print): """Test the output writing of the logger.""" # test writing to syslog reference = Logger("arbitrarylogger", syslog=True, json=False) reference.write("sample") mock_syslog.assert_called_with("sample") mock_print.assert_not_called() # reset mocks mock_syslog.reset_mock() mock_print.reset_mock() # test writing to stdout reference.syslog = False reference.write("sample") mock_syslog.assert_not_called() mock_print.assert_called_with("sample")
def test_format(self, mock_json_dumps): """Tests formatting of logging messages.""" reference = Logger("arbitrarylogger", syslog=False, json=True) event = { 'message': 'hello', 'level': Levels.INFO.name, 'logger': 'arbitrarylogger', 'timestamp': 'lolnao' } # test JSON formatting; JSON key sorting is not deterministic or weird at best reference.format(event) mock_json_dumps.assert_called_with(event) # test plaintext formatting reference.json = False self.assertEqual("lolnao [INFO ] arbitrarylogger - hello", reference.format(event))
def test_info(self, mock_emit): Logger("arbitrarylogger", Levels.TRACE).error("message") mock_emit.assert_called_with(Levels.ERROR, "message")
def test_info(self, mock_emit): Logger("arbitrarylogger", Levels.TRACE).warn("message") mock_emit.assert_called_with(Levels.WARN, "message")
def test_debug(self, mock_emit): Logger("arbitrarylogger", Levels.TRACE).debug("message") mock_emit.assert_called_with(Levels.DEBUG, "message")
def test_trace(self, mock_emit): Logger("arbitrarylogger", Levels.TRACE).trace("message") mock_emit.assert_called_with(Levels.TRACE, "message")