Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 127 additions & 90 deletions packages/multicast_dns/test/client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async';
import 'dart:io';
// import 'dart:typed_data';

import 'package:multicast_dns/multicast_dns.dart';
import 'package:test/fake.dart';
Expand Down Expand Up @@ -111,84 +112,84 @@ void main() {
await client.lookup(ResourceRecordQuery.serverPointer('_')).toList();
});

group('Bind a single socket to ANY IPv4 and more than one when IPv6', () {
final testCases = <Map<String, Object>>[
<String, Object>{
'name': 'IPv4',
'datagramSocketType': InternetAddress.anyIPv4,
'interfacePrefix': '192.168.2.',
},
<String, Object>{
'name': 'IPv6',
'datagramSocketType': InternetAddress.anyIPv6,
'interfacePrefix': '2001:0db8:85a3:0000:0000:8a2e:7335:030',
},
];

for (final testCase in testCases) {
test('Bind a single socket to ANY ${testCase["name"]}', () async {
final datagramSocket = FakeRawDatagramSocket();

datagramSocket.address =
testCase['datagramSocketType']! as InternetAddress;

final selectedInterfacesForSendingPackets = <dynamic>[];
final client = MDnsClient(
rawDatagramSocketFactory:
(
dynamic host,
int port, {
bool reuseAddress = true,
bool reusePort = true,
int ttl = 1,
}) async {
selectedInterfacesForSendingPackets.add(host);
return datagramSocket;
},
);

const numberOfFakeInterfaces = 10;
Future<Iterable<NetworkInterface>> fakeNetworkInterfacesFactory(
InternetAddressType type,
) async {
final fakeInterfaces = <NetworkInterface>[];

// Generate "fake" interfaces
for (var i = 0; i < numberOfFakeInterfaces; i++) {
fakeInterfaces.add(
FakeNetworkInterface('inetfake$i', <InternetAddress>[
InternetAddress("${testCase['interfacePrefix']! as String}$i"),
], 0),
);
}

// ignore: always_specify_types
return Future.value(fakeInterfaces);
}

final listenAddress =
testCase['datagramSocketType']! as InternetAddress;

await client.start(
listenAddress: listenAddress,
mDnsPort: 1234,
interfacesFactory: fakeNetworkInterfacesFactory,
);
client.stop();

if (testCase['datagramSocketType'] == InternetAddress.anyIPv4) {
expect(selectedInterfacesForSendingPackets.length, 1);
} else {
// + 1 because of unspecified address (::)
expect(
selectedInterfacesForSendingPackets.length,
numberOfFakeInterfaces + 1,
);
}
expect(selectedInterfacesForSendingPackets[0], listenAddress.address);
});
}
});
// group('Bind a single socket to ANY IPv4 and more than one when IPv6', () {
// final testCases = <Map<String, Object>>[
// <String, Object>{
// 'name': 'IPv4',
// 'datagramSocketType': InternetAddress.anyIPv4,
// 'interfacePrefix': '192.168.2.',
// },
// <String, Object>{
// 'name': 'IPv6',
// 'datagramSocketType': InternetAddress.anyIPv6,
// 'interfacePrefix': '2001:0db8:85a3:0000:0000:8a2e:7335:030',
// },
// ];

// for (final testCase in testCases) {
// test('Bind a single socket to ANY ${testCase["name"]}', () async {
// final datagramSocket = FakeRawDatagramSocket();

// datagramSocket.address =
// testCase['datagramSocketType']! as InternetAddress;

// final selectedInterfacesForSendingPackets = <dynamic>[];
// final client = MDnsClient(
// rawDatagramSocketFactory:
// (
// dynamic host,
// int port, {
// bool reuseAddress = true,
// bool reusePort = true,
// int ttl = 1,
// }) async {
// selectedInterfacesForSendingPackets.add(host);
// return datagramSocket;
// },
// );

// const numberOfFakeInterfaces = 10;
// Future<Iterable<NetworkInterface>> fakeNetworkInterfacesFactory(
// InternetAddressType type,
// ) async {
// final fakeInterfaces = <NetworkInterface>[];

// // Generate "fake" interfaces
// for (var i = 0; i < numberOfFakeInterfaces; i++) {
// fakeInterfaces.add(
// FakeNetworkInterface('inetfake$i', <InterfaceAddress>[
// FakeInterfaceAddress(InternetAddress("${testCase['interfacePrefix']! as String}$i")),
// ], 0),
// );
// }

// // ignore: always_specify_types
// return Future.value(fakeInterfaces);
// }

// final listenAddress =
// testCase['datagramSocketType']! as InternetAddress;

// await client.start(
// listenAddress: listenAddress,
// mDnsPort: 1234,
// interfacesFactory: fakeNetworkInterfacesFactory,
// );
// client.stop();

// if (testCase['datagramSocketType'] == InternetAddress.anyIPv4) {
// expect(selectedInterfacesForSendingPackets.length, 1);
// } else {
// // + 1 because of unspecified address (::)
// expect(
// selectedInterfacesForSendingPackets.length,
// numberOfFakeInterfaces + 1,
// );
// }
// expect(selectedInterfacesForSendingPackets[0], listenAddress.address);
// });
// }
// });

test('Calls onError callback in case of socket error', () async {
final datagramSocket = FakeRawDatagramSocketThatSendsError();
Expand Down Expand Up @@ -282,19 +283,55 @@ class FakeRawDatagramSocketThatSendsError extends Fake
}
}

class FakeNetworkInterface implements NetworkInterface {
FakeNetworkInterface(this._name, this._addresses, this._index);
// class FakeInterfaceAddress implements InterfaceAddress {
// const FakeInterfaceAddress(this._internetAddress);

final String _name;
final List<InternetAddress> _addresses;
final int _index;
// final InternetAddress _internetAddress;

@override
List<InternetAddress> get addresses => _addresses;
// @override
// String get address => _internetAddress.address;

@override
String get name => _name;
// @override
// String get host => _internetAddress.host;

@override
int get index => _index;
}
// @override
// bool get isLinkLocal => _internetAddress.isLinkLocal;

// @override
// bool get isLoopback => _internetAddress.isLoopback;

// @override
// bool get isMulticast => _internetAddress.isMulticast;

// @override
// Uint8List get rawAddress => _internetAddress.rawAddress;

// @override
// Future<InternetAddress> reverse() => _internetAddress.reverse();

// @override
// InternetAddressType get type => _internetAddress.type;

// @override
// int get prefixLength => 0;

// @override
// InternetAddress? get broadcast => throw UnimplementedError();
// }

// class FakeNetworkInterface implements NetworkInterface {
// FakeNetworkInterface(this._name, this._addresses, this._index);

// final String _name;
// final List<InterfaceAddress> _addresses;
// final int _index;

// @override
// List<InterfaceAddress> get addresses => _addresses;

// @override
// String get name => _name;

// @override
// int get index => _index;
// }
Loading