blob: d52f2ee974394862ae1e32fe7b159bc26229c7e4 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Dart test program for testing error handling in file I/O.
// @dart = 2.9
import "dart:convert";
import "dart:io";
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
Directory tempDir() {
return Directory.systemTemp.createTempSync('dart_file_error');
}
bool checkCannotOpenFileException(e) {
Expect.isTrue(e is FileSystemException);
Expect.isTrue(e.osError != null);
Expect.isTrue(e.toString().indexOf("Cannot open file") != -1);
if (Platform.operatingSystem == "linux") {
Expect.equals(2, e.osError.errorCode);
} else if (Platform.operatingSystem == "macos") {
Expect.equals(2, e.osError.errorCode);
} else if (Platform.operatingSystem == "windows") {
Expect.equals(3, e.osError.errorCode);
}
return true;
}
bool checkNonExistentFileSystemException(e, str) {
Expect.isTrue(e is FileSystemException);
Expect.isTrue(e.osError != null);
Expect.isTrue(e.toString().indexOf(str) != -1);
// File not not found has error code 2 on all supported platforms.
Expect.equals(2, e.osError.errorCode);
return true;
}
bool checkOpenNonExistentFileSystemException(e) {
return checkNonExistentFileSystemException(e, "Cannot open file");
}
bool checkDeleteNonExistentFileSystemException(e) {
return checkNonExistentFileSystemException(e, "Cannot delete file");
}
bool checkLengthNonExistentFileSystemException(e) {
return checkNonExistentFileSystemException(
e, "Cannot retrieve length of file");
}
void testOpenBlankFilename() {
asyncStart();
var file = new File("");
// Non-existing file should throw exception.
Expect.throws(() => file.openSync(), (e) => checkCannotOpenFileException(e));
var openFuture = file.open(mode: FileMode.read);
openFuture.then((raf) => Expect.fail("Unreachable code")).catchError((error) {
checkCannotOpenFileException(error);
asyncEnd();
});
}
void testOpenNonExistent() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentFile");
// Non-existing file should throw exception.
Expect.throws(
() => file.openSync(), (e) => checkOpenNonExistentFileSystemException(e));
var openFuture = file.open(mode: FileMode.read);
openFuture.then((raf) => Expect.fail("Unreachable code")).catchError((error) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
void testDeleteNonExistent() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentFile");
// Non-existing file should throw exception.
Expect.throws(() => file.deleteSync(),
(e) => checkDeleteNonExistentFileSystemException(e));
var delete = file.delete();
delete.then((ignore) => Expect.fail("Unreachable code")).catchError((error) {
checkDeleteNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
void testLengthNonExistent() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentFile");
// Non-existing file should throw exception.
Expect.throws(() => file.lengthSync(),
(e) => checkLengthNonExistentFileSystemException(e));
var lenFuture = file.length();
lenFuture.then((len) => Expect.fail("Unreachable code")).catchError((error) {
checkLengthNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
bool checkCreateInNonExistentFileSystemException(e) {
Expect.isTrue(e is FileSystemException);
Expect.isTrue(e.osError != null);
Expect.isTrue(e.toString().indexOf("Cannot create file") != -1);
if (Platform.operatingSystem == "linux") {
Expect.equals(2, e.osError.errorCode);
} else if (Platform.operatingSystem == "macos") {
Expect.equals(2, e.osError.errorCode);
} else if (Platform.operatingSystem == "windows") {
Expect.equals(3, e.osError.errorCode);
}
return true;
}
void testCreateInNonExistentDirectory() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentDirectory/newFile");
// Create in non-existent directory should throw exception.
Expect.throws(() => file.createSync(),
(e) => checkCreateInNonExistentFileSystemException(e));
var create = file.create();
create.then((ignore) => Expect.fail("Unreachable code")).catchError((error) {
checkCreateInNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
bool checkResolveSymbolicLinksOnNonExistentFileSystemException(e) {
Expect.isTrue(e is FileSystemException);
Expect.isTrue(e.osError != null);
Expect.isTrue(e.toString().indexOf("Cannot resolve symbolic links") != -1);
// File not not found has error code 2 on all supported platforms.
Expect.equals(2, e.osError.errorCode);
return true;
}
void testResolveSymbolicLinksOnNonExistentDirectory() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentDirectory");
// Full path non-existent directory should throw exception.
Expect.throws(() => file.resolveSymbolicLinksSync(),
(e) => checkResolveSymbolicLinksOnNonExistentFileSystemException(e));
var resolvedFuture = file.resolveSymbolicLinks();
resolvedFuture
.then((path) => Expect.fail("Unreachable code $path"))
.catchError((error) {
checkResolveSymbolicLinksOnNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
void testReadAsBytesNonExistent() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentFile3");
// Non-existing file should throw exception.
Expect.throws(() => file.readAsBytesSync(),
(e) => checkOpenNonExistentFileSystemException(e));
var readAsBytesFuture = file.readAsBytes();
readAsBytesFuture
.then((data) => Expect.fail("Unreachable code"))
.catchError((error) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
void testReadAsTextNonExistent() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentFile4");
// Non-existing file should throw exception.
Expect.throws(() => file.readAsStringSync(),
(e) => checkOpenNonExistentFileSystemException(e));
var readAsStringFuture = file.readAsString(encoding: ascii);
readAsStringFuture
.then((data) => Expect.fail("Unreachable code"))
.catchError((error) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
testReadAsLinesNonExistent() {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/nonExistentFile5");
// Non-existing file should throw exception.
Expect.throws(() => file.readAsLinesSync(),
(e) => checkOpenNonExistentFileSystemException(e));
var readAsLinesFuture = file.readAsLines(encoding: ascii);
readAsLinesFuture
.then((data) => Expect.fail("Unreachable code"))
.catchError((error) {
checkOpenNonExistentFileSystemException(error);
temp.deleteSync(recursive: true);
asyncEnd();
});
}
bool checkWriteReadOnlyFileSystemException(e) {
Expect.isTrue(e is FileSystemException);
Expect.isTrue(e.osError != null);
Expect.isTrue(e.osError.errorCode != OSError.noErrorCode);
return true;
}
// Create a test file in a temporary directory. Setup a port to signal
// when the temporary directory should be deleted. Pass the file and
// the port to the callback argument.
createTestFile(callback) {
asyncStart();
Directory temp = tempDir();
var file = new File("${temp.path}/test_file");
file.createSync();
callback(file, () {
temp.deleteSync(recursive: true);
asyncEnd();
});
}
testWriteByteToReadOnlyFile() {
createTestFile((file, done) {
var openedFile = file.openSync(mode: FileMode.read);
// Writing to read only file should throw an exception.
Expect.throws(() => openedFile.writeByteSync(0),
(e) => checkWriteReadOnlyFileSystemException(e));
var writeByteFuture = openedFile.writeByte(0);
writeByteFuture.catchError((error) {
checkWriteReadOnlyFileSystemException(error);
openedFile.close().then((_) => done());
});
});
}
testWriteFromToReadOnlyFile() {
createTestFile((file, done) {
var openedFile = file.openSync(mode: FileMode.read);
List<int> data = [0, 1, 2, 3];
// Writing to read only file should throw an exception.
Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkWriteReadOnlyFileSystemException(e));
var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
writeFromFuture.catchError((error) {
checkWriteReadOnlyFileSystemException(error);
openedFile.close().then((_) => done());
});
});
}
testTruncateReadOnlyFile() {
createTestFile((file, done) {
var openedFile = file.openSync(mode: FileMode.write);
openedFile.writeByteSync(0);
openedFile.closeSync();
openedFile = file.openSync(mode: FileMode.read);
// Truncating read only file should throw an exception.
Expect.throws(() => openedFile.truncateSync(0),
(e) => checkWriteReadOnlyFileSystemException(e));
var truncateFuture = openedFile.truncate(0);
truncateFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError((error) {
checkWriteReadOnlyFileSystemException(error);
openedFile.close().then((_) => done());
});
});
}
bool checkFileClosedException(e) {
Expect.isTrue(e is FileSystemException);
Expect.isTrue(e.toString().indexOf("File closed") != -1);
Expect.isTrue(e.osError == null);
return true;
}
testOperateOnClosedFile() {
createTestFile((file, done) {
var openedFile = file.openSync(mode: FileMode.read);
openedFile.closeSync();
List<int> data = [0, 1, 2, 3];
Expect.throws(
() => openedFile.readByteSync(), (e) => checkFileClosedException(e));
Expect.throws(
() => openedFile.writeByteSync(0), (e) => checkFileClosedException(e));
Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkFileClosedException(e));
Expect.throws(() => openedFile.readIntoSync(data, 0, data.length),
(e) => checkFileClosedException(e));
Expect.throws(() => openedFile.writeStringSync("Hello"),
(e) => checkFileClosedException(e));
Expect.throws(
() => openedFile.positionSync(), (e) => checkFileClosedException(e));
Expect.throws(() => openedFile.setPositionSync(0),
(e) => checkFileClosedException(e));
Expect.throws(
() => openedFile.truncateSync(0), (e) => checkFileClosedException(e));
Expect.throws(
() => openedFile.lengthSync(), (e) => checkFileClosedException(e));
Expect.throws(
() => openedFile.flushSync(), (e) => checkFileClosedException(e));
var errorCount = 0;
_errorHandler(error) {
checkFileClosedException(error);
if (--errorCount == 0) {
done();
}
}
var readByteFuture = openedFile.readByte();
readByteFuture
.then((byte) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var writeByteFuture = openedFile.writeByte(0);
writeByteFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var readIntoFuture = openedFile.readInto(data, 0, data.length);
readIntoFuture
.then((bytesRead) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
writeFromFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var writeStringFuture = openedFile.writeString("Hello");
writeStringFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var positionFuture = openedFile.position();
positionFuture
.then((position) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var setPositionFuture = openedFile.setPosition(0);
setPositionFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var truncateFuture = openedFile.truncate(0);
truncateFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var lenFuture = openedFile.length();
lenFuture
.then((length) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var flushFuture = openedFile.flush();
flushFuture
.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
});
}
testRepeatedlyCloseFile() {
createTestFile((file, done) {
var openedFile = file.openSync();
openedFile.close().then((ignore) {
var closeFuture = openedFile.close();
closeFuture.then((ignore) => null).catchError((error) {
Expect.isTrue(error is FileSystemException);
done();
});
});
});
}
testRepeatedlyCloseFileSync() {
createTestFile((file, done) {
var openedFile = file.openSync();
openedFile.closeSync();
Expect.throws(openedFile.closeSync, (e) => e is FileSystemException);
done();
});
}
testReadSyncClosedFile() {
createTestFile((file, done) {
var openedFile = file.openSync();
openedFile.closeSync();
Expect.throws(
() => openedFile.readSync(1), (e) => e is FileSystemException);
done();
});
}
main() {
testOpenBlankFilename();
testOpenNonExistent();
testDeleteNonExistent();
testLengthNonExistent();
testCreateInNonExistentDirectory();
testResolveSymbolicLinksOnNonExistentDirectory();
testReadAsBytesNonExistent();
testReadAsTextNonExistent();
testReadAsLinesNonExistent();
testWriteByteToReadOnlyFile();
testWriteFromToReadOnlyFile();
testTruncateReadOnlyFile();
testOperateOnClosedFile();
testRepeatedlyCloseFile();
testRepeatedlyCloseFileSync();
testReadSyncClosedFile();
}