| Index: tests/standalone/io/file_blocking_lock_test.dart
|
| diff --git a/tests/standalone/io/file_blocking_lock_test.dart b/tests/standalone/io/file_blocking_lock_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ef826a2037075efa3dd2f35f13fd8db7653dff36
|
| --- /dev/null
|
| +++ b/tests/standalone/io/file_blocking_lock_test.dart
|
| @@ -0,0 +1,109 @@
|
| +// Copyright (c) 2016, 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.
|
| +
|
| +// This test works by spawning a new process running
|
| +// file_blocking_lock_script.dart, trading the file lock back and forth,
|
| +// writing bytes 1 ... 25 in order to the file. There are checks to ensure
|
| +// that the bytes are written in order, that one process doesn't write all the
|
| +// bytes and that a non-blocking lock fails such that a blocking lock must
|
| +// be taken, which succeeds.
|
| +
|
| +import 'dart:async';
|
| +import 'dart:convert';
|
| +import 'dart:io';
|
| +
|
| +import "package:async_helper/async_helper.dart";
|
| +import "package:expect/expect.dart";
|
| +import "package:path/path.dart";
|
| +
|
| +// Check whether the file is locked or not.
|
| +runPeer(String path, int len, FileLock mode) {
|
| + var script = Platform.script.resolve(
|
| + 'file_blocking_lock_script.dart').toFilePath();
|
| + var arguments = []
|
| + ..addAll(Platform.executableArguments)
|
| + ..add(script)
|
| + ..add(path)
|
| + ..add(len.toString());
|
| + return Process.start(Platform.executable, arguments).then((process) {
|
| + process.stdout
|
| + .transform(UTF8.decoder)
|
| + .listen((data) { print(data); });
|
| + process.stderr
|
| + .transform(UTF8.decoder)
|
| + .listen((data) { print(data); });
|
| + return process;
|
| + });
|
| +}
|
| +
|
| +testLockWholeFile() async {
|
| + const int length = 25;
|
| + asyncStart();
|
| + Directory directory = await Directory.systemTemp.createTemp('dart_file_lock');
|
| + File file = new File(join(directory.path, "file"));
|
| + await file.writeAsBytes(new List.filled(length, 0));
|
| + var raf = await file.open(mode: APPEND);
|
| + await raf.setPosition(0);
|
| + await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length);
|
| + Process peer = await runPeer(file.path, length, FileLock.BLOCKING_EXCLUSIVE);
|
| +
|
| + // Wait a bit for the other process to get started. We'll synchronize on
|
| + // the file lock.
|
| + await new Future.delayed(const Duration(seconds: 1));
|
| +
|
| + int nextToWrite = 1;
|
| + int at = 0;
|
| + List iWrote = new List.filled(length, 0);
|
| + bool nonBlockingFailed = false;
|
| + while (nextToWrite <= length) {
|
| + int p = await raf.position();
|
| + await raf.writeByte(nextToWrite);
|
| + await raf.flush();
|
| + // Record which bytes this process wrote so that we can check that the
|
| + // other process was able to take the lock and write some bytes.
|
| + iWrote[nextToWrite-1] = nextToWrite;
|
| + nextToWrite++;
|
| + await raf.unlock(0, length);
|
| + try {
|
| + await raf.lock(FileLock.EXCLUSIVE, 0, length);
|
| + } catch(e) {
|
| + // Check that at some point the non-blocking lock fails.
|
| + nonBlockingFailed = true;
|
| + await raf.lock(FileLock.BLOCKING_EXCLUSIVE, 0, length);
|
| + }
|
| + while (true) {
|
| + p = await raf.position();
|
| + at = await raf.readByte();
|
| + if (at == 0 || at == -1) break;
|
| + nextToWrite++;
|
| + }
|
| + await raf.setPosition(p);
|
| + }
|
| +
|
| + await raf.setPosition(0);
|
| + for (int i = 1; i <= length; i++) {
|
| + Expect.equals(i, await raf.readByte());
|
| + }
|
| + await raf.unlock(0, length);
|
| +
|
| + bool wroteAll = true;
|
| + for (int i = 0; i < length; i++) {
|
| + // If there's a 0 entry, this process didn't write all bytes.
|
| + wroteAll = wroteAll && (iWrote[i] == 0);
|
| + }
|
| + Expect.equals(false, wroteAll);
|
| +
|
| + Expect.equals(true, nonBlockingFailed);
|
| +
|
| + peer.exitCode.then((v) {
|
| + Expect.equals(0, v);
|
| + raf.closeSync();
|
| + directory.deleteSync(recursive: true);
|
| + asyncEnd();
|
| + });
|
| +}
|
| +
|
| +main() {
|
| + testLockWholeFile();
|
| +}
|
|
|