提交 4a489638 authored 作者: Thomas Mueller's avatar Thomas Mueller

Improve code coverage.

上级 ad26195b
......@@ -6,12 +6,13 @@
*/
package org.h2.store.fs;
import java.io.FileNotFoundException;
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.NonWritableChannelException;
/**
* File which uses NIO FileChannel.
......@@ -19,17 +20,21 @@ import java.nio.channels.FileLock;
public class FileObjectDiskChannel implements FileObject {
private final String name;
private FileChannel channel;
private final RandomAccessFile file;
private final FileChannel channel;
private FileLock lock;
private long length;
FileObjectDiskChannel(String fileName, String mode) throws FileNotFoundException {
FileObjectDiskChannel(String fileName, String mode) throws IOException {
this.name = fileName;
RandomAccessFile file = new RandomAccessFile(fileName, mode);
file = new RandomAccessFile(fileName, mode);
channel = file.getChannel();
length = file.length();
}
public void close() throws IOException {
channel.close();
file.close();
}
public long getFilePointer() throws IOException {
......@@ -37,7 +42,7 @@ public class FileObjectDiskChannel implements FileObject {
}
public String getName() {
return name;
return FileSystemDiskNio.PREFIX + name;
}
public long length() throws IOException {
......@@ -48,10 +53,9 @@ public class FileObjectDiskChannel implements FileObject {
if (len == 0) {
return;
}
// reading the size can reduce the performance
// if (channel.size() <= off + len) {
// throw new java.io.EOFException();
// }
if (channel.position() + len > length) {
throw new EOFException();
}
ByteBuffer buf = ByteBuffer.wrap(b);
buf.position(off);
buf.limit(off + len);
......@@ -65,7 +69,11 @@ public class FileObjectDiskChannel implements FileObject {
public void setFileLength(long newLength) throws IOException {
if (newLength <= channel.size()) {
long oldPos = channel.position();
channel.truncate(newLength);
try {
channel.truncate(newLength);
} catch (NonWritableChannelException e) {
throw new IOException("read only");
}
if (oldPos > newLength) {
oldPos = newLength;
}
......@@ -75,6 +83,7 @@ public class FileObjectDiskChannel implements FileObject {
ByteBuffer b = ByteBuffer.allocate(1);
channel.write(b, newLength - 1);
}
length = newLength;
}
public void sync() throws IOException {
......@@ -85,7 +94,11 @@ public class FileObjectDiskChannel implements FileObject {
ByteBuffer buf = ByteBuffer.wrap(b);
buf.position(off);
buf.limit(off + len);
channel.write(buf);
try {
channel.write(buf);
} catch (NonWritableChannelException e) {
throw new IOException("read only");
}
}
public synchronized boolean tryLock() {
......
......@@ -130,7 +130,7 @@ public class FileObjectDiskMapped implements FileObject {
}
public String getName() {
return name;
return FileSystemDiskNioMapped.PREFIX + name;
}
public long length() throws IOException {
......
......@@ -14,10 +14,12 @@ import java.io.IOException;
public class FileObjectMemory implements FileObject {
private final FileObjectMemoryData data;
private final boolean readOnly;
private long pos;
FileObjectMemory(FileObjectMemoryData data) {
FileObjectMemory(FileObjectMemoryData data, boolean readOnly) {
this.data = data;
this.readOnly = readOnly;
}
public long length() {
......@@ -25,7 +27,7 @@ public class FileObjectMemory implements FileObject {
}
public void setFileLength(long newLength) throws IOException {
data.touch();
data.touch(readOnly);
if (newLength < length()) {
pos = Math.min(pos, newLength);
}
......@@ -37,7 +39,7 @@ public class FileObjectMemory implements FileObject {
}
public void write(byte[] b, int off, int len) throws IOException {
data.touch();
data.touch(readOnly);
pos = data.readWrite(pos, b, off, len, true);
}
......@@ -57,18 +59,10 @@ public class FileObjectMemory implements FileObject {
// do nothing
}
public void setName(String name) {
data.setName(name);
}
public String getName() {
return data.getName();
}
public long getLastModified() {
return data.getLastModified();
}
public boolean tryLock() {
return data.tryLock();
}
......
......@@ -152,8 +152,8 @@ class FileObjectMemoryData {
/**
* Update the last modified time.
*/
void touch() throws IOException {
if (isReadOnly) {
void touch(boolean openReadOnly) throws IOException {
if (isReadOnly || openReadOnly) {
throw new IOException("Read only");
}
lastModified = System.currentTimeMillis();
......
......@@ -6,6 +6,7 @@
*/
package org.h2.store.fs;
import java.io.EOFException;
import java.io.IOException;
import org.h2.message.DbException;
import org.h2.util.IOUtils;
......@@ -55,6 +56,9 @@ public class FileObjectSplit implements FileObject {
}
public void readFully(byte[] b, int off, int len) throws IOException {
if (filePointer + len > length) {
throw new EOFException();
}
while (true) {
int l = read(b, off, len);
len -= l;
......@@ -149,7 +153,7 @@ public class FileObjectSplit implements FileObject {
}
public String getName() {
return name;
return FileSystemSplit.PREFIX + name;
}
public boolean tryLock() {
......
......@@ -15,7 +15,7 @@ import java.io.InputStream;
*/
public class FileSystemDiskNio extends FileSystemDisk {
private static final String PREFIX = "nio:";
static final String PREFIX = "nio:";
static {
FileSystem.register(new FileSystemDiskNio());
......
......@@ -14,7 +14,7 @@ import java.io.IOException;
*/
public class FileSystemDiskNioMapped extends FileSystemDiskNio {
private static final String PREFIX = "nioMapped:";
static final String PREFIX = "nioMapped:";
static {
FileSystem.register(new FileSystemDiskNioMapped());
......
......@@ -128,9 +128,9 @@ public class FileSystemMemory extends FileSystem {
public String normalize(String fileName) {
fileName = fileName.replace('\\', '/');
int idx = fileName.indexOf(":/");
if (idx > 0) {
fileName = fileName.substring(0, idx + 1) + fileName.substring(idx + 2);
int idx = fileName.indexOf(':') + 1;
if (fileName.length() >= idx && fileName.charAt(idx) != '/') {
fileName = fileName.substring(0, idx) + "/" + fileName.substring(idx);
}
return fileName;
}
......@@ -196,7 +196,7 @@ public class FileSystemMemory extends FileSystem {
public OutputStream openFileOutputStream(String fileName, boolean append) {
try {
FileObjectMemoryData obj = getMemoryFile(fileName);
FileObjectMemory m = new FileObjectMemory(obj);
FileObjectMemory m = new FileObjectMemory(obj, false);
return new FileObjectOutputStream(m, append);
} catch (IOException e) {
throw DbException.convertIOException(e, fileName);
......@@ -205,13 +205,13 @@ public class FileSystemMemory extends FileSystem {
public InputStream openFileInputStream(String fileName) {
FileObjectMemoryData obj = getMemoryFile(fileName);
FileObjectMemory m = new FileObjectMemory(obj);
FileObjectMemory m = new FileObjectMemory(obj, true);
return new FileObjectInputStream(m);
}
public FileObject openFileObject(String fileName, String mode) {
FileObjectMemoryData obj = getMemoryFile(fileName);
return new FileObjectMemory(obj);
return new FileObjectMemory(obj, "r".equals(mode));
}
private FileObjectMemoryData getMemoryFile(String fileName) {
......
......@@ -17,14 +17,16 @@ import org.h2.util.Utils;
*/
public class FileObjectDatabase implements FileObject {
private FileSystemDatabase db;
private String fileName;
private final FileSystemDatabase db;
private final boolean readOnly;
private final String fileName;
private byte[] data;
private int pos, length;
private boolean changed;
FileObjectDatabase(FileSystemDatabase db, String fileName, byte[] data, boolean changed) {
FileObjectDatabase(FileSystemDatabase db, String fileName, byte[] data, boolean changed, boolean readOnly) {
this.db = db;
this.readOnly = readOnly;
this.fileName = fileName;
this.data = data;
this.length = data.length;
......@@ -55,7 +57,10 @@ public class FileObjectDatabase implements FileObject {
this.pos = (int) newPos;
}
public void setFileLength(long newLength) {
public void setFileLength(long newLength) throws IOException {
if (readOnly) {
throw new IOException("read only");
}
this.length = (int) newLength;
if (length != data.length) {
byte[] n = Utils.newBytes(length);
......@@ -73,7 +78,10 @@ public class FileObjectDatabase implements FileObject {
}
}
public void write(byte[] b, int off, int len) {
public void write(byte[] b, int off, int len) throws IOException {
if (readOnly) {
throw new IOException("read only");
}
if (pos + len > data.length) {
int newLen = Math.max(data.length * 2, pos + len);
byte[] n = Utils.newBytes(newLen);
......
......@@ -378,9 +378,9 @@ public class FileSystemDatabase extends FileSystem {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copyAndClose(in, out);
byte[] data = out.toByteArray();
return new FileObjectDatabase(this, fileName, data, false);
return new FileObjectDatabase(this, fileName, data, false, "r".equals(mode));
}
return new FileObjectDatabase(this, fileName, new byte[0], true);
return new FileObjectDatabase(this, fileName, new byte[0], true, "r".equals(mode));
} catch (SQLException e) {
throw convert(e);
}
......
......@@ -8,6 +8,7 @@ package org.h2.test.unit;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
......@@ -43,7 +44,8 @@ public class TestFileSystem extends TestBase {
testDatabaseInMemFileSys();
testDatabaseInJar();
// set default part size to 1 << 10
FileSystem.getInstance("split:10:" + getBaseDir() + "/fs");
String f = "split:10:" + getBaseDir() + "/fs";
FileSystem.getInstance(f).getAbsolutePath(f);
testFileSystem(getBaseDir() + "/fs");
testFileSystem(FileSystemMemory.PREFIX);
FileSystemDatabase fs = FileSystemDatabase.register("jdbc:h2:mem:fs");
......@@ -55,9 +57,16 @@ public class TestFileSystem extends TestBase {
try {
if (!config.splitFileSystem) {
testFileSystem("split:" + getBaseDir() + "/fs");
testFileSystem("nio:" + getBaseDir() + "/fs");
testFileSystem("nioMapped:" + getBaseDir() + "/fs");
testFileSystem("split:nioMapped:" + getBaseDir() + "/fs");
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} catch (Error e) {
e.printStackTrace();
throw e;
} finally {
IOUtils.delete(getBaseDir() + "/fs");
}
......@@ -160,11 +169,35 @@ public class TestFileSystem extends TestBase {
random.nextBytes(buffer);
fo.write(buffer, 0, 10000);
fo.seek(20000);
assertEquals(20000, fo.getFilePointer());
try {
fo.readFully(buffer, 0, 1);
fail();
} catch (EOFException e) {
// expected
}
assertEquals(fsBase + "/test", fo.getName());
assertEquals("test", fs.getFileName(fo.getName()));
assertEquals(fsBase, fs.getParent(fo.getName()));
fo.tryLock();
fo.releaseLock();
fo.close();
fo = fs.openFileObject(fsBase + "/test", "r");
byte[] test = new byte[10000];
fo.readFully(test, 0, 10000);
assertEquals(buffer, test);
try {
fo.write(test, 0, 10);
fail();
} catch (IOException e) {
// expected
}
try {
fo.setFileLength(10);
fail();
} catch (IOException e) {
// expected
}
fo.close();
long lastMod = fs.getLastModified(fsBase + "/test");
if (lastMod < time - 1999) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论