### Question:
PipelineImpl implements Pipeline { @Override public void cancel(Key taskId) { try { main.writeLock().lock(); tasks.remove(taskId); futures.remove(taskId).cancel(false); workings.remove(taskId); } finally { main.writeLock().unlock(); } } @Inject  PipelineImpl(Context ctx); @Override Key submit(Task<BuildResult> task); @Override Task<BuildResult> get(Key taskId); @Override void cancel(Key taskId); @Override List<Key> list(Filter... filters); @Override InputStream cat(Key task); @Override void addListener(Listener listener); @Override void removeListener(Listener listener); @Override void waitFor(Key... k); @Override void waitFor(long time, TimeUnit unit, Key... ks); @Override Future<BuildResult> getFuture(Key k);  }### Answer:
@Test public void cancel() throws Exception { Task<BuildResult> t = createTask("/", 5000); assertThat(pipeline.list(Filters.pending())).isEmpty(); Key k = pipeline.submit(t); Thread.sleep(20); assertThat(pipeline.list(Filters.running())).containsOnly(k); assertThat(pipeline.list(Filters.pending())).isEmpty(); pipeline.cancel(t.getKey()); assertThat(pipeline.list(Filters.running())).isEmpty(); assertThat(pipeline.list(Filters.pending())).isEmpty(); long l0 = System.currentTimeMillis(); pipeline.waitFor(1, TimeUnit.SECONDS, k); long l1 = System.currentTimeMillis(); assertThat(l1 - l0).isLessThan(1000); }