test_handler_multi.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import pytest
  2. from redmail import EmailSender
  3. from redmail import MultiEmailHandler
  4. import logging
  5. from convert import payloads_to_dict
  6. def _create_dummy_send(messages:list):
  7. def _dummy_send(msg):
  8. messages.append(msg)
  9. return _dummy_send
  10. def test_default_body():
  11. hdlr = MultiEmailHandler(host="localhost", port=0, receivers=["me@example.com"], subject="Some logging")
  12. # By default, this should be body if text/html/html_template/text_template not specified
  13. assert hdlr.email.text == MultiEmailHandler.default_text
  14. @pytest.mark.parametrize("kwargs,exp_headers,exp_payload",
  15. [
  16. pytest.param(
  17. {
  18. "email": EmailSender(host="localhost", port=0),
  19. "subject": "A log record",
  20. "sender": "me@example.com",
  21. "receivers": ["he@example.com", "she@example.com"],
  22. },
  23. {
  24. "from": "me@example.com",
  25. "to": "he@example.com, she@example.com",
  26. "subject": "A log record",
  27. 'Content-Transfer-Encoding': '7bit',
  28. 'Content-Type': 'text/plain; charset="utf-8"',
  29. 'MIME-Version': '1.0',
  30. },
  31. {
  32. 'text/plain': 'Log Recods:\na message\n'
  33. },
  34. id="Minimal",
  35. ),
  36. pytest.param(
  37. {
  38. "email": EmailSender(host="localhost", port=0),
  39. "subject": "A log record",
  40. "sender": "me@example.com",
  41. "receivers": ["he@example.com", "she@example.com"],
  42. "text": "The records: \n{% for msg in msgs %}Log: {{ msg }}{% endfor %}",
  43. "fmt": '%(name)s - %(levelname)s - %(message)s'
  44. },
  45. {
  46. "from": "me@example.com",
  47. "to": "he@example.com, she@example.com",
  48. "subject": "A log record",
  49. 'Content-Transfer-Encoding': '7bit',
  50. 'Content-Type': 'text/plain; charset="utf-8"',
  51. 'MIME-Version': '1.0',
  52. },
  53. {
  54. 'text/plain': 'The records: \nLog: _test - INFO - a message\n'
  55. },
  56. id="Custom message (msgs)",
  57. ),
  58. pytest.param(
  59. {
  60. "email": EmailSender(host="localhost", port=0),
  61. "subject": "A log record",
  62. "sender": "me@example.com",
  63. "receivers": ["he@example.com", "she@example.com"],
  64. "text": "The records: \n{% for rec in records %}Log: {{ rec.levelname }} - {{ rec.message }}{% endfor %}",
  65. "fmt": '%(name)s - %(levelname)s - %(message)s'
  66. },
  67. {
  68. "from": "me@example.com",
  69. "to": "he@example.com, she@example.com",
  70. "subject": "A log record",
  71. 'Content-Transfer-Encoding': '7bit',
  72. 'Content-Type': 'text/plain; charset="utf-8"',
  73. 'MIME-Version': '1.0',
  74. },
  75. {
  76. 'text/plain': 'The records: \nLog: INFO - a message\n',
  77. },
  78. id="Custom message (records)",
  79. ),
  80. pytest.param(
  81. {
  82. "email": EmailSender(host="localhost", port=0),
  83. "subject": "Logs: {min_level_name} - {max_level_name}",
  84. "sender": "me@example.com",
  85. "receivers": ["he@example.com", "she@example.com"],
  86. },
  87. {
  88. "from": "me@example.com",
  89. "to": "he@example.com, she@example.com",
  90. "subject": "Logs: INFO - INFO",
  91. 'Content-Transfer-Encoding': '7bit',
  92. 'Content-Type': 'text/plain; charset="utf-8"',
  93. 'MIME-Version': '1.0',
  94. },
  95. {
  96. 'text/plain': 'Log Recods:\na message\n',
  97. },
  98. id="Sender with fomatted subject",
  99. ),
  100. pytest.param(
  101. {
  102. "email": EmailSender(host="localhost", port=0),
  103. "subject": "A log record",
  104. "sender": "me@example.com",
  105. "receivers": ["he@example.com", "she@example.com"],
  106. "fmt": '%(name)s - %(levelname)s - %(message)s',
  107. "html": "<h1>The records:</h1><p>{% for msg in msgs %}Log: {{ msg }}{% endfor %}</p>"
  108. },
  109. {
  110. "from": "me@example.com",
  111. "to": "he@example.com, she@example.com",
  112. "subject": "A log record",
  113. 'Content-Type': 'multipart/mixed',
  114. },
  115. {
  116. 'multipart/mixed': {
  117. 'multipart/alternative': {
  118. 'text/html': "<h1>The records:</h1><p>Log: _test - INFO - a message</p>\n",
  119. }
  120. }
  121. },
  122. id="Custom message (HTML, msgs)",
  123. ),
  124. pytest.param(
  125. {
  126. "email": EmailSender(host="localhost", port=0),
  127. "subject": "A log record",
  128. "sender": "me@example.com",
  129. "receivers": ["he@example.com", "she@example.com"],
  130. "fmt": '%(name)s: %(levelname)s: %(message)s',
  131. "html": "<h1>The records:</h1><p>{% for rec in records %}Log: {{ rec.levelname }} - {{ rec.message }}{% endfor %}</p>"
  132. },
  133. {
  134. "from": "me@example.com",
  135. "to": "he@example.com, she@example.com",
  136. "subject": "A log record",
  137. 'Content-Type': 'multipart/mixed',
  138. },
  139. {
  140. 'multipart/mixed': {
  141. 'multipart/alternative': {
  142. 'text/html': "<h1>The records:</h1><p>Log: INFO - a message</p>\n",
  143. }
  144. }
  145. },
  146. id="Custom message (HTML, records)",
  147. ),
  148. ]
  149. )
  150. def test_emit(logger, kwargs, exp_headers, exp_payload):
  151. msgs = []
  152. fmt = kwargs.pop("fmt", None)
  153. hdlr = MultiEmailHandler(**kwargs)
  154. hdlr.formatter = logging.Formatter(fmt)
  155. hdlr.email.send_message = _create_dummy_send(msgs)
  156. logger.addHandler(hdlr)
  157. logger.setLevel(logging.INFO)
  158. logger.info("a message")
  159. hdlr.flush()
  160. assert len(msgs) == 1
  161. msg = msgs[0]
  162. headers = dict(msg.items())
  163. payload = msg.get_payload()
  164. assert headers == exp_headers
  165. structure = payloads_to_dict(msg)
  166. assert structure == exp_payload
  167. def test_flush_multiple(logger):
  168. msgs = []
  169. hdlr = MultiEmailHandler(
  170. email=EmailSender(host="localhost", port=0),
  171. subject="Logs: {min_level_name} - {max_level_name}",
  172. receivers=["he@example.com", "she@example.com"],
  173. text="Records: \n{% for rec in records %}{{ rec.levelname }} - {{ rec.message }}\n{% endfor %}"
  174. )
  175. hdlr.email.send_message = _create_dummy_send(msgs)
  176. logger.addHandler(hdlr)
  177. logger.setLevel(logging.DEBUG)
  178. logger.info("an info")
  179. logger.debug("a debug")
  180. hdlr.flush()
  181. assert len(msgs) == 1
  182. msg = msgs[0]
  183. headers = dict(msg.items())
  184. text = msg.get_payload()
  185. assert headers == {
  186. "from": "None",
  187. "to": "he@example.com, she@example.com",
  188. "subject": "Logs: DEBUG - INFO",
  189. 'Content-Transfer-Encoding': '7bit',
  190. 'Content-Type': 'text/plain; charset="utf-8"',
  191. 'MIME-Version': '1.0',
  192. }
  193. assert text == "Records: \nINFO - an info\nDEBUG - a debug\n"
  194. def test_flush_none():
  195. msgs = []
  196. hdlr = MultiEmailHandler(
  197. email=EmailSender(host="localhost", port=0),
  198. subject="Logs: {min_level_name} - {max_level_name}",
  199. receivers=["he@example.com", "she@example.com"],
  200. text="Records: \n{% for rec in records %}{{ rec.levelname }} - {{ rec.message }}\n{% endfor %}"
  201. )
  202. hdlr.email.send_message = _create_dummy_send(msgs)
  203. logger = logging.getLogger("_test")
  204. logger.addHandler(hdlr)
  205. logger.setLevel(logging.DEBUG)
  206. hdlr.flush()
  207. assert len(msgs) == 1
  208. msg = msgs[0]
  209. headers = dict(msg.items())
  210. text = msg.get_payload()
  211. assert headers == {
  212. "from": "None",
  213. "to": "he@example.com, she@example.com",
  214. "subject": "Logs: NOTSET - NOTSET",
  215. 'Content-Transfer-Encoding': '7bit',
  216. 'Content-Type': 'text/plain; charset="utf-8"',
  217. 'MIME-Version': '1.0',
  218. }
  219. assert text == "Records: \n"