### Question:
CentralJobScheduler extends LifecycleAdapter implements JobScheduler, AutoCloseable { @Override public JobHandle schedule( Group group, Runnable job ) { if ( !started ) { throw new RejectedExecutionException( "Scheduler is not started" ); } return pools.submit( group, job ); } protected  CentralJobScheduler(); @Override void setTopLevelGroupName( String name ); @Override void init(); @Override Executor executor( Group group ); @Override ExecutorService workStealingExecutor( Group group, int parallelism ); @Override ExecutorService workStealingExecutorAsyncMode( Group group, int parallelism ); @Override ThreadFactory threadFactory( Group group ); @Override JobHandle schedule( Group group, Runnable job ); @Override JobHandle scheduleRecurring( Group group, final Runnable runnable, long period, TimeUnit timeUnit ); @Override JobHandle scheduleRecurring( Group group, Runnable runnable, long initialDelay, long period, TimeUnit unit ); @Override JobHandle schedule( Group group, final Runnable runnable, long initialDelay, TimeUnit unit ); @Override void shutdown(); @Override void close();  }### Answer:
@Test public void taskSchedulerGroupMustNotBeDirectlySchedulable() { life.start(); expectedException.expect( IllegalArgumentException.class ); scheduler.schedule( Group.TASK_SCHEDULER, () -> fail( "This task should not have been executed." ) ); }
@Test public void shouldRunWithDelay() throws Throwable { life.start(); final AtomicLong runTime = new AtomicLong(); final CountDownLatch latch = new CountDownLatch( 1 ); long time = System.nanoTime(); scheduler.schedule( Group.INDEX_POPULATION, () -> { runTime.set( System.nanoTime() ); latch.countDown(); }, 100, TimeUnit.MILLISECONDS ); latch.await(); assertTrue( time + TimeUnit.MILLISECONDS.toNanos( 100 ) <= runTime.get() ); }