11import asyncio
22import logging
3- from unittest import TestCase
3+ import unittest
4+ from unittest import TestCase , skip
45
56from mqlog import MqttHandler
67from tests .utils import AsyncMock , Mock , call
910class FakeClient :
1011 """A fake MQTT client for testing purposes."""
1112
12- publish : None
13+ def __init__ (self ):
14+ self .publish = AsyncMock ()
15+ self .up = asyncio .Event ()
1316
1417
1518class TestMqttHandler (TestCase ):
1619 def setUp (self ):
1720 self .client = FakeClient ()
18- self .client .publish = AsyncMock ()
1921 self .handler = MqttHandler (self .client , "test_topic" )
20- self .handler .setFormatter (logging .Formatter ("%(message)s" ))
2122 self .logger = logging .getLogger ("test" )
2223 self .logger .addHandler (self .handler )
2324 self .logger .setLevel (logging .INFO )
25+ self .client .up .set () # Simulate client being ready
2426
2527 def tearDown (self ):
2628 """Clean up after each test"""
2729 self .handler .buffer .clear ()
2830 self .handler .will_flush .clear ()
31+ self .client .up .clear ()
2932
3033 def test_default_formatter (self ):
3134 """Handler should use default formatter if none is set"""
@@ -54,7 +57,7 @@ def test_flush_full_buffer(self):
5457 def test_flush_fail (self ):
5558 """Flushing should log an error if publish fails"""
5659 self .handler ._logger .error = Mock ()
57- self .client .publish = AsyncMock ( side_effect = Exception ("Publish failed" ) )
60+ self .client .publish . side_effect = Exception ("Publish failed" )
5861
5962 async def do_test (handler : logging .Handler , logger : logging .Logger ):
6063 asyncio .create_task (handler .run ())
@@ -81,7 +84,7 @@ async def do_test(handler: logging.Handler, logger: logging.Logger):
8184 asyncio .run (do_test (self .handler , self .logger ))
8285
8386 self .client .publish .assert_called_with (
84- "test_topic" , "Test message 1\n Test message 2" , qos = 0
87+ "test_topic" , "INFO:test: Test message 1\n ERROR:test:Test message 2" , qos = 0
8588 )
8689
8790 def test_flush_multiple (self ):
@@ -104,15 +107,23 @@ async def do_test(handler: logging.Handler, logger: logging.Logger):
104107
105108 self .client .publish .assert_has_calls (
106109 [
107- call ("test_topic" , "Test message 1\n Test message 2" , qos = 0 ),
108- call ("test_topic" , "Test message 3\n Test message 4" , qos = 0 ),
110+ call (
111+ "test_topic" ,
112+ "INFO:test:Test message 1\n INFO:test:Test message 2" ,
113+ qos = 0 ,
114+ ),
115+ call (
116+ "test_topic" ,
117+ "INFO:test:Test message 3\n INFO:test:Test message 4" ,
118+ qos = 0 ,
119+ ),
109120 ]
110121 )
111122
112123 def test_buffer_overflow (self ):
113124 """Buffer should get truncated if it exceeds capacity"""
114125 self .handler .capacity = 3
115- self .client .publish = AsyncMock ( side_effect = Exception ( "Publish failed" ))
126+ self .client .up . clear () # Simulate client being disconnected
116127
117128 async def do_test (handler : logging .Handler , logger : logging .Logger ):
118129 asyncio .create_task (handler .run ())
@@ -129,5 +140,36 @@ async def do_test(handler: logging.Handler, logger: logging.Logger):
129140 asyncio .run (do_test (self .handler , self .logger ))
130141
131142 self .assertEqual (
132- self .handler .buffer , ["Test message 2" , "Test message 3" , "Test message 4" ]
143+ self .handler .buffer ,
144+ [
145+ "INFO:test:Test message 2" ,
146+ "INFO:test:Test message 3" ,
147+ "INFO:test:Test message 4" ,
148+ ],
149+ )
150+
151+ def test_reconnect (self ):
152+ """Handler should reconnect and publish messages after a disconnect"""
153+ self .client .up .clear () # Simulate client being disconnected
154+
155+ async def do_test (
156+ handler : logging .Handler , logger : logging .Logger , client : FakeClient
157+ ):
158+ asyncio .create_task (handler .run ())
159+ await asyncio .sleep (0.1 )
160+ logger .error ("Test message 1" )
161+ await asyncio .sleep (0.1 )
162+
163+ # Simulate reconnect
164+ client .up .set ()
165+ await asyncio .sleep (0.1 )
166+
167+ asyncio .run (do_test (self .handler , self .logger , self .client ))
168+
169+ self .client .publish .assert_called_with (
170+ "test_topic" , "ERROR:test:Test message 1" , qos = 0
133171 )
172+
173+
174+ if __name__ == "__main__" :
175+ unittest .main ()
0 commit comments