001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (license2)
004: * Initial Developer: H2 Group
005: */
006: package org.h2.test.unit;
007:
008: import java.io.EOFException;
009: import java.io.File;
010: import java.io.InputStream;
011: import java.io.OutputStream;
012: import java.io.RandomAccessFile;
013: import java.sql.Connection;
014: import java.sql.DriverManager;
015: import java.sql.ResultSet;
016: import java.sql.Statement;
017: import java.util.Random;
018:
019: import org.h2.store.fs.FileObject;
020: import org.h2.store.fs.FileSystem;
021: import org.h2.test.TestBase;
022:
023: /**
024: * Tests various file system.
025: */
026: public class TestFileSystem extends TestBase {
027:
028: public void test() throws Exception {
029: testDatabaseInJar();
030: testFileSystem(baseDir + "/fs");
031: testFileSystem(FileSystem.MEMORY_PREFIX);
032: // testFileSystem("jdbc:h2:mem:fs;TRACE_LEVEL_FILE=3");
033: testFileSystem("jdbc:h2:mem:fs");
034: testFileSystem(FileSystem.MEMORY_PREFIX_LZF);
035: testUserHome();
036: }
037:
038: private void testDatabaseInJar() throws Exception {
039: if (config.networked) {
040: return;
041: }
042: Class.forName("org.h2.Driver");
043: String url = "jdbc:h2:" + baseDir + "/fsJar";
044: Connection conn = DriverManager.getConnection(url, "sa", "sa");
045: Statement stat = conn.createStatement();
046: stat
047: .execute("create table test(id int primary key, name varchar, b blob, c clob)");
048: stat
049: .execute("insert into test values(1, 'Hello', SECURE_RAND(2000), space(2000))");
050: ResultSet rs;
051: rs = stat.executeQuery("select * from test");
052: rs.next();
053: byte[] b1 = rs.getBytes(3);
054: String s1 = rs.getString(4);
055: conn.close();
056: conn = DriverManager.getConnection(url, "sa", "sa");
057: stat = conn.createStatement();
058: stat.execute("backup to '" + baseDir + "/fsJar.zip'");
059: conn.close();
060:
061: deleteDb("fsJar");
062: FileSystem fs = FileSystem.getInstance("zip:" + baseDir
063: + "/fsJar.zip");
064: String[] files = fs.listFiles("zip:" + baseDir + "/fsJar.zip");
065: for (int i = 0; i < files.length; i++) {
066: String f = files[i];
067: check(fs.isAbsolute(f));
068: check(!fs.isDirectory(f));
069: check(fs.length(f) > 0);
070: check(f.endsWith(fs.getFileName(f)));
071: }
072: String urlJar = "jdbc:h2:zip:" + baseDir + "/fsJar.zip!/fsJar";
073: conn = DriverManager.getConnection(urlJar, "sa", "sa");
074: stat = conn.createStatement();
075: rs = stat.executeQuery("select * from test");
076: rs.next();
077: check(1, rs.getInt(1));
078: check("Hello", rs.getString(2));
079: byte[] b2 = rs.getBytes(3);
080: String s2 = rs.getString(4);
081: check(2000, b2.length);
082: check(2000, s2.length());
083: check(b1, b2);
084: check(s1, s2);
085: checkFalse(rs.next());
086: conn.close();
087: }
088:
089: private void testUserHome() throws Exception {
090: FileSystem fs = FileSystem.getInstance("~/test");
091: String fileName = fs.getAbsolutePath("~/test");
092: String userDir = System.getProperty("user.home");
093: check(fileName.startsWith(userDir));
094: }
095:
096: private void testFileSystem(String fsBase) throws Exception {
097: testSimple(fsBase);
098: testTempFile(fsBase);
099: testRandomAccess(fsBase);
100: }
101:
102: private void testSimple(String fsBase) throws Exception {
103: FileSystem fs = FileSystem.getInstance(fsBase);
104: long time = System.currentTimeMillis();
105: String[] list = fs.listFiles(fsBase);
106: for (int i = 0; i < list.length; i++) {
107: fs.delete(list[i]);
108: }
109: fs.mkdirs(fsBase + "/test");
110: fs.delete(fsBase + "/test");
111: fs.delete(fsBase + "/test2");
112: check(fs.createNewFile(fsBase + "/test"));
113: check(fs.canWrite(fsBase + "/test"));
114: FileObject fo = fs.openFileObject(fsBase + "/test", "rw");
115: byte[] buffer = new byte[10000];
116: Random random = new Random(1);
117: random.nextBytes(buffer);
118: fo.write(buffer, 0, 10000);
119: fo.close();
120: long lastMod = fs.getLastModified(fsBase + "/test");
121: if (lastMod < time - 1999) {
122: // at most 2 seconds difference
123: check(lastMod, time);
124: }
125: check(fs.length(fsBase + "/test"), 10000);
126: list = fs.listFiles(fsBase);
127: check(list.length, 1);
128: check(list[0].endsWith("test"));
129:
130: fs.copy(fsBase + "/test", fsBase + "/test3");
131: fs.rename(fsBase + "/test3", fsBase + "/test2");
132: check(!fs.exists(fsBase + "/test3"));
133: check(fs.exists(fsBase + "/test2"));
134: check(fs.length(fsBase + "/test2"), 10000);
135: byte[] buffer2 = new byte[10000];
136: InputStream in = fs.openFileInputStream(fsBase + "/test2");
137: int pos = 0;
138: while (true) {
139: int l = in.read(buffer2, pos, Math.min(10000 - pos, 1000));
140: if (l <= 0) {
141: break;
142: }
143: pos += l;
144: }
145: in.close();
146: check(pos, 10000);
147: check(buffer2, buffer);
148:
149: check(fs.tryDelete(fsBase + "/test2"));
150: fs.delete(fsBase + "/test");
151:
152: if (!fsBase.startsWith(FileSystem.MEMORY_PREFIX)
153: && !fsBase.startsWith(FileSystem.MEMORY_PREFIX_LZF)) {
154: fs.createDirs(fsBase + "/testDir/test");
155: check(fs.isDirectory(fsBase + "/testDir"));
156: if (!fsBase.startsWith(FileSystem.DB_PREFIX)) {
157: fs.deleteRecursive("/testDir");
158: check(!fs.exists("/testDir"));
159: }
160: }
161: }
162:
163: private void testRandomAccess(String fsBase) throws Exception {
164: FileSystem fs = FileSystem.getInstance(fsBase);
165: String s = fs.createTempFile(fsBase + "/temp", ".tmp", false,
166: false);
167: File file = new File(baseDir + "/temp");
168: file.delete();
169: RandomAccessFile ra = new RandomAccessFile(file, "rw");
170: fs.delete(s);
171: FileObject f = fs.openFileObject(s, "rw");
172: try {
173: f.readFully(new byte[1], 0, 1);
174: error();
175: } catch (EOFException e) {
176: // expected
177: }
178: f.sync();
179: Random random = new Random(1);
180: int size = getSize(100, 500);
181: for (int i = 0; i < size; i++) {
182: int pos = random.nextInt(10000);
183: switch (random.nextInt(7)) {
184: case 0: {
185: pos = (int) Math.min(pos, ra.length());
186: trace("seek " + pos);
187: f.seek(pos);
188: ra.seek(pos);
189: break;
190: }
191: case 1: {
192: byte[] buffer = new byte[random.nextInt(1000)];
193: random.nextBytes(buffer);
194: trace("write " + buffer.length);
195: f.write(buffer, 0, buffer.length);
196: ra.write(buffer, 0, buffer.length);
197: break;
198: }
199: case 2: {
200: f.setFileLength(pos);
201: ra.setLength(pos);
202: if (ra.getFilePointer() > pos) {
203: f.seek(0);
204: ra.seek(0);
205: }
206: trace("setLength " + pos);
207: break;
208: }
209: case 3: {
210: int len = random.nextInt(1000);
211: len = (int) Math.min(len, ra.length()
212: - ra.getFilePointer());
213: byte[] b1 = new byte[len];
214: byte[] b2 = new byte[len];
215: f.readFully(b1, 0, len);
216: ra.readFully(b2, 0, len);
217: trace("readFully " + len);
218: check(b1, b2);
219: break;
220: }
221: case 4: {
222: trace("getFilePointer");
223: check(f.getFilePointer(), ra.getFilePointer());
224: break;
225: }
226: case 5: {
227: trace("length " + ra.length());
228: check(f.length(), ra.length());
229: break;
230: }
231: case 6: {
232: trace("reopen");
233: f.close();
234: ra.close();
235: ra = new RandomAccessFile(file, "rw");
236: f = fs.openFileObject(s, "rw");
237: check(f.length(), ra.length());
238: break;
239: }
240: }
241: }
242: f.close();
243: ra.close();
244: }
245:
246: private void testTempFile(String fsBase) throws Exception {
247: FileSystem fs = FileSystem.getInstance(fsBase);
248: String s = fs.createTempFile(fsBase + "/temp", ".tmp", false,
249: false);
250: OutputStream out = fs.openFileOutputStream(s, false);
251: byte[] buffer = new byte[10000];
252: out.write(buffer);
253: out.close();
254: out = fs.openFileOutputStream(s, true);
255: out.write(1);
256: out.close();
257: InputStream in = fs.openFileInputStream(s);
258: for (int i = 0; i < 10000; i++) {
259: check(in.read(), 0);
260: }
261: check(in.read(), 1);
262: check(in.read(), -1);
263: in.close();
264: out.close();
265: }
266:
267: }
|