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 Joerg Schaible *
009 *****************************************************************************/
010 package org.picocontainer.defaults;
011
012 import junit.framework.TestCase;
013
014 /**
015 * Test the CyclicDependecy.
016 */
017 public class CyclicDependencyGuardTestCase
018 extends TestCase {
019 private Runnable[] runner = new Runnable[3];
020
021 class ThreadLocalRunner implements Runnable {
022 public CyclicDependencyException exception;
023 private final Blocker blocker;
024 private final CyclicDependencyGuard guard;
025
026 public ThreadLocalRunner() {
027 this.blocker = new Blocker();
028 this.guard = new ThreadLocalCyclicDependencyGuard() {
029 public Object run() {
030 try {
031 blocker.block();
032 } catch (InterruptedException e) {
033 }
034 return null;
035 }
036 };
037 }
038
039 public void run() {
040 try {
041 guard.observe(ThreadLocalRunner.class);
042 } catch (CyclicDependencyException e) {
043 exception = e;
044 }
045 }
046 }
047
048 public class Blocker {
049 public void block() throws InterruptedException {
050 final Thread thread = Thread.currentThread();
051 synchronized (thread) {
052 thread.wait();
053 }
054 }
055 }
056
057 private void initTest(final Runnable[] runner) throws InterruptedException {
058
059 Thread racer[] = new Thread[runner.length];
060 for(int i = 0; i < racer.length; ++i) {
061 racer[i] = new Thread(runner[i]);
062 }
063
064 for(int i = 0; i < racer.length; ++i) {
065 racer[i].start();
066 Thread.sleep(200);
067 }
068
069 for(int i = 0; i < racer.length; ++i) {
070 synchronized (racer[i]) {
071 racer[i].notify();
072 }
073 }
074
075 for(int i = 0; i < racer.length; ++i) {
076 racer[i].join();
077 }
078 }
079
080 public void testCyclicDependencyWithThreadSafeGuard() throws InterruptedException {
081 for(int i = 0; i < runner.length; ++i) {
082 runner[i] = new ThreadLocalRunner();
083 }
084
085 initTest(runner);
086
087 for(int i = 0; i < runner.length; ++i) {
088 assertNull(((ThreadLocalRunner)runner[i]).exception);
089 }
090 }
091 }