/*
 * Created on Feb 21, 2005
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */

package org.activemq.streams;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import junit.framework.TestCase;
import org.activemq.ActiveMQConnectionFactory;
import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;

/**
 * JMSInputStreamTest
 */
public class JMSInputStreamTest extends TestCase {
    protected Connection producerConnection;
    protected Connection consumerConnection;
    protected DataOutputStream out;
    protected DataInputStream in;

    /*
     * @see TestCase#setUp()
     */
    protected void setUp() throws Exception {
        super.setUp();
        ConnectionFactory fac = new ActiveMQConnectionFactory("vm://localhost");
        producerConnection = fac.createConnection();
        Session s = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination dest = s.createTopic(getClass().getName());
        MessageProducer producer = s.createProducer(dest);
        consumerConnection = fac.createConnection();
        s = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageConsumer consumer = s.createConsumer(dest);
        consumerConnection.start();
        out = new DataOutputStream(new JMSOutputStream(producer));
        in = new DataInputStream(new JMSInputStream(consumer));
    }

    /*
     * @see TestCase#tearDown()
     */
    protected void tearDown() throws Exception {
        super.tearDown();
        consumerConnection.close();
        producerConnection.close();
    }

    public void testStreams() throws Exception {
        out.writeInt(4);
        out.flush();
        assertTrue(in.readInt() == 4);
        out.writeFloat(2.3f);
        out.flush();
        assertTrue(in.readFloat() == 2.3f);
        String str = "this is a test string";
        out.writeUTF(str);
        out.flush();
        assertTrue(in.readUTF().equals(str));
        for (int i = 0;i < 100;i++) {
            out.writeLong(i);
        }
        out.flush();
        for (int i = 0;i < 100;i++) {
            assertTrue(in.readLong() == i);
        }
    }

    public void testLarge() throws Exception {
        final int TEST_DATA = 23;
        final int DATA_LENGTH = 4096;
        final int COUNT = 1024;
        byte[] data = new byte[DATA_LENGTH];
        for (int i = 0;i < data.length;i++) {
            data[i] = TEST_DATA;
        }
        final SynchronizedBoolean complete = new SynchronizedBoolean(false);
        Thread runner = new Thread(new Runnable() {
            public void run() {
                try {
                    for (int x = 0;x < COUNT;x++) {
                        byte[] b = new byte[2048];
                        in.readFully(b);
                        for (int i = 0;i < b.length;i++) {
                            assertTrue(b[i] == TEST_DATA);
                        }
                    }
                    complete.set(true);
                    synchronized(complete){
                        complete.notify();
                    }
                }
                catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        runner.start();
        for (int i = 0;i < COUNT;i++) {
            out.write(data);
        }
        out.flush();
        synchronized (complete) {
            if (!complete.get()) {
                complete.wait(30000);
            }
        }
        assertTrue(complete.get());
    }

    /**
     * Constructor for JMSInputStreamTest.
     * 
     * @param arg0
     */
    public JMSInputStreamTest(String arg0) {
        super(arg0);
    }
}