/**
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.commons.utils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedList;
import junit.framework.Assert;
import org.exoplatform.component.test.AbstractGateInTest;
import org.gatein.common.io.UndeclaredIOException;
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
public class TestOutputStreamPrinter extends AbstractGateInTest {
static final int NOOP = -1;
static final int WRITE = 0;
static final int FLUSH = 1;
static final int CLOSE = 2;
public void testIOExceptionBlocking() {
internalTest(IOFailureFlow.RETHROW, true);
}
public void testUndeclaredIOExceptionBlocking() {
internalTest(IOFailureFlow.THROW_UNDECLARED, true);
}
public void testIgnoreIOExceptionBlocking() {
internalTest(IOFailureFlow.IGNORE, true);
}
public void testIOExceptionNoBlocking() {
internalTest(IOFailureFlow.RETHROW, false);
}
public void testUndeclaredIOExceptionNoBlocking() {
internalTest(IOFailureFlow.THROW_UNDECLARED, false);
}
public void testIgnoreIOExceptionNoBlocking() {
internalTest(IOFailureFlow.IGNORE, false);
}
public void internalTest(IOFailureFlow mode, boolean blockOnFailure) {
int writeAfterFailure = blockOnFailure ? NOOP : WRITE;
int flushAfterFailure = blockOnFailure ? NOOP : FLUSH;
//
TestOutputStream out = new TestOutputStream(true, mode, blockOnFailure);
out.write(mode);
out.assertOperation(WRITE).assertEmpty().wantFailure = false;
out.flush(IOFailureFlow.IGNORE);
out.assertOperation(flushAfterFailure).assertEmpty();
out.write(IOFailureFlow.IGNORE);
out.assertOperation(writeAfterFailure).assertEmpty();
out.close(IOFailureFlow.IGNORE);
out.assertOperation(CLOSE).assertEmpty();
//
out = new TestOutputStream(false, mode, blockOnFailure);
out.write(IOFailureFlow.IGNORE);
out.assertOperation(WRITE).assertEmpty().wantFailure = true;
out.flush(mode);
out.assertOperation(FLUSH).assertEmpty().wantFailure = false;
out.write(IOFailureFlow.IGNORE);
out.assertOperation(writeAfterFailure).assertEmpty();
out.close(IOFailureFlow.IGNORE);
out.assertOperation(CLOSE).assertEmpty();
//
out = new TestOutputStream(false, mode, blockOnFailure);
out.write(IOFailureFlow.IGNORE);
out.assertOperation(WRITE).assertEmpty();
out.flush(IOFailureFlow.IGNORE);
out.assertOperation(FLUSH).assertEmpty().wantFailure = true;
out.write(mode);
out.assertOperation(WRITE).assertEmpty().wantFailure = false;
out.close(IOFailureFlow.IGNORE);
out.assertOperation(CLOSE).assertEmpty();
//
out = new TestOutputStream(false, mode, blockOnFailure);
out.write(IOFailureFlow.IGNORE);
out.assertOperation(WRITE).assertEmpty();
out.flush(IOFailureFlow.IGNORE);
out.assertOperation(FLUSH).assertEmpty();
out.write(IOFailureFlow.IGNORE);
out.assertOperation(WRITE).assertEmpty().wantFailure = true;
out.close(mode);
out.assertOperation(CLOSE).assertEmpty();
}
private static class TestOutputStream extends OutputStream {
boolean wantFailure = false;
final LinkedList<Integer> operations = new LinkedList<Integer>();
OutputStreamPrinter osp;
private TestOutputStream(boolean wantFailure, IOFailureFlow mode, boolean blockOnFailure) {
this.wantFailure = wantFailure;
this.osp = new OutputStreamPrinter(CharsetTextEncoder.getUTF8(), this, mode, blockOnFailure, false, 0);
}
public void write(int b) throws IOException {
operations.add(WRITE);
if (wantFailure) {
throw new IOException();
}
}
@Override
public void flush() throws IOException {
operations.add(FLUSH);
if (wantFailure) {
throw new IOException();
}
}
@Override
public void close() throws IOException {
operations.add(CLOSE);
if (wantFailure) {
throw new IOException();
}
}
public void write(IOFailureFlow mode) {
switch (mode) {
case RETHROW:
try {
osp.write("a");
fail();
} catch (IOException ignore) {
}
break;
case THROW_UNDECLARED:
try {
osp.write("a");
fail();
} catch (UndeclaredIOException ignore) {
} catch (IOException expected) {
fail();
}
break;
case IGNORE:
try {
osp.write("a");
} catch (UndeclaredIOException ignore) {
fail();
} catch (IOException expected) {
fail();
}
break;
}
}
public void flush(IOFailureFlow mode) {
switch (mode) {
case RETHROW:
try {
osp.flush();
fail();
} catch (IOException ignore) {
}
break;
case THROW_UNDECLARED:
try {
osp.flush();
fail();
} catch (UndeclaredIOException ignore) {
} catch (IOException e) {
fail();
}
break;
case IGNORE:
try {
osp.flush();
} catch (IOException e) {
fail();
}
break;
}
}
public void close(IOFailureFlow mode) {
switch (mode) {
case RETHROW:
try {
osp.close();
fail();
} catch (IOException ignore) {
}
break;
case THROW_UNDECLARED:
try {
osp.close();
fail();
} catch (UndeclaredIOException ignore) {
} catch (IOException e) {
fail();
}
break;
case IGNORE:
try {
osp.close();
} catch (IOException e) {
fail();
}
break;
}
}
public TestOutputStream assertEmpty() {
Assert.assertTrue(operations.isEmpty());
return this;
}
public TestOutputStream assertOperation(int operation) {
if (operation != NOOP) {
Assert.assertFalse(operations.isEmpty());
int actual = operations.removeFirst();
Assert.assertEquals(operation, actual);
}
return this;
}
}
}