JJ_MKVMaker/test/mdns_smb_test.dart

50 lines
2.3 KiB
Dart

import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:jj_mkvmaker/core/lan_scan.dart';
import 'package:jj_mkvmaker/core/mdns_smb.dart';
/// X-plore j 보충: mDNS (_smb._tcp.local) 질의 · 응답 읽기 (이름 압축 포함), 찾기 합치기
void main() {
List<int> name(String n) => [
for (final p in n.split('.')) ...[p.length, ...p.codeUnits],
0,
];
test('질의: PTR · QU (유니캐스트로 답해 달라)', () {
final q = mdnsQuery(0x1234, '_smb._tcp.local', 12);
expect(q.sublist(0, 6), [0x12, 0x34, 0, 0, 0, 1]);
expect(q.sublist(q.length - 4), [0, 12, 0x80, 1]);
});
test('응답: PTR → 인스턴스, SRV → 호스트 (이름 압축), A → 주소', () {
final b = BytesBuilder();
b.add([0, 0, 0x84, 0, 0, 0, 0, 1, 0, 0, 0, 2]); // 답 1 · 추가 2
final ptrOwner = b.length;
b.add(name('_smb._tcp.local'));
b.add([0, 12, 0, 1, 0, 0, 0, 120]);
final inst = [3, ...'NAS'.codeUnits, 0xc0, ptrOwner]; // "NAS" + 압축 (_smb._tcp.local)
b.add([0, inst.length, ...inst]);
final instAt = b.length - inst.length;
// SRV: 이름 = 인스턴스 (압축), 자료 = 우선 · 무게 · 포트 · 대상 "ds1815.local"
b.add([0xc0, instAt, 0, 33, 0, 1, 0, 0, 0, 120]);
final target = name('ds1815.local');
b.add([0, 6 + target.length, 0, 0, 0, 0, 1, 189, ...target]);
final targetAt = b.length - target.length;
b.add([0xc0, targetAt, 0, 1, 0, 1, 0, 0, 0, 120, 0, 4, 192, 168, 0, 15]);
final r = parseMdns(Uint8List.fromList(b.toBytes()));
expect(r.map((x) => (x.name, x.type, x.data)), [
('_smb._tcp.local', 12, 'NAS._smb._tcp.local'),
('NAS._smb._tcp.local', 33, 'ds1815.local'),
('ds1815.local', 1, '192.168.0.15'),
]);
});
test('합치기: mDNS 이름이 포트 훑기 결과를 덮고, 주소 순서대로', () async {
final out = await findSmbServersBoth(({cancelled, onProgress}) async => const [LanHost('192.168.0.20', null), LanHost('192.168.0.3', null)],
cancelled: () => false);
// 이 PC 의 망에 실제 mDNS 응답자가 있으면 더 나올 수 있다 - 훑기 결과 두 개는 늘 있어야 함
expect(out.map((h) => h.address), containsAllInOrder(['192.168.0.3', '192.168.0.20']));
});
}