### Question:
CoreStateDownloaderService extends LifecycleAdapter { public synchronized Optional<JobHandle> scheduleDownload( CatchupAddressProvider addressProvider ) { if ( stopped ) { return Optional.empty(); } if ( currentJob == null || currentJob.hasCompleted() ) { currentJob = new PersistentSnapshotDownloader( addressProvider, applicationProcess, downloader, log, downloaderPauseStrategy, dbHealth, monitors ); jobHandle = jobScheduler.schedule( Group.DOWNLOAD_SNAPSHOT, currentJob ); return Optional.of( jobHandle ); } return Optional.of( jobHandle ); } CoreStateDownloaderService( JobScheduler jobScheduler, CoreStateDownloader downloader,
            CommandApplicationProcess applicationProcess, LogProvider logProvider,
            TimeoutStrategy.Timeout downloaderPauseStrategy, Supplier<DatabaseHealth> dbHealth, Monitors monitors ); synchronized Optional<JobHandle> scheduleDownload( CatchupAddressProvider addressProvider ); @Override synchronized void stop(); synchronized Optional<JobHandle> downloadJob();  }### Answer:
@Test public void shouldRunPersistentDownloader() throws Exception { CoreStateDownloader coreStateDownloader = mock( CoreStateDownloader.class ); when( coreStateDownloader.downloadSnapshot( any() ) ).thenReturn( true ); final CommandApplicationProcess applicationProcess = mock( CommandApplicationProcess.class ); final Log log = mock( Log.class ); CoreStateDownloaderService coreStateDownloaderService = new CoreStateDownloaderService( centralJobScheduler, coreStateDownloader, applicationProcess, logProvider( log ), new NoTimeout(), () -> dbHealth, new Monitors() ); coreStateDownloaderService.scheduleDownload( catchupAddressProvider ); waitForApplierToResume( applicationProcess ); verify( applicationProcess, times( 1 ) ).pauseApplier( OPERATION_NAME ); verify( applicationProcess, times( 1 ) ).resumeApplier( OPERATION_NAME ); verify( coreStateDownloader, times( 1 ) ).downloadSnapshot( any() ); }
@Test public void shouldOnlyScheduleOnePersistentDownloaderTaskAtTheTime() throws InterruptedException { AtomicInteger schedules = new AtomicInteger(); CountingJobScheduler countingJobScheduler = new CountingJobScheduler( schedules, centralJobScheduler ); Semaphore blockDownloader = new Semaphore( 0 ); CoreStateDownloader coreStateDownloader = new BlockingCoreStateDownloader( blockDownloader ); final CommandApplicationProcess applicationProcess = mock( CommandApplicationProcess.class ); final Log log = mock( Log.class ); CoreStateDownloaderService coreStateDownloaderService = new CoreStateDownloaderService( countingJobScheduler, coreStateDownloader, applicationProcess, logProvider( log ), new NoTimeout(), () -> dbHealth, new Monitors() ); coreStateDownloaderService.scheduleDownload( catchupAddressProvider ); Thread.sleep( 50 ); coreStateDownloaderService.scheduleDownload( catchupAddressProvider ); coreStateDownloaderService.scheduleDownload( catchupAddressProvider ); coreStateDownloaderService.scheduleDownload( catchupAddressProvider ); assertEquals( 1, schedules.get() ); blockDownloader.release(); }