001 /*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 * *
008 * Original code by *
009 *****************************************************************************/
010 package org.picocontainer.behaviors;
011
012 import static org.junit.Assert.assertEquals;
013 import static org.junit.Assert.assertFalse;
014 import static org.junit.Assert.assertNotNull;
015 import static org.junit.Assert.assertSame;
016
017 import org.junit.Test;
018 import org.picocontainer.DefaultPicoContainer;
019 import org.picocontainer.containers.EmptyPicoContainer;
020 import org.picocontainer.lifecycle.NullLifecycleStrategy;
021
022 public class ThreadCachingTestCase {
023
024 public static class Foo {
025 public Foo(StringBuilder sb) {
026 sb.append("<Foo");
027 }
028 }
029
030 public static class Bar {
031 private final Foo foo;
032 public Bar(StringBuilder sb, Foo foo) {
033 this.foo = foo;
034 sb.append("<Bar");
035 }
036 }
037
038 @Test public void testThatForASingleThreadTheBehaviorIsTheSameAsPlainCaching() {
039
040 DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
041 DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), parent);
042
043 parent.addComponent(StringBuilder.class);
044 child.addComponent(Foo.class);
045
046 StringBuilder sb = parent.getComponent(StringBuilder.class);
047 Foo foo = child.getComponent(Foo.class);
048 Foo foo2 = child.getComponent(Foo.class);
049 assertNotNull(foo);
050 assertNotNull(foo2);
051 assertEquals(foo,foo2);
052 assertEquals("<Foo", sb.toString());
053 assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
054 }
055
056 @Test public void testThatTwoThreadsHaveSeparatedCacheValues() {
057
058 final Foo[] foos = new Foo[4];
059
060 DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
061 final DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), parent);
062
063 parent.addComponent(StringBuilder.class);
064 child.addComponent(Foo.class);
065
066 StringBuilder sb = parent.getComponent(StringBuilder.class);
067 foos[0] = child.getComponent(Foo.class);
068
069 Thread thread = new Thread() {
070 public void run() {
071 foos[1] = child.getComponent(Foo.class);
072 foos[3] = child.getComponent(Foo.class);
073 }
074 };
075 thread.start();
076 foos[2] = child.getComponent(Foo.class);
077 try {
078 Thread.sleep(100);
079 } catch (InterruptedException e) {
080 }
081
082 assertNotNull(foos[0]);
083 assertNotNull(foos[1]);
084 assertNotNull(foos[2]);
085 assertNotNull(foos[3]);
086 assertSame(foos[0],foos[2]);
087 assertEquals(foos[1],foos[3]);
088 assertFalse(foos[0] == foos[1]);
089 assertEquals("<Foo<Foo", sb.toString());
090 assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
091 }
092
093 @Test public void testThatTwoThreadsHaveSeparatedCacheValuesForThreeScopeScenario() {
094
095 final Foo[] foos = new Foo[4];
096 final Bar[] bars = new Bar[4];
097
098 DefaultPicoContainer appScope = new DefaultPicoContainer(new Caching());
099 final DefaultPicoContainer sessionScope = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), appScope);
100 final DefaultPicoContainer requestScope = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), sessionScope);
101
102 appScope.addComponent(StringBuilder.class);
103 sessionScope.addComponent(Foo.class);
104 requestScope.addComponent(Bar.class);
105
106 StringBuilder sb = appScope.getComponent(StringBuilder.class);
107 foos[0] = sessionScope.getComponent(Foo.class);
108 bars[0] = requestScope.getComponent(Bar.class);
109
110 Thread thread = new Thread() {
111 public void run() {
112 foos[1] = sessionScope.getComponent(Foo.class);
113 bars[1] = requestScope.getComponent(Bar.class);
114 foos[3] = sessionScope.getComponent(Foo.class);
115 bars[3] = requestScope.getComponent(Bar.class);
116 }
117 };
118 thread.start();
119 foos[2] = sessionScope.getComponent(Foo.class);
120 bars[2] = requestScope.getComponent(Bar.class);
121 try {
122 Thread.sleep(100);
123 } catch (InterruptedException e) {
124 }
125
126 assertSame(bars[0],bars[2]);
127 assertEquals(bars[1],bars[3]);
128 assertFalse(bars[0] == bars[1]);
129 assertSame(bars[0].foo,foos[0]);
130 assertSame(bars[1].foo,foos[1]);
131 assertSame(bars[2].foo,foos[2]);
132 assertSame(bars[3].foo,foos[3]);
133 assertEquals("<Foo<Bar<Foo<Bar", sb.toString());
134 assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", sessionScope.getComponentAdapter(Foo.class).toString());
135 }
136
137
138 }