### Question:
MetricExitCallback implements ProcessorSlotExitCallback { @Override public void onExit(Context context, ResourceWrapper rw, int acquireCount, Object... args) { Entry curEntry = context.getCurEntry(); if (curEntry == null) { return; } for (MetricExtension m : MetricExtensionProvider.getMetricExtensions()) { if (curEntry.getBlockError() != null) { continue; } String resource = rw.getName(); Throwable ex = curEntry.getError(); long completeTime = curEntry.getCompleteTimestamp(); if (completeTime <= 0) { completeTime = TimeUtil.currentTimeMillis(); } long rt = completeTime - curEntry.getCreateTimestamp(); if (m instanceof AdvancedMetricExtension) { ((AdvancedMetricExtension) m).onComplete(rw, rt, acquireCount, args); if (ex != null) { ((AdvancedMetricExtension) m).onError(rw, ex, acquireCount, args); } } else { m.addRt(resource, rt, args); m.addSuccess(resource, acquireCount, args); m.decreaseThreadNum(resource, args); if (null != ex) { m.addException(resource, acquireCount, ex); } } } }  @Override void onExit(Context context, ResourceWrapper rw, int acquireCount, Object... args);  }### Answer:
@Test public void onExit() { FakeMetricExtension extension = new FakeMetricExtension(); MetricExtensionProvider.addMetricExtension(extension); MetricExitCallback exitCallback = new MetricExitCallback(); StringResourceWrapper resourceWrapper = new StringResourceWrapper("resource", EntryType.OUT); int count = 2; Object[] args = {"args1", "args2"}; long prevRt = 20; extension.rt = prevRt; extension.success = 6; extension.thread = 10; Context context = mock(Context.class); Entry entry = mock(Entry.class); long curMillis = System.currentTimeMillis(); setCurrentMillis(curMillis); int deltaMs = 100; when(entry.getError()).thenReturn(null); when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs); when(context.getCurEntry()).thenReturn(entry); exitCallback.onExit(context, resourceWrapper, count, args); Assert.assertEquals(prevRt + deltaMs, extension.rt); Assert.assertEquals(extension.success, 6 + count); Assert.assertEquals(extension.thread, 10 - 1); }
@Test public void advancedExtensionOnExit() { FakeAdvancedMetricExtension extension = new FakeAdvancedMetricExtension(); MetricExtensionProvider.addMetricExtension(extension); MetricExitCallback exitCallback = new MetricExitCallback(); StringResourceWrapper resourceWrapper = new StringResourceWrapper("resource", EntryType.OUT); int count = 2; Object[] args = {"args1", "args2"}; long prevRt = 20; extension.rt = prevRt; extension.complete = 6; extension.concurrency = 10; Context context = mock(Context.class); Entry entry = mock(Entry.class); long curMillis = System.currentTimeMillis(); setCurrentMillis(curMillis); int deltaMs = 100; when(entry.getError()).thenReturn(null); when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs); when(context.getCurEntry()).thenReturn(entry); exitCallback.onExit(context, resourceWrapper, count, args); Assert.assertEquals(prevRt + deltaMs, extension.rt); Assert.assertEquals(extension.complete, 6 + count); Assert.assertEquals(extension.concurrency, 10 - 1); }