JJ_MKVMaker/test/remote_mkdirs_contract_test...

76 lines
3.4 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:jj_mkvmaker/core/ftp.dart';
import 'package:jj_mkvmaker/core/remote_fs.dart';
import 'package:jj_mkvmaker/core/sftp.dart';
import 'package:jj_mkvmaker/core/webdav.dart';
import 'package:path/path.dart' as p;
import 'support/dav_server.dart';
import 'support/sftp_server.dart';
/// modular_sync #6 RemoteFs 약속 (mkdirs, F11): 서버 종류와 상관없이 같게 - 없는 위 폴더까지 만들고 · 이미 폴더면 그대로 ·
/// 같은 이름의 파일이 있으면 RemoteNameIsFile (파일은 그대로). 예전에는 FTP 는 조용히 넘어가고 WebDAV 는 서버 오류였다.
/// 실제 시험 서버: WebDAV (TestDavServer) · FTP (pyftpdlib) · SFTP (asyncssh). SMB 는 Android 에서만 돈다 (기기 확인)
void main() {
late Directory tmp, root;
setUp(() {
tmp = Directory.systemTemp.createTempSync('jj_rmkdirs_');
root = Directory(p.join(tmp.path, 'root'))..createSync();
File(p.join(root.path, 'file')).writeAsStringSync('keep');
});
tearDown(() async {
for (var i = 0;; i++) {
try {
if (tmp.existsSync()) tmp.deleteSync(recursive: true);
break;
} on FileSystemException {
if (i > 30) rethrow;
await Future<void>.delayed(const Duration(milliseconds: 100));
}
}
});
Future<void> contract(RemoteClient c) async {
await c.mkdirs('/a/b/c');
expect(Directory(p.join(root.path, 'a', 'b', 'c')).existsSync(), isTrue, reason: '위 폴더까지');
await c.mkdirs('/a/b');
await expectLater(c.mkdirs('/file'), throwsA(isA<RemoteNameIsFile>()));
await expectLater(c.mkdirs('/file/sub'), throwsA(isA<RemoteNameIsFile>()), reason: '위 폴더 자리가 파일');
expect(File(p.join(root.path, 'file')).readAsStringSync(), 'keep', reason: '파일은 그대로');
}
test('WebDAV', () async {
final server = TestDavServer(root);
await server.start();
addTearDown(server.stop);
await contract(DavClient(DavServer(id: 'd', name: 'd', url: server.url, user: 'user', password: 'pass')));
});
test('FTP (pyftpdlib)', () async {
if (!sftpTestServerAvailable) return markTestSkipped('시험용 python 없음');
final pr = await Process.start(sftpTestPython, ['tool/ftp_test_server.py', '--root', root.path, '--mode', 'plain', '--password', 'pw-rm']);
addTearDown(() async {
pr.kill();
await pr.exitCode.timeout(const Duration(seconds: 5), onTimeout: () => -1);
});
pr.stderr.drain<void>();
final lines = pr.stdout.transform(utf8.decoder).transform(const LineSplitter()).asBroadcastStream();
final port = int.parse((await lines.firstWhere((l) => l.startsWith('PORT ')).timeout(const Duration(seconds: 20))).split(' ')[1]);
final c = FtpRemote(FtpServer(id: 'f', name: 'f', host: '127.0.0.1', port: port, user: 'jj', password: 'pw-rm', security: 'none'));
addTearDown(c.close);
await contract(c);
});
test('SFTP (asyncssh)', () async {
if (!sftpTestServerAvailable) return markTestSkipped('시험용 python 없음');
final server = await SftpTestServer.start(root: root.path, hostKeyFile: p.join(tmp.path, 'hostkey'));
addTearDown(server.stop);
final c = SftpRemote(SftpServer(id: 's', name: 's', host: '127.0.0.1', port: server.port, user: 'jj', password: 'pw', hostKeyFingerprint: server.fingerprint));
addTearDown(c.close);
await contract(c);
});
}