| // Copyright (c) 2025, 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. |
| // ignore_for_file: unreachable_from_main |
| |
| import 'dart:io'; |
| |
| import 'package:test/test.dart'; |
| |
| import 'client_simulator.dart'; |
| import 'end_to_end_test_runner.dart'; |
| import 'file_changer.dart'; |
| |
| /// End to end test using a [FileChanger] to change files then a |
| /// [ClientSimulator] that tracks state using a Watcher. |
| /// |
| /// The tests pass if the [ClientSimulator] tracking matches what's actually on |
| /// disk. |
| /// |
| /// `end_to_end_test_runner` can be run as a binary to try random file changes |
| /// until a failure, it outputs a log which can be turned into a test case here. |
| /// |
| /// See `README.md` for more detail. |
| void endToEndTests() { |
| // Random test to cover a wide range of cases. |
| test( |
| 'end to end test: random', |
| timeout: const Timeout(Duration(minutes: 10)), |
| () async { |
| await runTest(name: 'random', repeats: 100); |
| }, |
| ); |
| |
| // Specific test cases that have caught bugs. |
| for (final testCase in testCases) { |
| test( |
| 'end to end test: ${testCase.name}', |
| timeout: const Timeout(Duration(minutes: 5)), |
| () async { |
| await runTest( |
| name: testCase.name, |
| replayLog: testCase.log, |
| repeats: 50, |
| ); |
| }, |
| skip: testCase.skipOnLinux && Platform.isLinux, |
| ); |
| } |
| } |
| |
| final testCases = [ |
| TestCase('many directories, move directory to recently moved directory', ''' |
| F create directory,f/a |
| F create,f/a/78670,387 |
| F create directory,g/f |
| F create directory,b/c |
| F create directory,g/j |
| F create directory,f/d |
| F create directory,i |
| F create directory,h/i |
| F create directory,c/h |
| F create directory,g/c |
| F create directory,g/a |
| F create directory,e/c |
| F move directory to new,f/d,b/h |
| F create directory,j/c |
| F move directory to new,b/h,d/h |
| F create directory,d/i |
| F move directory to new,b/g,g/h |
| F create,j/c/73241,207 |
| F move file to new,42776,61386 |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F wait |
| F create directory,d/b |
| F create,d/b/56283,667 |
| F create directory,g |
| F move directory to new,g,d/a |
| F create directory,j/j |
| F move file to new,i/63276,j/j/66963 |
| F modify,f/8110,250 |
| F create,52267,858 |
| F move directory to new,f,g |
| '''), |
| TestCase('moves and modifies', ''' |
| F create directory,1 |
| F create,1/1,1 |
| ${_movesAndModifies()} |
| '''), |
| TestCase('move directory in, move file over', ''' |
| F create directory,a |
| F create,a/1,1 |
| F create directory,b |
| F create,b/2,2 |
| F move directory to new,a,b/a |
| F create directory,c |
| F create,c/3,3 |
| F move file over file,b/2,b/a/1 |
| '''), |
| TestCase('move new file over recently-moved file', ''' |
| F create directory,b/g |
| F create,b/g/67046,94 |
| F create directory,d |
| F move directory to new,b,d/f |
| F wait |
| F create directory,a/j |
| F create,a/j/85244,308 |
| F wait |
| F move file over file,a/j/85244,d/f/g/67046 |
| '''), |
| TestCase('move over, modify, delete in new directory', ''' |
| F create,62543,809 |
| F wait |
| F wait |
| F wait |
| F wait |
| F create directory,a |
| F create,a/63090,758 |
| F move file over file,62543,a/63090 |
| F modify,a/63090,439 |
| F delete,a/63090 |
| '''), |
| ]; |
| |
| String _movesAndModifies() { |
| final result = StringBuffer(); |
| for (var i = 1; i != 50; ++i) { |
| result.writeln('F move directory to new,$i,${i + 1}'); |
| result.writeln('F modify,${i + 1}/1,$i'); |
| } |
| return result.toString(); |
| } |