/*                          
 * 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 java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.StringTokenizer;

import jp.co.scs.mbench.BenchmarkTerminateException;
import jp.co.scs.mbench.LogWriter;
import junit.framework.TestCase;

/**
 *      @author Tetsuro Ikeda
 */
public class LogWriterTest extends TestCase {

    private static final String LOG_FILE_NAME = "testlog";

    public static final int LOG_DEBUG = 0;

    public static final int LOG_INFO = 1;
    
    public static final int LOG_ERROR = 2;

    public static final String LOG_DEGUB_MESSAGE = "hoge";
    
    public static final String LOG_INFO_MESSAGE = "foo";

    public static final String LOG_ERROR_MESSAGE = "bar";
    
    /**
     *  Log writer thread must be started if "init" method was invoked.
     */
    public void testInit() {
        LogWriter logWriter = new LogWriter(LOG_FILE_NAME);
        try {
            logWriter.init();
            assertTrue(logWriter.isInitialized());
        } catch (BenchmarkTerminateException ex) {
            fail(ex.getMessage());
        } finally {
            logWriter.clean();
            FileUtil.deleteFile(LOG_FILE_NAME);
        }
    }
    
    /**
     *  Only the same or upper level of log must be in the queue.
     */
    public void testWrite() {
        LogWriter logWriter = new LogWriter(LOG_FILE_NAME);
        try {
            logWriter.init();
            logWriter.setLogLevel(LOG_INFO);
            logWriter.write(LOG_DEBUG, LOG_DEGUB_MESSAGE);
            logWriter.write(LOG_INFO, LOG_INFO_MESSAGE);
            logWriter.write(LOG_ERROR, LOG_ERROR_MESSAGE);
            
            assertEquals(2, logWriter.getLogQueueSize());
        } catch (BenchmarkTerminateException ex) {
            fail(ex.getMessage());
        } finally {
            logWriter.clean();
            FileUtil.deleteFile(LOG_FILE_NAME);
        }
    }
    
    /**
     *  The log in queue must be printed out if run method is called.
     */
    public void testRun() {
        LogWriter logWriter = new LogWriter(LOG_FILE_NAME);
        ByteArrayOutputStream output1 = new ByteArrayOutputStream();
        ByteArrayOutputStream output2 = new ByteArrayOutputStream();
        PrintStream defaultOut = System.out;
        PrintStream defaultErr = System.err;
        System.setOut(new PrintStream(output1));
        System.setErr(new PrintStream(output2));
        
        try {
            logWriter.init();
            logWriter.setLogLevel(LOG_INFO);
            logWriter.write(LOG_DEBUG, LOG_DEGUB_MESSAGE);
            logWriter.write(LOG_INFO, LOG_INFO_MESSAGE);
            logWriter.write(LOG_ERROR, LOG_ERROR_MESSAGE);
            logWriter.clean();
            
            String lineSeparator = System.getProperty("line.separator");
            String infoString = output1.toString();
            StringTokenizer stringTokennizer =
                new StringTokenizer(infoString, lineSeparator);
            String lineString = null;

            while (stringTokennizer.hasMoreTokens()) {
                lineString = stringTokennizer.nextToken();
                assertTrue(lineString.endsWith("[INFO]foo"));
            }

            String errorString = output2.toString();
            stringTokennizer =
                new StringTokenizer(errorString, lineSeparator);
            
            while (stringTokennizer.hasMoreTokens()) {
                lineString = stringTokennizer.nextToken();
                assertTrue(lineString.endsWith("[ERROR]bar"));
            }
            
            assertTrue(FileUtil.existsFile(LOG_FILE_NAME));
        } catch (BenchmarkTerminateException ex) {
            fail(ex.getMessage());
        } catch (Exception ex) {
            fail(ex.getMessage());
        } finally {
            FileUtil.deleteFile(LOG_FILE_NAME);
            System.setOut(defaultOut);
            System.setErr(defaultErr);
        }
    }

    /**
     *  Log writer thread must be ended if "clean" method is invoked.
     */
    public void testClean() {
        LogWriter logWriter = new LogWriter(LOG_FILE_NAME);
        try {
            logWriter.init();
            logWriter.setLogLevel(LOG_INFO);
            logWriter.write(LOG_DEBUG, LOG_DEGUB_MESSAGE);
            logWriter.write(LOG_INFO, LOG_INFO_MESSAGE);
            logWriter.write(LOG_ERROR, LOG_ERROR_MESSAGE);
            logWriter.clean();

            assertFalse(logWriter.isRunning());
        } catch (BenchmarkTerminateException ex) {
            fail(ex.getMessage());
        } finally {
            FileUtil.deleteFile(LOG_FILE_NAME);
        }
    }
}
