@@ -261,6 +261,59 @@ public void certAndKeyFileUpdateOnly()
261261 verifyTimeServiceAndScheduledFuture ();
262262 }
263263
264+ @ Test
265+ public void certFileUpdateOnly ()
266+ throws IOException , CertificateException , InterruptedException {
267+ TestScheduledFuture <?> scheduledFuture =
268+ new TestScheduledFuture <>();
269+ doReturn (scheduledFuture )
270+ .when (timeService )
271+ .schedule (any (Runnable .class ), any (Long .TYPE ), eq (TimeUnit .SECONDS ));
272+ // Ideally we'd use a matching cert/key pair here, but we don't actually have any ready-made.
273+ // The test doesn't notice they don't match though.
274+ populateTarget (
275+ CLIENT_PEM_FILE , SERVER_0_KEY_FILE , CA_PEM_FILE , null , false , false , false , false );
276+ provider .checkAndReloadCertificates ();
277+
278+ reset (mockWatcher , timeService );
279+ doReturn (scheduledFuture )
280+ .when (timeService )
281+ .schedule (any (Runnable .class ), any (Long .TYPE ), eq (TimeUnit .SECONDS ));
282+ timeProvider .forwardTime (1 , TimeUnit .SECONDS );
283+ // It's normal to get a newer cert while continuing to use the same private key
284+ populateTarget (SERVER_0_PEM_FILE , null , null , null , false , false , false , false );
285+ provider .checkAndReloadCertificates ();
286+ verifyWatcherUpdates (SERVER_0_PEM_FILE , null , null );
287+ verifyTimeServiceAndScheduledFuture ();
288+ }
289+
290+ @ Test
291+ public void keyFileUpdateOnly ()
292+ throws IOException , CertificateException , InterruptedException {
293+ TestScheduledFuture <?> scheduledFuture =
294+ new TestScheduledFuture <>();
295+ doReturn (scheduledFuture )
296+ .when (timeService )
297+ .schedule (any (Runnable .class ), any (Long .TYPE ), eq (TimeUnit .SECONDS ));
298+ // Assume the key/cert is not updated atomically and we see a tear between them. Or maybe this
299+ // was just a bug.
300+ populateTarget (
301+ SERVER_0_PEM_FILE , CLIENT_KEY_FILE , CA_PEM_FILE , null , false , false , false , false );
302+ provider .checkAndReloadCertificates ();
303+
304+ reset (mockWatcher , timeService );
305+ doReturn (scheduledFuture )
306+ .when (timeService )
307+ .schedule (any (Runnable .class ), any (Long .TYPE ), eq (TimeUnit .SECONDS ));
308+ timeProvider .forwardTime (1 , TimeUnit .SECONDS );
309+ // Even though it is strange the key updated without a cert update, we do still want to use the
310+ // new files, as this recovers from the earlier tear.
311+ populateTarget (null , SERVER_0_KEY_FILE , null , null , false , false , false , false );
312+ provider .checkAndReloadCertificates ();
313+ verifyWatcherUpdates (SERVER_0_PEM_FILE , null , null );
314+ verifyTimeServiceAndScheduledFuture ();
315+ }
316+
264317 @ Test
265318 public void spiffeTrustMapFileUpdateOnly () throws Exception {
266319 provider = new FileWatcherCertificateProvider (watcher , true , certFile , keyFile , null ,
0 commit comments