### Question:
MappableTypeHierarchyChangeListener implements EventHandler { @Activate protected void activate() { executorService.execute(() -> { while (!isShutDown) { try { Object path = invalidationRequests.poll(5, SECONDS); if (path != null) { if (logger.isTraceEnabled()) { logger.trace("Invalidating the resource model registry lookup cache due to changes to {}.", path); } modelRegistry.clearLookupCaches(); } } catch (InterruptedException e) { if (!isShutDown) { logger.debug("The type hierarchy change listener got interrupted, but was not shut down.", e); } } } }); }  @Override void handleEvent(Event event);  }### Answer:
@Test public void testActivateListenerClearsModelRegistryUponEvent() throws Exception { activate(); withChangeOn("/apps/testapp/components/test"); sleep(); verifyModelRegistryCacheIsCleared(); }
@Test public void testOnlyOneEventIsAccepted() throws Exception { withChangeOn("/apps/testapp/components/test"); withChangeOn("/apps/testapp/components/test"); withChangeOn("/apps/testapp/components/test"); withChangeOn("/apps/testapp/components/test"); withChangeOn("/apps/testapp/components/test"); activate(); sleep(); verifyModelRegistryCacheIsCleared(); }
@Test public void testLoggingOfInvalidatingChangeWhenLogLevelIsTrace() throws Exception { activate(); withTraceLogging(); withChangeOn("/apps/testapp/components/test"); sleep(); verifyLoggerTraces( "Invalidating the resource model registry lookup cache due to changes to {}.", "/apps/testapp/components/test"); }
@Test public void testLoggingOfInterruptionWithoutShutdown() throws Exception { withInterruptedExceptionThrownWhileBlocked(); activate(); withChangeOn("/some/path"); sleep(); verifyLoggerDebugs("The type hierarchy change listener got interrupted, but was not shut down."); }