66import com .uid2 .operator .service .ShutdownService ;
77import com .uid2 .operator .vertx .OperatorShutdownHandler ;
88import com .uid2 .shared .attest .AttestationResponseCode ;
9- import io .vertx .core .Vertx ;
109import io .vertx .junit5 .VertxExtension ;
1110import io .vertx .junit5 .VertxTestContext ;
1211import org .junit .jupiter .api .AfterEach ;
1918import org .slf4j .LoggerFactory ;
2019import software .amazon .awssdk .utils .Pair ;
2120
22- import java .security .Permission ;
2321import java .time .Clock ;
2422import java .time .Duration ;
2523import java .time .Instant ;
@@ -43,7 +41,7 @@ void beforeEach() {
4341 mocks = MockitoAnnotations .openMocks (this );
4442 when (clock .instant ()).thenAnswer (i -> Instant .now ());
4543 doThrow (new RuntimeException ()).when (shutdownService ).Shutdown (1 );
46- this .operatorShutdownHandler = new OperatorShutdownHandler (Duration .ofHours (12 ), Duration .ofHours (12 ), Duration .ofHours (168 ), clock , shutdownService );
44+ this .operatorShutdownHandler = new OperatorShutdownHandler (Duration .ofHours (12 ), Duration .ofHours (12 ), Duration .ofHours (168 ), Duration . ofMinutes ( 15 ), clock , shutdownService );
4745 }
4846
4947 @ AfterEach
@@ -62,7 +60,6 @@ void shutdownOnAttestFailure(VertxTestContext testContext) {
6260 this .operatorShutdownHandler .handleAttestResponse (Pair .of (AttestationResponseCode .AttestationFailure , "Unauthorized" ));
6361 } catch (RuntimeException e ) {
6462 verify (shutdownService ).Shutdown (1 );
65- String message = logWatcher .list .get (0 ).getFormattedMessage ();
6663 Assertions .assertEquals ("core attestation failed with AttestationFailure, shutting down operator, core response: Unauthorized" , logWatcher .list .get (0 ).getFormattedMessage ());
6764 testContext .completeNow ();
6865 }
@@ -236,4 +233,55 @@ void keysetKeyLogProgressAtInterval(VertxTestContext testContext) {
236233
237234 testContext .completeNow ();
238235 }
236+
237+ @ Test
238+ void shutdownWhenNoActiveKeys (VertxTestContext testContext ) {
239+ ListAppender <ILoggingEvent > logWatcher = new ListAppender <>();
240+ logWatcher .start ();
241+ ((Logger ) LoggerFactory .getLogger (OperatorShutdownHandler .class )).addAppender (logWatcher );
242+
243+ // No active keys available
244+ this .operatorShutdownHandler .handleKeyAvailability (false );
245+ Assertions .assertTrue (logWatcher .list .get (0 ).getFormattedMessage ().contains ("No active keys available" ));
246+
247+ when (clock .instant ()).thenAnswer (i -> Instant .now ().plus (15 , ChronoUnit .MINUTES ).plusSeconds (60 ));
248+ try {
249+ this .operatorShutdownHandler .handleKeyAvailability (false );
250+ } catch (RuntimeException e ) {
251+ verify (shutdownService ).Shutdown (1 );
252+ Assertions .assertTrue (logWatcher .list .stream ().anyMatch (log ->
253+ log .getFormattedMessage ().contains ("No active keys for too long" )));
254+ testContext .completeNow ();
255+ }
256+ }
257+
258+ @ Test
259+ void recoverWhenActiveKeysBecomesAvailable (VertxTestContext testContext ) {
260+ // Start with no active keys
261+ this .operatorShutdownHandler .handleKeyAvailability (false );
262+ when (clock .instant ()).thenAnswer (i -> Instant .now ().plus (10 , ChronoUnit .MINUTES ));
263+
264+ // Keys become available
265+ this .operatorShutdownHandler .handleKeyAvailability (true );
266+
267+ // Should not shutdown even after total time exceeds threshold
268+ when (clock .instant ()).thenAnswer (i -> Instant .now ().plus (20 , ChronoUnit .MINUTES ));
269+ assertDoesNotThrow (() -> {
270+ this .operatorShutdownHandler .handleKeyAvailability (false );
271+ });
272+ verify (shutdownService , never ()).Shutdown (anyInt ());
273+ testContext .completeNow ();
274+ }
275+
276+ @ Test
277+ void keyAvailabilityNoShutdownWhenAlwaysAvailable (VertxTestContext testContext ) {
278+ // Keys are always available
279+ this .operatorShutdownHandler .handleKeyAvailability (true );
280+ this .operatorShutdownHandler .handleKeyAvailability (true );
281+ this .operatorShutdownHandler .handleKeyAvailability (true );
282+
283+ verify (shutdownService , never ()).Shutdown (anyInt ());
284+ testContext .completeNow ();
285+ }
286+
239287}
0 commit comments