|
| 1 | +import logging |
1 | 2 | import unittest
|
| 3 | +import unittest.mock |
2 | 4 |
|
3 |
| -from influxdb_client import InfluxLoggingHandler |
| 5 | +import urllib3 |
4 | 6 |
|
| 7 | +from influxdb_client import InfluxLoggingHandler, InfluxDBClient, WriteApi, WritePrecision, Point |
5 | 8 |
|
6 |
| -class LoggingHandlerTest(unittest.TestCase): |
7 |
| - def test_imports(self): |
8 |
| - handler = InfluxLoggingHandler() |
9 |
| - self.assertIsNotNone(handler) |
| 9 | + |
| 10 | +class LoggingBaseTestCase(unittest.TestCase): |
| 11 | + fake_line_record = "tag,field=value 123456" |
| 12 | + URL_TOKEN_ORG = { |
| 13 | + 'url': 'http://example.com', |
| 14 | + 'token': 'my-token', |
| 15 | + 'org': 'my-org', |
| 16 | + } |
| 17 | + BUCKET = 'my-bucket' |
| 18 | + |
| 19 | + def setUp(self) -> None: |
| 20 | + self.mock_InfluxDBClient = unittest.mock.patch("influxdb_client.client.loggingHandler.InfluxDBClient").start() |
| 21 | + self.mock_client = unittest.mock.MagicMock(spec=InfluxDBClient) |
| 22 | + self.mock_write_api = unittest.mock.MagicMock(spec=WriteApi) |
| 23 | + self.mock_client.write_api.return_value = self.mock_write_api |
| 24 | + self.mock_InfluxDBClient.return_value = self.mock_client |
| 25 | + |
| 26 | + def gen_handler_and_logger(self): |
| 27 | + self.handler = InfluxLoggingHandler(**self.URL_TOKEN_ORG, bucket=self.BUCKET) |
| 28 | + self.handler.setLevel(logging.DEBUG) |
| 29 | + |
| 30 | + self.logger = logging.getLogger("test-logger") |
| 31 | + self.logger.setLevel(logging.DEBUG) |
| 32 | + |
| 33 | + def tearDown(self) -> None: |
| 34 | + unittest.mock.patch.stopall() |
| 35 | + |
| 36 | + |
| 37 | +class TestHandlerCreation(LoggingBaseTestCase): |
| 38 | + def test_can_create_handler(self): |
| 39 | + self.handler = InfluxLoggingHandler(**self.URL_TOKEN_ORG, bucket=self.BUCKET) |
| 40 | + self.mock_InfluxDBClient.assert_called_once_with(**self.URL_TOKEN_ORG) |
| 41 | + self.assertEqual(self.BUCKET, self.handler.bucket) |
| 42 | + self.mock_client.write_api.assert_called_once_with() |
| 43 | + |
| 44 | + def test_can_create_handler_with_optional_args_for_client(self): |
| 45 | + self.handler = InfluxLoggingHandler(**self.URL_TOKEN_ORG, bucket=self.BUCKET, |
| 46 | + client_args={'arg2': 2.90, 'optArg': 'whot'}) |
| 47 | + self.mock_InfluxDBClient.assert_called_once_with(**self.URL_TOKEN_ORG, arg2=2.90, optArg="whot") |
| 48 | + self.mock_client.write_api.assert_called_once_with() |
| 49 | + |
| 50 | + def test_can_create_handler_with_args_for_write_api(self): |
| 51 | + self.handler = InfluxLoggingHandler(**self.URL_TOKEN_ORG, bucket=self.BUCKET, |
| 52 | + client_args={'arg2': 2.90, 'optArg': 'whot'}, |
| 53 | + write_api_args={'foo': 'bar'}) |
| 54 | + self.mock_InfluxDBClient.assert_called_once_with(**self.URL_TOKEN_ORG, arg2=2.90, optArg="whot") |
| 55 | + self.mock_client.write_api.assert_called_once_with(foo='bar') |
| 56 | + |
| 57 | + |
| 58 | +class CreatedHandlerTestCase(LoggingBaseTestCase): |
| 59 | + def setUp(self) -> None: |
| 60 | + super().setUp() |
| 61 | + self.gen_handler_and_logger() |
| 62 | + |
| 63 | + |
| 64 | +class LoggingSetupAndTearDown(CreatedHandlerTestCase): |
| 65 | + def test_is_handler(self): |
| 66 | + self.assertIsInstance(self.handler, logging.Handler) |
| 67 | + |
| 68 | + def test_set_up_client(self): |
| 69 | + self.mock_InfluxDBClient.assert_called_once() |
| 70 | + |
| 71 | + def test_closes_connections_on_close(self): |
| 72 | + self.handler.close() |
| 73 | + self.mock_write_api.close.assert_called_once() |
| 74 | + self.mock_client.close.assert_called_once() |
| 75 | + |
| 76 | + def test_handler_can_be_attached_to_logger(self): |
| 77 | + self.logger.addHandler(self.handler) |
| 78 | + self.assertTrue(self.logger.hasHandlers()) |
| 79 | + self.assertTrue(self.handler in self.logger.handlers) |
| 80 | + |
| 81 | + |
| 82 | +class LoggingWithAttachedHandler(CreatedHandlerTestCase): |
| 83 | + |
| 84 | + def setUp(self) -> None: |
| 85 | + super().setUp() |
| 86 | + self.logger.addHandler(self.handler) |
| 87 | + |
| 88 | + |
| 89 | +class LoggingHandlerTest(LoggingWithAttachedHandler): |
| 90 | + |
| 91 | + def test_can_log_str(self): |
| 92 | + self.logger.debug(self.fake_line_record) |
| 93 | + self.mock_write_api.write.assert_called_once_with(bucket="my-bucket", record=self.fake_line_record) |
| 94 | + |
| 95 | + def test_can_log_points(self): |
| 96 | + point = Point("measurement").field("field_name", "field_value").time(333, WritePrecision.NS) |
| 97 | + self.logger.debug(point) |
| 98 | + self.mock_write_api.write.assert_called_once_with(bucket="my-bucket", record=point) |
| 99 | + |
| 100 | + def test_catches_urllib_exceptions(self): |
| 101 | + self.mock_write_api.write.side_effect = urllib3.exceptions.HTTPError() |
| 102 | + try: |
| 103 | + with unittest.mock.patch("logging.sys.stderr") as _: |
| 104 | + # Handler writes logging errors to stderr. Don't display it in the test output. |
| 105 | + self.logger.debug(self.fake_line_record) |
| 106 | + finally: |
| 107 | + self.mock_write_api.write.side_effect = None |
| 108 | + |
| 109 | + def test_raises_on_exit(self): |
| 110 | + try: |
| 111 | + self.mock_write_api.write.side_effect = KeyboardInterrupt() |
| 112 | + self.assertRaises(KeyboardInterrupt, self.logger.debug, self.fake_line_record) |
| 113 | + self.mock_write_api.write.side_effect = SystemExit() |
| 114 | + self.assertRaises(SystemExit, self.logger.debug, self.fake_line_record) |
| 115 | + finally: |
| 116 | + self.mock_write_api.write.side_effect = None |
| 117 | + |
| 118 | + def test_can_set_bucket(self): |
| 119 | + self.handler.bucket = "new-bucket" |
| 120 | + self.logger.debug(self.fake_line_record) |
| 121 | + self.mock_write_api.write.assert_called_once_with(bucket="new-bucket", record=self.fake_line_record) |
| 122 | + |
| 123 | + def test_can_pass_bucket_on_log(self): |
| 124 | + self.logger.debug(self.fake_line_record, extra={'bucket': "other-bucket"}) |
| 125 | + self.mock_write_api.write.assert_called_once_with(bucket="other-bucket", record=self.fake_line_record) |
| 126 | + |
| 127 | + def test_can_pass_optional_params_on_log(self): |
| 128 | + self.logger.debug(self.fake_line_record, extra={'org': "other-org", 'write_precision': WritePrecision.S, |
| 129 | + "arg3": 3, "arg2": "two"}) |
| 130 | + self.mock_write_api.write.assert_called_once_with(bucket="my-bucket", org='other-org', |
| 131 | + record=self.fake_line_record, |
| 132 | + write_precision=WritePrecision.S, |
| 133 | + arg3=3, arg2="two") |
| 134 | + |
| 135 | + |
| 136 | +if __name__ == "__main__": |
| 137 | + unittest.main() |
0 commit comments