@@ -3,6 +3,7 @@ package configmgr
33import (
44 "context"
55 "encoding/json"
6+ "fmt"
67 "log/slog"
78 "net/http"
89 "net/http/httptest"
@@ -107,15 +108,32 @@ func TestFleetConfigManager_Start_ConnectError(t *testing.T) {
107108 // Arrange
108109 logger := slog .New (slog .NewTextHandler (os .Stderr , & slog.HandlerOptions {Level : slog .LevelError }))
109110 mockPMgr := & mockPolicyManagerForFleet {}
110- fleetManager := newFleetConfigManager (logger , mockPMgr , & mockBackendState {})
111+
112+ // Create mock MQTT connection that returns a connection error immediately
113+ mockConn := & fleet.MockMQTTConnection {
114+ ConnectError : fmt .Errorf ("mqtt connection failed: invalid URL" ),
115+ }
116+ fleetManager := newFleetConfigManagerWithConnection (logger , mockPMgr , & mockBackendState {}, mockConn )
111117
112118 // Create mock HTTP server for token endpoint
119+ // Use a valid JWT token so parsing succeeds and we reach the connection step
120+ validJWT := fleet .RawJWTWithClaims (map [string ]any {
121+ "orb:org_id" : "test-org" ,
122+ "orb:zone" : "default" ,
123+ "orb:agent_id" : "test-agent" ,
124+ "client_id" : "test-client" ,
125+ "iat" : 1516239022 ,
126+ "ext" : map [string ]any {
127+ "orb:mqtt_url" : "mqtt://test.example.com:1883" ,
128+ },
129+ })
113130 server := httptest .NewTLSServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
114131 response := fleet.TokenResponse {
115- AccessToken : "test_access_token" ,
116- MQTTURL : "://invalid-mqtt-url" , // Invalid MQTT URL
132+ AccessToken : validJWT ,
133+ MQTTURL : "mqtt ://test.example.com:1883" ,
117134 ExpiresIn : 3600 ,
118135 }
136+ w .Header ().Set ("Content-Type" , "application/json" )
119137 _ = json .NewEncoder (w ).Encode (response )
120138 }))
121139 defer server .Close ()
@@ -126,6 +144,7 @@ func TestFleetConfigManager_Start_ConnectError(t *testing.T) {
126144 Sources : config.Sources {
127145 Fleet : config.FleetManager {
128146 TokenURL : server .URL ,
147+ SkipTLS : true , // Skip TLS verification for test server
129148 ClientID : "test_client" ,
130149 ClientSecret : "test_secret" ,
131150 },
@@ -141,6 +160,8 @@ func TestFleetConfigManager_Start_ConnectError(t *testing.T) {
141160
142161 // Assert
143162 assert .Error (t , err )
163+ // Verify the error is from the mock connection (no 30s wait)
164+ assert .Contains (t , err .Error (), "mqtt connection failed" )
144165}
145166
146167func TestFleetConfigManager_GetContext (t * testing.T ) {
@@ -182,7 +203,12 @@ func TestFleetConfigManager_Start_WithJWTTopicGeneration(t *testing.T) {
182203
183204 logger := slog .New (slog .NewTextHandler (os .Stderr , & slog.HandlerOptions {Level : slog .LevelDebug }))
184205 mockPMgr := & mockPolicyManagerForFleet {}
185- fleetManager := newFleetConfigManager (logger , mockPMgr , & mockBackendState {})
206+
207+ // Create mock MQTT connection that returns a connection error
208+ mockConn := & fleet.MockMQTTConnection {
209+ ConnectError : fmt .Errorf ("mqtt connection failed: connection refused" ),
210+ }
211+ fleetManager := newFleetConfigManagerWithConnection (logger , mockPMgr , & mockBackendState {}, mockConn )
186212
187213 // Create mock HTTP server that returns a JWT token
188214 server := httptest .NewTLSServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
@@ -216,22 +242,19 @@ func TestFleetConfigManager_Start_WithJWTTopicGeneration(t *testing.T) {
216242 // Mock backends
217243 backends := make (map [string ]backend.Backend )
218244
219- // Since we can't easily mock the MQTT connection in this test,
220- // we expect the Start method to fail at the MQTT connection step,
221- // but succeed in generating topics from JWT claims
245+ // The Start method should succeed in generating topics from JWT claims,
246+ // but fail at the MQTT connection step (which is mocked to return an error)
222247 err := fleetManager .Start (cfg , backends )
223248
224- // We expect an error because we can't actually connect to MQTT ,
249+ // We expect an error because the mock connection returns an error ,
225250 // but we want to verify that topic generation succeeded
226251 // (The error should be related to MQTT connection, not JWT parsing)
227252 require .Error (t , err )
228- // The error could be connection-related (mqtt, tcp, timeout, etc.)
253+ // The error should be the mocked connection error
229254 errorMsg := strings .ToLower (err .Error ())
230255 assert .True (t ,
231256 strings .Contains (errorMsg , "mqtt" ) ||
232- strings .Contains (errorMsg , "connection" ) ||
233- strings .Contains (errorMsg , "timeout" ) ||
234- strings .Contains (errorMsg , "deadline" ),
257+ strings .Contains (errorMsg , "connection" ),
235258 "Expected connection-related error, got: %s" , err .Error ())
236259}
237260
@@ -386,7 +409,7 @@ func TestFleetConfigManager_MonitorTokenExpiry_Configuration(t *testing.T) {
386409 select {
387410 case <- done :
388411 // Monitor stopped successfully
389- case <- time .After (1 * time .Second ):
412+ case <- time .After (100 * time .Millisecond ):
390413 t .Fatal ("monitor did not stop within timeout" )
391414 }
392415}
@@ -434,7 +457,7 @@ func TestFleetConfigManager_MonitorTokenExpiry_CustomConfiguration(t *testing.T)
434457 select {
435458 case <- done :
436459 // Monitor stopped successfully
437- case <- time .After (1 * time .Second ):
460+ case <- time .After (100 * time .Millisecond ):
438461 t .Fatal ("monitor did not stop within timeout" )
439462 }
440463}
@@ -467,7 +490,7 @@ func TestFleetConfigManager_Stop_CancelsMonitor(t *testing.T) {
467490 select {
468491 case <- fleetManager .monitorCtx .Done ():
469492 // Good, context is cancelled
470- case <- time .After (100 * time .Millisecond ):
493+ case <- time .After (50 * time .Millisecond ):
471494 t .Fatal ("monitor context should be cancelled after Stop()" )
472495 }
473496}
@@ -572,10 +595,11 @@ func TestFleetConfigManager_MonitorTokenExpiry_DetectsExpiredToken(t *testing.T)
572595 }()
573596
574597 // Wait for monitor to detect expired token
598+ // Allow at least one ticker interval (100ms) plus buffer
575599 select {
576600 case <- done :
577601 // Monitor detected expired token
578- case <- time .After (500 * time .Millisecond ):
602+ case <- time .After (200 * time .Millisecond ):
579603 t .Fatal ("monitor did not detect expired token within timeout" )
580604 }
581605
@@ -670,10 +694,11 @@ func TestFleetConfigManager_MonitorTokenExpiry_DetectsExpiringSoonToken(t *testi
670694 }()
671695
672696 // Wait for monitor to detect expiring token
697+ // Allow at least one ticker interval (100ms) plus buffer
673698 select {
674699 case <- done :
675700 // Monitor detected expiring token
676- case <- time .After (500 * time .Millisecond ):
701+ case <- time .After (200 * time .Millisecond ):
677702 t .Fatal ("monitor did not detect expiring token within timeout" )
678703 }
679704
0 commit comments