package javax.microedition.io.file; import javax.microedition.io.*; import java.util.Enumeration; import java.util.Vector; import java.util.Hashtable; import java.io.*; import gnu.testlet.TestHarness; import gnu.testlet.Testlet; public class TestFileConnection implements Testlet { public int getExpectedPass() { return 169; } public int getExpectedFail() { return 0; } public int getExpectedKnownFail() { return 0; } String dirPath; FileConnection dir; void testListFilter(TestHarness th) throws IOException { Vector provaDirFiles = new Vector(); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/prova1.doc")); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/prova2.doc")); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/prova3.doc")); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/.doc")); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/marco_it.res")); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/marco_en.res")); provaDirFiles.addElement(Connector.open(dirPath + "provaDir/marco_")); FileConnection subDir = (FileConnection)Connector.open(dirPath + "provaDir/subDir"); subDir.mkdir(); for (int i = 0; i < provaDirFiles.size(); i++) { FileConnection file = (FileConnection)provaDirFiles.elementAt(i); file.create(); } Hashtable expected = new Hashtable(); Enumeration files = dir.list("*.doc", false); th.check(files.hasMoreElements(), "Elements found"); expected.put(".doc", ""); expected.put("prova1.doc", ""); expected.put("prova2.doc", ""); expected.put("prova3.doc", ""); while (files.hasMoreElements()) { String file = (String)files.nextElement(); th.check(expected.remove(file) != null); } th.check(expected.isEmpty(), "Only 3 elements found"); files = dir.list("marco_*.res", false); th.check(files.hasMoreElements(), "Elements found"); expected.put("marco_it.res", ""); expected.put("marco_en.res", ""); while (files.hasMoreElements()) { String file = (String)files.nextElement(); th.check(expected.remove(file) != null); } th.check(expected.isEmpty(), "Only 2 elements found"); files = dir.list("m*.re*", false); th.check(files.hasMoreElements(), "Elements found"); expected.put("marco_it.res", ""); expected.put("marco_en.res", ""); while (files.hasMoreElements()) { String file = (String)files.nextElement(); th.check(expected.remove(file) != null); } th.check(expected.isEmpty(), "Only 2 elements found"); files = dir.list("*.js", false); th.check(!files.hasMoreElements(), "No elements found"); files = dir.list("sub*", false); th.check(files.hasMoreElements(), "Elements found"); expected.put("subDir/", ""); while (files.hasMoreElements()) { String file = (String)files.nextElement(); th.check(expected.remove(file) != null); } th.check(expected.isEmpty(), "Only 1 element found"); for (int i = 0; i < provaDirFiles.size(); i++) { FileConnection file = (FileConnection)provaDirFiles.elementAt(i); file.delete(); file.close(); } subDir.delete(); subDir.close(); } void testLastModified(TestHarness th) throws IOException { FileConnection file = (FileConnection)Connector.open(dirPath + "provaDir/stat.txt"); long lastTime; long modifiedTime; modifiedTime = file.lastModified(); th.check(modifiedTime, 0L, "nonexistent file has '0' mtime"); lastTime = modifiedTime; try { Thread.sleep(1); } catch (Exception e) {} file.create(); modifiedTime = file.lastModified(); th.check(modifiedTime > lastTime, "create updates mtime"); lastTime = modifiedTime; try { Thread.sleep(1); } catch (Exception e) {} OutputStream out = file.openOutputStream(); modifiedTime = file.lastModified(); th.check(modifiedTime, lastTime, "open output stream doesn't update mtime"); lastTime = modifiedTime; out.write(new byte[]{ 4, 3, 2, 1 }); modifiedTime = file.lastModified(); th.check(modifiedTime, lastTime, "write to output stream doesn't update mtime"); lastTime = modifiedTime; out.close(); modifiedTime = file.lastModified(); th.check(modifiedTime > lastTime, "close output stream updates mtime"); lastTime = modifiedTime; try { Thread.sleep(1); } catch (Exception e) {} file.truncate(4); modifiedTime = file.lastModified(); th.check(modifiedTime, lastTime, "truncate to same size doesn't update mtime"); lastTime = modifiedTime; // FileConnection.truncate behaves differently from ftruncate // when the new size is greater than the existing size of the file. // In that case, ftruncate increases the size of the file, // while FileConnection.truncate returns early without changing it. try { Thread.sleep(1); } catch (Exception e) {} file.truncate(5); modifiedTime = file.lastModified(); th.check(modifiedTime, lastTime, "truncate to larger size doesn't update mtime"); lastTime = modifiedTime; try { Thread.sleep(1); } catch (Exception e) {} file.truncate(3); modifiedTime = file.lastModified(); th.check(modifiedTime > lastTime, "truncate to smaller size updates mtime"); lastTime = modifiedTime; file.delete(); modifiedTime = file.lastModified(); th.check(modifiedTime, 0L, "deleted file has '0' mtime"); lastTime = modifiedTime; file.close(); } void testIgnoredFile(TestHarness th) throws IOException { FileConnection file = (FileConnection)Connector.open(dirPath + "ignored-file"); th.check(file.exists(), "ignored file exists"); th.check(file.lastModified(), 0L, "ignored file isn't modified"); th.check(file.fileSize(), 0, "ignored file is empty"); OutputStream out = file.openOutputStream(); out.write(new byte[]{ 7, 6, 5, 4, 3, 2, 1 }); out.close(); th.check(file.lastModified(), 0L, "ignored file isn't modified after write"); th.check(file.fileSize(), 0, "ignored file is empty after write"); file.truncate(3); th.check(file.lastModified(), 0L, "ignored file isn't modified after truncate"); th.check(file.fileSize(), 0, "ignored file is empty after truncate"); InputStream in = file.openInputStream(); th.check(in.read(), -1, "ignored file read returns no data"); in.close(); file.delete(); th.check(file.exists(), "ignored file exists after delete"); th.check(file.lastModified(), 0L, "ignored file isn't modified after delete"); file.close(); } class CreateFileThread extends Thread { String name; TestHarness th; public CreateFileThread(String name, TestHarness th) { this.name = name; this.th = th; } public void run() { try { ((FileConnection)Connector.open(name)).create(); } catch (IOException ioe) { th.fail("Unexpected failure."); ioe.printStackTrace(); } } } class RemoveFileThread extends Thread { String name; TestHarness th; public RemoveFileThread(String name, TestHarness th) { this.name = name; this.th = th; } public void run() { try { FileConnection file = (FileConnection)Connector.open(name); th.check(file.exists(), name + " exists."); file.delete(); th.check(!file.exists(), name + " has been removed."); file.close(); } catch (IOException ioe) { th.fail("Unexpected failure."); ioe.printStackTrace(); } } } public void test(TestHarness th) { try { dirPath = System.getProperty("fileconn.dir.private"); dir = (FileConnection)Connector.open(dirPath + "provaDir"); th.check(dir.isOpen(), "Directory opened"); th.check(!dir.exists(), "Directory doesn't exist"); th.check(!dir.isDirectory(), "Directory isn't (yet) a directory"); dir.mkdir(); th.check(dir.isOpen(), "Directory opened"); th.check(dir.exists(), "Directory exists"); th.check(dir.isDirectory(), "Directory is a directory"); Enumeration files = dir.list(); th.check(!files.hasMoreElements(), "Directory is empty"); FileConnection file = (FileConnection)Connector.open(dirPath + "provaDir/prova"); th.check(file.isOpen(), "File opened"); th.check(!file.exists(), "File doesn't exist"); th.check(!file.isDirectory(), "File isn't a directory"); try { file.list(); th.fail("Exception expected"); } catch (IOException e) { th.check(e.getMessage(), "Directory does not exist: file:///Private/provaDir/prova"); } file.create(); th.check(file.exists(), "File created"); th.check(!file.isDirectory(), "File isn't a directory"); th.check(file.fileSize(), 0, "Check file size"); try { file.list(); th.fail("Exception expected"); } catch (IOException e) { th.check(e.getMessage(), "Connection is open on a file: file:///Private/provaDir/prova"); } OutputStream out = file.openOutputStream(); out.write(new byte[]{ 5, 4, 3, 2, 1 }); out.close(); // Closing the output stream again should succeed out.close(); th.check(file.fileSize(), 5); InputStream in = file.openInputStream(); th.check(in.read(), 5); th.check(in.read(), 4); th.check(in.read(), 3); th.check(in.read(), 2); th.check(in.read(), 1); th.check(in.read(), -1); in.close(); // Closing the input stream again should succeed in.close(); // Test reading in = file.openInputStream(); byte[] data = new byte[5]; th.check(in.read(data, 0, 5), 5); th.check(data[0], 5); th.check(data[1], 4); th.check(data[2], 3); th.check(data[3], 2); th.check(data[4], 1); in.close(); // Test reading with offset and length in = file.openInputStream(); byte[] smallBuffer = new byte[3]; smallBuffer[0] = 42; th.check(in.read(smallBuffer, 1, 2), 2); th.check(smallBuffer[0], 42); th.check(smallBuffer[1], 5); th.check(smallBuffer[2], 4); in.close(); // Test reading more than the size of the file in = file.openInputStream(); byte[] bigBuffer = new byte[50]; th.check(in.read(bigBuffer, 0, 50), 5); th.check(bigBuffer[0], 5); th.check(bigBuffer[1], 4); th.check(bigBuffer[2], 3); th.check(bigBuffer[3], 2); th.check(bigBuffer[4], 1); for (int i = 5; i < bigBuffer.length; i++) { th.check(bigBuffer[i], 0); } in.close(); // Test with negative offset in = file.openInputStream(); try { in.read(data, -1, 0); th.fail("Exception expected"); } catch (IndexOutOfBoundsException e) { th.check(true, "Exception expected"); } // Test with negative count try { in.read(data, 0, -1); th.fail("Exception expected"); } catch (IndexOutOfBoundsException e) { th.check(true, "Exception expected"); } // Test with offset > buffer len try { in.read(data, 7, 1); th.fail("Exception expected"); } catch (IndexOutOfBoundsException e) { th.check(true, "Exception expected"); } // Test with (buffer len - offset) < count try { in.read(data, 4, 3); th.fail("Exception expected"); } catch (IndexOutOfBoundsException e) { th.check(true, "Exception expected"); } // Test with buffer len 0 byte[] empty = new byte[0]; th.check(in.read(empty, 0, 0), 0); // Test with count 0 th.check(in.read(data, 0, 0), 0); in.close(); file.close(); th.check(!file.isOpen()); // Test with closed file try { in.read(data, 0, 5); th.fail("Exception expected"); } catch (IOException e) { th.check(e.getMessage(), "Stream closed"); } try { in.read(); th.fail("Exception expected"); } catch (IOException e) { th.check(e.getMessage(), "Stream closed"); } file = (FileConnection)Connector.open(dirPath + "provaDir/prova"); in = file.openInputStream(); th.check(in.available(), 5); in.read(); th.check(in.available(), 4); th.check(in.skip((long) 1), 1); th.check(in.available(), 3); th.check(in.skip((long) -5), 0); th.check(in.available(), 3); th.check(in.skip((long) 10), 3); th.check(in.available(), 0); th.check(in.skip((long) 1), 0); in.close(); file.close(); files = dir.list(); th.check(files.hasMoreElements(), "Directory has one file"); th.check(files.nextElement(), "prova"); th.check(!files.hasMoreElements(), "Directory has just one file"); testListFilter(th); testLastModified(th); testIgnoredFile(th); dir.close(); th.check(!dir.isOpen()); file = (FileConnection)Connector.open(dirPath + "provaDir/prova"); file.delete(); th.check(!file.exists()); file.close(); file = (FileConnection)Connector.open(dirPath + "provaDir/prova%2B"); th.check(file.getName(), "prova+"); th.check(file.getURL(), "file:///Private/provaDir/prova%2B"); file.create(); file.close(); file = (FileConnection)Connector.open(dirPath + "provaDir/prova+"); th.check(file.exists(), "File 'prova+' exists"); file.delete(); file.close(); // Opening an output stream to a nonexistent file should throw // an exception. file = (FileConnection)Connector.open(dirPath + "provaDir/nonexistent.txt"); th.check(!file.exists()); try { out = file.openOutputStream(); th.fail("Exception expected opening output stream to nonexistent file"); } catch (IOException e) { th.check(e.getMessage(), "Target file doesn't exist"); } th.check(!file.exists()); out.close(); file.close(); // Deleting a file with an open output stream succeeds. file = (FileConnection)Connector.open(dirPath + "provaDir/nonexistent.txt"); file.create(); out = file.openOutputStream(); file.delete(); th.check(!file.exists()); // Renaming a file with an open output stream succeeds. file.create(); out = file.openOutputStream(); file.rename("newname"); th.check(file.getName(), "newname"); out.close(); file.close(); // The file with the old name doesn't exist anymore. file = (FileConnection)Connector.open(dirPath + "provaDir/nonexistent.txt"); th.check(!file.exists()); file.close(); // The file with the new name exists. file = (FileConnection)Connector.open(dirPath + "provaDir/newname"); th.check(file.exists()); file.delete(); file.close(); // Check creating files in multi-thread Hashtable expected = new Hashtable(); expected.put("ThreadFile1", ""); expected.put("ThreadFile2", ""); expected.put("ThreadFile3", ""); Thread t1 = new CreateFileThread(dirPath + "provaDir/" + "ThreadFile1", th); Thread t2 = new CreateFileThread(dirPath + "provaDir/" + "ThreadFile2", th); Thread t3 = new CreateFileThread(dirPath + "provaDir/" + "ThreadFile3", th); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); dir = (FileConnection)Connector.open(dirPath + "provaDir"); files = dir.list(); while (files.hasMoreElements()) { String fileName = (String)files.nextElement(); th.check(expected.remove(fileName) != null); } th.check(expected.isEmpty(), "3 files were created and removed."); // Check removing files in multi-thread t1 = new RemoveFileThread(dirPath + "provaDir/" + "ThreadFile1", th); t2 = new RemoveFileThread(dirPath + "provaDir/" + "ThreadFile2", th); t3 = new RemoveFileThread(dirPath + "provaDir/" + "ThreadFile3", th); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); files = dir.list(); th.check(!files.hasMoreElements(), "dir is empty."); dir.delete(); th.check(!dir.exists()); dir.close(); try { file = (FileConnection)Connector.open(dirPath + "prov>"); th.fail("Exception expected"); } catch (IOException e) { th.check(e.getMessage(), "Contains characters invalid for a filename"); } // Check that the fileconn.dir.photos property value is longer than 8 characters. String photoDir = System.getProperty("fileconn.dir.photos"); th.check(photoDir.length() > 8); // Check that the photos directory exists and is a directory. dir = (FileConnection)Connector.open(photoDir); th.check(dir.exists(), "fileconn.dir.photos exists"); th.check(dir.isDirectory(), "fileconn.dir.photos is a directory"); dir.close(); } catch (Exception e) { th.fail("Unexpected exception: " + e); e.printStackTrace(); } } }