package com.thoughtworks.acceptance;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.thoughtworks.acceptance.objects.Software;
import com.thoughtworks.acceptance.someobjects.WithNamedList;


/**
 * @author J&ouml;rg Schaible
 */
public class ConcurrencyTest extends AbstractAcceptanceTest {

    public void testConcurrentXStreaming() throws InterruptedException {
        xstream.alias("thing", WithNamedList.class);
        xstream.addImplicitCollection(WithNamedList.class, "things");

        final List reference = Arrays.asList(new String[]{"A", "B", "C", "D"});
        final WithNamedList[] namedLists = new WithNamedList[5];
        for (int i = 0; i < namedLists.length; ++i) {
            namedLists[i] = new WithNamedList("Name " + (i + 1));
            namedLists[i].things.add(new Software("walnes", "XStream 1." + i));
            namedLists[i].things.add(reference);
            namedLists[i].things.add(new RuntimeException("JUnit " + i)); // a Serializable
        }

        final Map exceptions = new HashMap();
        final ThreadGroup tg = new ThreadGroup(getName()) {
            public void uncaughtException(Thread t, Throwable e) {
                exceptions.put(e, t.getName());
                super.uncaughtException(t, e);
            }
        };

        final Object object = Arrays.asList(namedLists); 
        final String xml = xstream.toXML(object);
        final Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.length; ++i) {
            threads[i] = new Thread(tg, "JUnit Thread " + i) {

                public void run() {
                    try {
                        synchronized (this) {
                            notifyAll();
                            wait();
                        }
                        while(!interrupted()) {
                            assertBothWays(object, xml);
                        }
                    } catch (InterruptedException e) {
                        fail("Unexpected InterruptedException");
                    }
                }

            };
        }

        for (int i = 0; i < threads.length; ++i) {
            synchronized (threads[i]) {
                threads[i].start();
                threads[i].wait();
            }
        }
        
        for (int i = 0; i < threads.length; ++i) {
            synchronized (threads[i]) {
                threads[i].notifyAll();
            }
        }
        
        Thread.sleep(500);
        
        for (int i = 0; i < threads.length; ++i) {
            synchronized (threads[i]) {
                threads[i].interrupt();
                threads[i].join();
            }
        }
        
        assertEquals(0, exceptions.size());
    }
}

@@ -1390,18 +1390,17 @@
 dLists);
- 
 %0A
+
         
@@ -1441,16 +1441,82 @@
 bject);%0A
+        final int%5B%5D counter = new int%5B1%5D;%0A        counter%5B0%5D = 0;%0A
         
@@ -1555,10 +1555,9 @@
 ead%5B
-10
+5
 %5D;%0A 
@@ -1702,24 +1702,55 @@
 oid run() %7B%0A
+                    int i = 0;%0A
             
@@ -1941,16 +1941,17 @@
    while
+ 
 (!interr
@@ -2018,16 +2018,49 @@
 , xml);%0A
+                            ++i;%0A
         
@@ -2211,32 +2211,140 @@
               %7D%0A
+                    synchronized (counter) %7B%0A                        counter%5B0%5D += i;%0A                    %7D%0A
                 
@@ -2554,33 +2554,25 @@
 %7D%0A        %7D%0A
-        
 %0A
+
         for 
@@ -2710,32 +2710,33 @@
 %7D%0A        %7D%0A
+%0A
         
 %0A        Thr
@@ -2727,33 +2727,113 @@
     
-%0A        Thread.sleep(500
+Thread.sleep(1000);%0A%0A        for (int i = 0; i %3C threads.length; ++i) %7B%0A            threads%5Bi%5D.interrupt(
 );%0A 
@@ -2831,32 +2831,33 @@
 rupt();%0A        
+%7D
 %0A        for (in
@@ -2936,48 +2936,8 @@
 ) %7B%0A
-                threads%5Bi%5D.interrupt();%0A
     
@@ -2991,24 +2991,16 @@
       %7D%0A
-        
 %0A       
@@ -3032,20 +3032,70 @@
 ns.size());%0A
+        assertTrue(counter%5B0%5D %3E= threads.length);%0A
     %7D%0A%7D%0A

Optimize runtime.