blob: e31fb7aa53efd9d42b6be28548b386d1cc6f3a61 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2015 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 java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.Assert;
import org.junit.Test;
public class ContainerLifeCycleTest
{
@Test
public void testStartStopDestroy() throws Exception
{
final AtomicInteger destroyed=new AtomicInteger();
final AtomicInteger started=new AtomicInteger();
final AtomicInteger stopped=new AtomicInteger();
ContainerLifeCycle a0=new ContainerLifeCycle();
ContainerLifeCycle a1=new ContainerLifeCycle()
{
@Override
protected void doStart() throws Exception
{
started.incrementAndGet();
super.doStart();
}
@Override
protected void doStop() throws Exception
{
stopped.incrementAndGet();
super.doStop();
}
@Override
public void destroy()
{
destroyed.incrementAndGet();
super.destroy();
}
};
a0.addBean(a1);
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(2,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.stop();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.destroy();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
a0.start();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
a0.addBean(a1);
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
Assert.assertFalse(a0.isManaged(a1));
a0.start();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
a1.start();
a0.manage(a1);
Assert.assertEquals(3,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
a0.removeBean(a1);
Assert.assertEquals(3,started.get());
Assert.assertEquals(3,stopped.get());
Assert.assertEquals(1,destroyed.get());
a0.stop();
a0.destroy();
Assert.assertEquals(3,started.get());
Assert.assertEquals(3,stopped.get());
Assert.assertEquals(1,destroyed.get());
a1.stop();
Assert.assertEquals(3,started.get());
Assert.assertEquals(3,stopped.get());
Assert.assertEquals(1,destroyed.get());
a1.destroy();
Assert.assertEquals(3,started.get());
Assert.assertEquals(3,stopped.get());
Assert.assertEquals(2,destroyed.get());
}
@Test
public void testDisJoint() throws Exception
{
final AtomicInteger destroyed=new AtomicInteger();
final AtomicInteger started=new AtomicInteger();
final AtomicInteger stopped=new AtomicInteger();
ContainerLifeCycle a0=new ContainerLifeCycle();
ContainerLifeCycle a1=new ContainerLifeCycle()
{
@Override
protected void doStart() throws Exception
{
started.incrementAndGet();
super.doStart();
}
@Override
protected void doStop() throws Exception
{
stopped.incrementAndGet();
super.doStop();
}
@Override
public void destroy()
{
destroyed.incrementAndGet();
super.destroy();
}
};
// Start the a1 bean before adding, makes it auto disjoint
a1.start();
// Now add it
a0.addBean(a1);
Assert.assertFalse(a0.isManaged(a1));
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(0,stopped.get());
Assert.assertEquals(0,destroyed.get());
a1.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.manage(a1);
Assert.assertTrue(a0.isManaged(a1));
a0.stop();
Assert.assertEquals(1,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.start();
Assert.assertEquals(2,started.get());
Assert.assertEquals(1,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.stop();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(0,destroyed.get());
a0.unmanage(a1);
Assert.assertFalse(a0.isManaged(a1));
a0.destroy();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(0,destroyed.get());
a1.destroy();
Assert.assertEquals(2,started.get());
Assert.assertEquals(2,stopped.get());
Assert.assertEquals(1,destroyed.get());
}
@Test
public void testDumpable() throws Exception
{
ContainerLifeCycle a0 = new ContainerLifeCycle();
String dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
ContainerLifeCycle aa0 = new ContainerLifeCycle();
a0.addBean(aa0);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," +? org.eclipse.jetty.util.component.ContainerLife");
ContainerLifeCycle aa1 = new ContainerLifeCycle();
a0.addBean(aa1);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," +? org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +? org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump,"");
ContainerLifeCycle aa2 = new ContainerLifeCycle();
a0.addBean(aa2,false);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," +? org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +? org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +~ org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump,"");
aa1.start();
a0.start();
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +~ org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +~ org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump,"");
a0.manage(aa1);
a0.removeBean(aa2);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump,"");
ContainerLifeCycle aaa0 = new ContainerLifeCycle();
aa0.addBean(aaa0);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump,"");
ContainerLifeCycle aa10 = new ContainerLifeCycle();
aa1.addBean(aa10,true);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," += org.eclipse.jetty.util.component.Container");
dump=check(dump,"");
final ContainerLifeCycle a1 = new ContainerLifeCycle();
final ContainerLifeCycle a2 = new ContainerLifeCycle();
final ContainerLifeCycle a3 = new ContainerLifeCycle();
final ContainerLifeCycle a4 = new ContainerLifeCycle();
ContainerLifeCycle aa = new ContainerLifeCycle()
{
@Override
public void dump(Appendable out, String indent) throws IOException
{
out.append(this.toString()).append("\n");
dump(out,indent,TypeUtil.asList(new Object[]{a1,a2}),TypeUtil.asList(new Object[]{a3,a4}));
}
};
a0.addBean(aa,true);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | += org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump,"");
a2.addBean(aa0,true);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | += org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," | += org.eclipse.jetty.util.component.Conta");
dump=check(dump," | +~ org.eclipse.jetty.util.component.C");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump,"");
a2.unmanage(aa0);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | += org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Conta");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump," +- org.eclipse.jetty.util.component.Container");
dump=check(dump,"");
a0.unmanage(aa);
dump=trim(a0.dump());
dump=check(dump,"org.eclipse.jetty.util.component.ContainerLifeCycl");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | +~ org.eclipse.jetty.util.component.Container");
dump=check(dump," += org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump," | += org.eclipse.jetty.util.component.Container");
dump=check(dump," +~ org.eclipse.jetty.util.component.ContainerLife");
dump=check(dump,"");
}
@Test
public void listenerTest() throws Exception
{
final Queue<String> handled = new ConcurrentLinkedQueue<>();
final Queue<String> operation = new ConcurrentLinkedQueue<>();
final Queue<Container> parent = new ConcurrentLinkedQueue<>();
final Queue<Object> child = new ConcurrentLinkedQueue<>();
Container.Listener listener= new Container.Listener()
{
@Override
public void beanRemoved(Container p, Object c)
{
handled.add(toString());
operation.add("removed");
parent.add(p);
child.add(c);
}
@Override
public void beanAdded(Container p, Object c)
{
handled.add(toString());
operation.add("added");
parent.add(p);
child.add(c);
}
public @Override String toString() {return "listener";}
};
ContainerLifeCycle c0 = new ContainerLifeCycle() { public @Override String toString() {return "c0";}};
ContainerLifeCycle c00 = new ContainerLifeCycle() { public @Override String toString() {return "c00";}};
c0.addBean(c00);
String b000="b000";
c00.addBean(b000);
c0.addBean(listener);
Assert.assertEquals("listener",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(c00,child.poll());
Assert.assertEquals("listener",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(listener,child.poll());
Container.InheritedListener inherited= new Container.InheritedListener()
{
@Override
public void beanRemoved(Container p, Object c)
{
handled.add(toString());
operation.add("removed");
parent.add(p);
child.add(c);
}
@Override
public void beanAdded(Container p, Object c)
{
handled.add(toString());
operation.add("added");
parent.add(p);
child.add(c);
}
public @Override String toString() {return "inherited";}
};
c0.addBean(inherited);
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(c00,child.poll());
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(listener,child.poll());
Assert.assertEquals("listener",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(inherited,child.poll());
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(inherited,child.poll());
c0.start();
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c00,parent.poll());
Assert.assertEquals(b000,child.poll());
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("added",operation.poll());
Assert.assertEquals(c00,parent.poll());
Assert.assertEquals(inherited,child.poll());
c0.removeBean(c00);
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("removed",operation.poll());
Assert.assertEquals(c00,parent.poll());
Assert.assertEquals(inherited,child.poll());
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("removed",operation.poll());
Assert.assertEquals(c00,parent.poll());
Assert.assertEquals(b000,child.poll());
Assert.assertEquals("listener",handled.poll());
Assert.assertEquals("removed",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(c00,child.poll());
Assert.assertEquals("inherited",handled.poll());
Assert.assertEquals("removed",operation.poll());
Assert.assertEquals(c0,parent.poll());
Assert.assertEquals(c00,child.poll());
}
private final class InheritedListenerLifeCycle extends AbstractLifeCycle implements Container.InheritedListener
{
public @Override void beanRemoved(Container p, Object c){}
public @Override void beanAdded(Container p, Object c) {}
public @Override String toString() {return "inherited";}
}
@Test
public void testInheritedListener() throws Exception
{
ContainerLifeCycle c0 = new ContainerLifeCycle() { public @Override String toString() {return "c0";}};
ContainerLifeCycle c00 = new ContainerLifeCycle() { public @Override String toString() {return "c00";}};
ContainerLifeCycle c01 = new ContainerLifeCycle() { public @Override String toString() {return "c01";}};
Container.InheritedListener inherited= new InheritedListenerLifeCycle();
c0.addBean(c00);
c0.start();
c0.addBean(inherited);
c0.manage(inherited);
c0.addBean(c01);
c01.start();
c0.manage(c01);
Assert.assertTrue(c0.isManaged(inherited));
Assert.assertFalse(c00.isManaged(inherited));
Assert.assertFalse(c01.isManaged(inherited));
}
String trim(String s) throws IOException
{
StringBuilder b=new StringBuilder();
BufferedReader reader=new BufferedReader(new StringReader(s));
for (String line=reader.readLine();line!=null;line=reader.readLine())
{
if (line.length()>50)
line=line.substring(0,50);
b.append(line).append('\n');
}
return b.toString();
}
String check(String s,String x)
{
String r=s;
int nl = s.indexOf('\n');
if (nl>0)
{
r=s.substring(nl+1);
s=s.substring(0,nl);
}
Assert.assertEquals(x,s);
return r;
}
}