// // ======================================================================== // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // // You may elect to redistribute this code under either of these licenses. // ======================================================================== // package org.eclipse.jetty.util.component; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.List; import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; /** * Testing for LifeCycleListener events on nested components * during runtime. */ @Ignore public class LifeCycleListenerNestedTest { // Set this true to use test-specific workaround. private final boolean WORKAROUND = false; public static class Foo extends ContainerLifeCycle { @Override public String toString() { return Foo.class.getSimpleName(); } } public static class Bar extends ContainerLifeCycle { private final String id; public Bar(String id) { this.id = id; } public String getId() { return id; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Bar other = (Bar)obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } @Override public String toString() { return Bar.class.getSimpleName() + "(" + id + ")"; } } public static enum LifeCycleEvent { STARTING, STARTED, FAILURE, STOPPING, STOPPED } public static class CapturingListener implements LifeCycle.Listener, Container.InheritedListener { private List<String> events = new ArrayList<>(); private void addEvent(Object obj, LifeCycleEvent event) { events.add(String.format("%s - %s",obj.toString(),event.name())); } @Override public void lifeCycleStarting(LifeCycle event) { addEvent(event,LifeCycleEvent.STARTING); } @Override public void lifeCycleStarted(LifeCycle event) { addEvent(event,LifeCycleEvent.STARTED); } @Override public void lifeCycleFailure(LifeCycle event, Throwable cause) { addEvent(event,LifeCycleEvent.FAILURE); } @Override public void lifeCycleStopping(LifeCycle event) { addEvent(event,LifeCycleEvent.STOPPING); } @Override public void lifeCycleStopped(LifeCycle event) { addEvent(event,LifeCycleEvent.STOPPED); } public List<String> getEvents() { return events; } public void assertEvents(Matcher<Iterable<? super String>> matcher) { assertThat(events,matcher); } @Override public void beanAdded(Container parent, Object child) { if(child instanceof LifeCycle) { ((LifeCycle)child).addLifeCycleListener(this); } } @Override public void beanRemoved(Container parent, Object child) { if(child instanceof LifeCycle) { ((LifeCycle)child).removeLifeCycleListener(this); } } } @Test public void testAddBean_AddListener_Start() throws Exception { Foo foo = new Foo(); Bar bara = new Bar("a"); Bar barb = new Bar("b"); foo.addBean(bara); foo.addBean(barb); CapturingListener listener = new CapturingListener(); foo.addLifeCycleListener(listener); if(WORKAROUND) foo.addEventListener(listener); try { foo.start(); assertThat("Foo.started",foo.isStarted(),is(true)); assertThat("Bar(a).started",bara.isStarted(),is(true)); assertThat("Bar(b).started",barb.isStarted(),is(true)); listener.assertEvents(hasItem("Foo - STARTING")); listener.assertEvents(hasItem("Foo - STARTED")); listener.assertEvents(hasItem("Bar(a) - STARTING")); listener.assertEvents(hasItem("Bar(a) - STARTED")); listener.assertEvents(hasItem("Bar(b) - STARTING")); listener.assertEvents(hasItem("Bar(b) - STARTED")); } finally { foo.stop(); } } @Test public void testAddListener_AddBean_Start() throws Exception { Foo foo = new Foo(); CapturingListener listener = new CapturingListener(); foo.addLifeCycleListener(listener); if(WORKAROUND) foo.addEventListener(listener); Bar bara = new Bar("a"); Bar barb = new Bar("b"); foo.addBean(bara); foo.addBean(barb); try { foo.start(); assertThat("Foo.started",foo.isStarted(),is(true)); assertThat("Bar(a).started",bara.isStarted(),is(true)); assertThat("Bar(b).started",barb.isStarted(),is(true)); listener.assertEvents(hasItem("Foo - STARTING")); listener.assertEvents(hasItem("Foo - STARTED")); listener.assertEvents(hasItem("Bar(a) - STARTING")); listener.assertEvents(hasItem("Bar(a) - STARTED")); listener.assertEvents(hasItem("Bar(b) - STARTING")); listener.assertEvents(hasItem("Bar(b) - STARTED")); } finally { foo.stop(); } } @Test public void testAddListener_Start_AddBean() throws Exception { Foo foo = new Foo(); Bar bara = new Bar("a"); Bar barb = new Bar("b"); CapturingListener listener = new CapturingListener(); foo.addLifeCycleListener(listener); if(WORKAROUND) foo.addEventListener(listener); try { foo.start(); listener.assertEvents(hasItem("Foo - STARTING")); listener.assertEvents(hasItem("Foo - STARTED")); foo.addBean(bara); foo.addBean(barb); bara.start(); barb.start(); assertThat("Bar(a).started",bara.isStarted(),is(true)); assertThat("Bar(b).started",barb.isStarted(),is(true)); listener.assertEvents(hasItem("Bar(a) - STARTING")); listener.assertEvents(hasItem("Bar(a) - STARTED")); listener.assertEvents(hasItem("Bar(b) - STARTING")); listener.assertEvents(hasItem("Bar(b) - STARTED")); } finally { barb.stop(); bara.stop(); foo.stop(); } } }