001: /* ====================================================================
002: The Jicarilla Software License
003:
004: Copyright (c) 2003 Leo Simons.
005: All rights reserved.
006:
007: Permission is hereby granted, free of charge, to any person obtaining
008: a copy of this software and associated documentation files (the
009: "Software"), to deal in the Software without restriction, including
010: without limitation the rights to use, copy, modify, merge, publish,
011: distribute, sublicense, and/or sell copies of the Software, and to
012: permit persons to whom the Software is furnished to do so, subject to
013: the following conditions:
014:
015: The above copyright notice and this permission notice shall be
016: included in all copies or substantial portions of the Software.
017:
018: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
019: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
020: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
021: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
022: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
023: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
024: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
025: ==================================================================== */
026: package org.jicarilla.plumbing.test;
027:
028: import org.jicarilla.plumbing.NoopSink;
029: import org.jicarilla.plumbing.SimpleMulticaster;
030: import org.jicarilla.plumbing.Sink;
031: import org.jicarilla.plumbing.Sink;
032: import org.jicarilla.plumbing.NoopSink;
033: import org.jicarilla.plumbing.SimpleMulticaster;
034: import junit.framework.TestCase;
035:
036: import java.util.List;
037:
038: /**
039: * <a href="http://www.junit.org/">JUnit</a> {@link TestCase testcase} for
040: * SimpleMulticaster.
041: *
042: * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
043: * @version $Id: SimpleMulticasterTestCase.java,v 1.1 2003/11/18 16:09:16
044: * lsimons Exp $
045: */
046: public class SimpleMulticasterTestCase extends TestCase {
047: public static class CountingSink implements Sink {
048: public int put = 0;
049: public int offered = 0;
050: public static int sput = 0;
051: public static int soffered = 0;
052:
053: public void put(Object o) throws InterruptedException {
054: put++;
055: sput++;
056: }
057:
058: public boolean offer(Object o, long l)
059: throws InterruptedException {
060: offered++;
061: soffered++;
062: return true;
063: }
064: }
065:
066: public void testConstructor() {
067: new SimpleMulticaster();
068:
069: assertEquals(0, new Multicaster().getSinks().size());
070: assertEquals(0, new Multicaster().getSize());
071: }
072:
073: public void testAdd() {
074: Multicaster m = new Multicaster();
075:
076: NoopSink s = new NoopSink();
077: m.addSink(s);
078:
079: assertEquals(m.getSinks().get(0), s);
080:
081: NoopSink s2 = new NoopSink();
082: m.addSink(s2);
083: assertEquals(m.getSinks().get(1), s2);
084:
085: assertEquals(m.getSinks().size(), m.getSize());
086:
087: Throwable t = null;
088: try {
089: m.addSink(null);
090: } catch (AssertionError ae) {
091: t = ae;
092: }
093: assertNotNull(t);
094: }
095:
096: boolean running = true;
097:
098: public void testConcurrentAdd() throws InterruptedException {
099: final Multicaster m = new Multicaster();
100:
101: Thread[] threads = new Thread[5];
102: for (int i = 0; i < 5; i++) {
103: threads[i] = new Thread(new Runnable() {
104:
105: public void run() {
106: while (running) {
107: try {
108: Thread.sleep(100);
109: } catch (InterruptedException e1) {
110: break;
111: }
112: NoopSink s = new NoopSink();
113: m.addSink(s);
114: Thread.yield();
115: }
116: }
117: });
118: }
119: for (int i = 0; i < 5; i++) {
120: threads[i].start();
121: }
122:
123: Thread.sleep(1000);
124: running = false;
125:
126: for (int i = 0; i < 5; i++) {
127: threads[i].interrupt();
128: }
129: }
130:
131: public void testPut() throws InterruptedException {
132: Multicaster m = new Multicaster();
133:
134: CountingSink s1 = new CountingSink();
135: CountingSink s2 = new CountingSink();
136: CountingSink s3 = new CountingSink();
137:
138: m.addSink(s1);
139: m.addSink(s2);
140: m.addSink(s3);
141:
142: m.put(new CloneMe());
143: m.put(new Object());
144: m.put(new DontCloneMe());
145: m.put(new Object());
146:
147: assertEquals(12, CountingSink.sput);
148: assertEquals(4, s1.put);
149: }
150:
151: public void testOffer() throws InterruptedException {
152: Multicaster m = new Multicaster();
153:
154: CountingSink s1 = new CountingSink();
155: CountingSink s2 = new CountingSink();
156: CountingSink s3 = new CountingSink();
157:
158: m.addSink(s1);
159: m.addSink(s2);
160: m.addSink(s3);
161:
162: assertTrue(m.offer(new CloneMe(), 10));
163: m.offer(new Object(), 10);
164: assertTrue(m.offer(new Object(), 10));
165:
166: assertEquals(9, CountingSink.soffered);
167: assertEquals(3, s1.offered);
168: }
169:
170: public static class Multicaster extends SimpleMulticaster {
171: public List getSinks() {
172: return m_sinks;
173: }
174:
175: public int getSize() {
176: return m_sinks.size();
177: }
178: }
179:
180: public static class CloneMe implements Cloneable {
181: public Object clone() throws CloneNotSupportedException {
182: return super .clone();
183: }
184: }
185:
186: public static class DontCloneMe implements Cloneable {
187: protected Object clone() throws CloneNotSupportedException {
188: return super.clone();
189: }
190: }
191: }
|