blob: 1f6187a2f4f43f0f9a2620355ae766526fb60525 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.tests.internal.localstore;
import java.io.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.localstore.*;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.runtime.IPath;
public class SafeChunkyInputOutputStreamTest extends LocalStoreTest {
protected File temp;
public SafeChunkyInputOutputStreamTest() {
super();
}
public SafeChunkyInputOutputStreamTest(String name) {
super(name);
}
protected boolean compare(byte[] source, byte[] target) {
if (source.length != target.length) {
return false;
}
for (int i = 0; i < target.length; i++) {
if (source[i] != target[i]) {
return false;
}
}
return true;
}
protected byte[] merge(byte[] b1, byte[] b2) {
byte[] result = new byte[b1.length + b2.length];
for (int i = 0; i < b1.length; i++) {
result[i] = b1[i];
}
for (int i = 0; i < b2.length; i++) {
result[b1.length + i] = b2[i];
}
return result;
}
@Override
protected void setUp() throws Exception {
super.setUp();
IPath location = getRandomLocation();
temp = location.append("temp").toFile();
temp.mkdirs();
assertTrue("could not create temp directory", temp.isDirectory());
}
public static Test suite() {
return new TestSuite(SafeChunkyInputOutputStreamTest.class);
}
@Override
protected void tearDown() throws Exception {
ensureDoesNotExistInFileSystem(temp.getParentFile());
super.tearDown();
}
public void testBufferLimit() {
File target = new File(temp, "target");
Workspace.clear(target); // make sure there was nothing here before
assertTrue("1.0", !target.exists());
// use only one chunk but bigger than the buffer
int bufferSize = 10024;
byte[] chunk = getBigContents(bufferSize);
SafeChunkyOutputStream output = null;
try {
output = new SafeChunkyOutputStream(target);
try {
output.write(chunk);
output.succeed();
} finally {
output.close();
}
} catch (IOException e) {
fail("2.0", e);
}
// read chunks
SafeChunkyInputStream input = null;
try {
input = new SafeChunkyInputStream(target);
try {
byte[] read = new byte[chunk.length];
assertTrue("3.0", input.read(read) == chunk.length);
assertTrue("3.6", compare(chunk, read));
} finally {
input.close();
}
} catch (IOException e) {
fail("3.20", e);
}
Workspace.clear(target); // make sure there was nothing here before
}
public void testFailure() {
File target = new File(temp, "target");
Workspace.clear(target); // make sure there was nothing here before
assertTrue("1.0", !target.exists());
// misc
byte[] fakeEnd = new byte[ILocalStoreConstants.END_CHUNK.length];
System.arraycopy(ILocalStoreConstants.END_CHUNK, 0, fakeEnd, 0, ILocalStoreConstants.END_CHUNK.length);
fakeEnd[fakeEnd.length - 1] = 86;
// write chunks
byte[] chunk1 = getRandomString().getBytes();
byte[] chunk2 = getRandomString().getBytes();
byte[] chunk3 = getRandomString().getBytes();
byte[] chunk4 = getRandomString().getBytes();
byte[] chunk5 = getRandomString().getBytes();
byte[] chunk6 = getRandomString().getBytes();
SafeChunkyOutputStream output = null;
try {
output = new SafeChunkyOutputStream(target);
try {
output.write(chunk1);
output.succeed();
doNothing(output);
output = new SafeChunkyOutputStream(target);
// fake failure
output.write(chunk2);
output.write(ILocalStoreConstants.BEGIN_CHUNK); // another begin
output.succeed();
//
doNothing(output);
output = new SafeChunkyOutputStream(target);
output.write(chunk3);
output.succeed();
doNothing(output);
output = new SafeChunkyOutputStream(target);
// fake failure
output.write(chunk4);
output.write(ILocalStoreConstants.END_CHUNK); // another end
output.succeed();
doNothing(output);
//
output = new SafeChunkyOutputStream(target);
output.write(chunk5);
output.succeed();
// fake failure
output.write(fakeEnd);
output.write(chunk6);
output.succeed();
} finally {
output.close();
}
} catch (IOException e) {
fail("2.0", e);
}
// read chunks
SafeChunkyInputStream input = null;
try {
input = new SafeChunkyInputStream(target);
try {
byte[] read1 = new byte[chunk1.length];
//byte[] read2 = new byte[chunk2.length];
byte[] read3 = new byte[chunk3.length];
byte[] read4 = new byte[chunk4.length];
byte[] read5 = new byte[chunk5.length];
byte[] read6 = new byte[fakeEnd.length + chunk6.length];
assertTrue("3.0", input.read(read1) == chunk1.length);
//assert("3.1", input.read(read2) == chunk2.length);
assertTrue("3.2", input.read(read3) == chunk3.length);
assertTrue("3.3", input.read(read4) == chunk4.length);
assertTrue("3.4", input.read(read5) == chunk5.length);
assertTrue("3.5", input.read(read6) == (fakeEnd.length + chunk6.length));
assertTrue("3.6", compare(chunk1, read1));
//assert("3.7", compare(chunk2, read2));
assertTrue("3.8", compare(chunk3, read3));
assertTrue("3.9", compare(chunk4, read4));
assertTrue("3.10", compare(chunk5, read5));
byte[] expected = merge(fakeEnd, chunk6);
assertTrue("3.11", compare(expected, read6));
} finally {
input.close();
}
} catch (IOException e) {
fail("3.20", e);
}
Workspace.clear(target); // make sure there was nothing here before
}
/**
* This method is used to trick the java compiler to avoid reporting
* a warning that the stream was not closed. In this test we are intentionally
* not closing the stream to test recovery from failure.
*/
private void doNothing(SafeChunkyOutputStream output) {
}
public void testAlmostEmpty() {
File target = new File(temp, "target");
Workspace.clear(target); // make sure there was nothing here before
assertTrue("1.0", !target.exists());
// open the file but don't write anything.
SafeChunkyOutputStream output = null;
try {
output = new SafeChunkyOutputStream(target);
} catch (IOException e) {
fail("1.0", e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
fail("1.1", e);
}
}
}
DataInputStream input = null;
try {
input = new DataInputStream(new SafeChunkyInputStream(target));
input.readUTF();
fail("2.0");
} catch (EOFException e) {
// should hit here
} catch (IOException e) {
fail("2.1", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
fail("2.2", e);
}
}
}
}
public void testSimple() {
File target = new File(temp, "target");
Workspace.clear(target); // make sure there was nothing here before
assertTrue("1.0", !target.exists());
// write chunks
byte[] chunk1 = getRandomString().getBytes();
byte[] chunk2 = getRandomString().getBytes();
byte[] chunk3 = getRandomString().getBytes();
byte[] chunk4 = getRandomString().getBytes();
byte[] chunk5 = getRandomString().getBytes();
SafeChunkyOutputStream output = null;
try {
output = new SafeChunkyOutputStream(target);
try {
output.write(chunk1);
output.succeed();
output.write(chunk2);
output.succeed();
output.write(chunk3);
output.succeed();
output.write(chunk4);
output.succeed();
output.write(chunk5);
output.succeed();
} finally {
output.close();
}
} catch (IOException e) {
fail("2.0", e);
}
// read chunks
SafeChunkyInputStream input = null;
try {
input = new SafeChunkyInputStream(target);
try {
byte[] read1 = new byte[chunk1.length];
byte[] read2 = new byte[chunk2.length];
byte[] read3 = new byte[chunk3.length];
byte[] read4 = new byte[chunk4.length];
byte[] read5 = new byte[chunk5.length];
assertTrue("3.0", input.read(read1) == chunk1.length);
assertTrue("3.1", input.read(read2) == chunk2.length);
assertTrue("3.2", input.read(read3) == chunk3.length);
assertTrue("3.3", input.read(read4) == chunk4.length);
assertTrue("3.4", input.read(read5) == chunk5.length);
assertTrue("3.5", compare(chunk1, read1));
assertTrue("3.6", compare(chunk2, read2));
assertTrue("3.7", compare(chunk3, read3));
assertTrue("3.8", compare(chunk4, read4));
assertTrue("3.9", compare(chunk5, read5));
} finally {
input.close();
}
} catch (IOException e) {
fail("3.10", e);
}
Workspace.clear(target); // make sure there was nothing here before
}
}