/*                          
 * mBench: The Open Source Micro Benchmark Tool 
 *                                             
 * Distributable under GPL license. 
 * See terms of license at gnu.org.                 
 *
 * Copyright (C) 2005 Sumisho Computer Systems Corp.
 */
package test.jp.co.scs.mbench;

import jp.co.scs.mbench.BenchmarkContainer;
import jp.co.scs.mbench.BenchmarkInfo;
import jp.co.scs.mbench.BenchmarkTerminateException;
import jp.co.scs.mbench.CSVAsynchronousDataWriter;
import jp.co.scs.mbench.LogWriter;
import jp.co.scs.mbench.BenchmarkState;
import jp.co.scs.mbench.Synchronizer;
import junit.framework.TestCase;
import test.jp.co.scs.mbench.stub.StubBenchmarkContainer2;
import test.jp.co.scs.mbench.stub.StubBenchmarkContainer3;

/**
 *      @author Tetsuro Ikeda
 */
public class BenchmarkContainerTest extends TestCase {
    /**
     *  The state must be "INITIALIZED" if the initialization was succeeded.
     */
    public void testInitTarget() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer");
        info.setName("StubBenchmarkContainer");
        LogWriter logWriter = new LogWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, null);
        try {
            assertEquals(BenchmarkState.CREATED, container.getCurrentState());
            container.initTarget();
            assertEquals(BenchmarkState.INITIALIZED, container.getCurrentState());
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
    }
    
    /**
     *  The state must be "BENCHMARK_TERMINATED" and BenchmarkTerminatedException
     *  must be thrown if the benchmark component couldn't be created by the FQCN.
     */
    public void testInitTarget2() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName("Dummy");
        info.setName("StubBenchmarkContainer");
        LogWriter logWriter = new LogWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, null);
        try {
            container.initTarget();
            fail();
        } catch (BenchmarkTerminateException ex) {
        }
    }
    
    /**
     *  This method must return false before the "initTarget" is invoked,
     *  and must return true after that. 
     */
    public void testIsInitialized() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer");
        info.setName("StubBenchmarkContainer");
        LogWriter logWriter = new LogWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, null);
        try {
            assertFalse(container.isInitialized());
            container.initTarget();
            assertTrue(container.isInitialized());
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
    }
    
    /**
     *  Data log must be in the queue of CVSAsynchronousDataWriter
     *  (although it ism't started yet) and the state must be "FINISHED",
     *  after the invocation of "execute" method.
     */
    public void testExecuteTarget() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer");
        info.setName("StubBenchmarkContainer");
        int repeatNumber = 10;
        info.setRepeatNumber(repeatNumber);
        LogWriter logWriter = new LogWriter(null);
        CSVAsynchronousDataWriter dataWriter =
            new CSVAsynchronousDataWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, dataWriter);
        try {
            container.initTarget();
            assertEquals(0, dataWriter.getDataQueueSize());
            container.executeTarget();
            assertEquals(repeatNumber, dataWriter.getDataQueueSize());
            assertEquals(BenchmarkState.FINISHED, container.getCurrentState());
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
    }
    
    /**
     *  The data log must be in the queue of CVSAsynchronousDataWriter and 
     *  the state must be "THREAD_TERMINATED", if the "execute" method 
     *  threw the "ThreadTerminateException" while executing.
     */
    public void testExecuteTarget2() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer2");
        info.setName("StubBenchmarkContainer2");
        int repeatNumber = StubBenchmarkContainer2.ABORT_NUMBER * 2;
        info.setRepeatNumber(repeatNumber);
        LogWriter logWriter = new LogWriter(null);
        CSVAsynchronousDataWriter dataWriter =
            new CSVAsynchronousDataWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, dataWriter);
        try {
            container.initTarget();
            container.executeTarget();
            assertEquals(StubBenchmarkContainer2.ABORT_NUMBER - 1,
                dataWriter.getDataQueueSize());
            assertEquals(BenchmarkState.THREAD_TERMINATED, container.getCurrentState());
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
    }
    
    /**
     *  Data log must be in the queue and the state must be
     *  "BENCHMARK_TERMINATED" if "execute" method threw 
     *  BenchmarkTerminateException.
     */
    public void testExecuteTarget3() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer3");
        info.setName("StubBenchmarkContainer3");
        int repeatNumber = StubBenchmarkContainer3.ABORT_NUMBER * 2;
        info.setRepeatNumber(repeatNumber);
        LogWriter logWriter = new LogWriter(null);
        CSVAsynchronousDataWriter dataWriter =
            new CSVAsynchronousDataWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, dataWriter);
        try {
            container.initTarget();
            container.executeTarget();
            assertEquals(StubBenchmarkContainer3.ABORT_NUMBER - 1,
                dataWriter.getDataQueueSize());
            assertEquals(BenchmarkState.BENCHMARK_TERMINATED, container.getCurrentState());
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
    }
    
    /**
     *  The state must be "INITIALIZED" while synchronizer is locked,
     *  and the state must be "RUNNING" after the lock is released.
     */
    public void testRun() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer4");
        info.setName("StubBenchmarkContainer4");
        int repeatNumber = 2;
        info.setRepeatNumber(repeatNumber);
        LogWriter logWriter = new LogWriter(null);
        Synchronizer sync = new Synchronizer();
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            sync, logWriter, null);
        try {
            container.initTarget();
            sync.start();
            container.start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                fail();
            }
            assertEquals(BenchmarkState.INITIALIZED, container.getCurrentState());
            sync.interrupt();
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                fail();
            }
            assertEquals(BenchmarkState.RUNNING, container.getCurrentState());
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
    }
    
    /**
     *  The state must be "CLEANED" after the "clean" method.
     */
    public void testCleanTarget() {
        BenchmarkInfo info = new BenchmarkInfo();
        info.setClassName(
            "test.jp.co.scs.mbench.stub.StubBenchmarkContainer");
        info.setName("StubBenchmarkContainer");
        LogWriter logWriter = new LogWriter(null);
        BenchmarkContainer container = new BenchmarkContainer(0, info,
            null, logWriter, null);
        assertEquals(BenchmarkState.CREATED, container.getCurrentState());
        try {
            container.initTarget();
        } catch (BenchmarkTerminateException ex) {
            fail();
        }
        assertEquals(BenchmarkState.INITIALIZED, container.getCurrentState());
        container.cleanTarget();
        assertEquals(BenchmarkState.CLEANED, container.getCurrentState());
    }
}
