Skip to content

Commit

Permalink
Merge pull request #87 from osociety/hostscanner-unit-test
Browse files Browse the repository at this point in the history
Unit test for host scanner added
  • Loading branch information
git-elliot authored Mar 4, 2023
2 parents a98b360 + 9aa7ab6 commit 0c00513
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 10 deletions.
4 changes: 4 additions & 0 deletions network_tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ Add this code to your `main.dart` file
});
```

## Run unit tests

1. dart test

## Sample App

[Vernet](https://github.com/git-elliot/vernet) is the open source app built on top of this library.
Expand Down
28 changes: 20 additions & 8 deletions network_tools/lib/src/host_scanner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,32 @@ class HostScanner {
static const classBSubnets = 65536;
static const classCSubnets = 256;
static int getMaxHost(String subnet) {
final List<String> lastHostIdStr = subnet.split('.');
if (lastHostIdStr.isEmpty) {
throw 'Invalid subnet Address';
if (subnet.isEmpty) {
throw ArgumentError('Invalid subnet address, address can not be empty.');
}
final List<String> firstOctetStr = subnet.split('.');
if (firstOctetStr.isEmpty) {
throw ArgumentError(
'Invalid subnet address, address should be in IPv4 format x.x.x',
);
}

final int lastHostId = int.parse(lastHostIdStr[0]);
final int firstOctet = int.parse(firstOctetStr[0]);

if (lastHostId < 128) {
if (firstOctet > 0 && firstOctet < 128) {
return classASubnets;
} else if (lastHostId >= 128 && lastHostId < 192) {
} else if (firstOctet >= 128 && firstOctet < 192) {
return classBSubnets;
} else if (lastHostId >= 192 && lastHostId < 224) {
} else if (firstOctet >= 192 && firstOctet < 224) {
return classCSubnets;
}
return classCSubnets;
// Out of range for first octet
throw RangeError.range(
firstOctet,
1,
223,
'subnet',
'Out of range for first octet',
);
}
}
2 changes: 1 addition & 1 deletion network_tools/lib/src/models/active_host.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class ActiveHost extends Comparable<ActiveHost> {
int get hashCode => address.hashCode;

@override
bool operator ==(dynamic o) => o is ActiveHost && address == o.address;
bool operator ==(Object o) => o is ActiveHost && address == o.address;

@override
int compareTo(ActiveHost other) {
Expand Down
2 changes: 1 addition & 1 deletion network_tools/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ dev_dependencies:
# Set of lint rules for Dart.
lint: ^2.0.1
# Writing and running Dart tests.
test: ^1.22.2
test: ^1.22.2
66 changes: 66 additions & 0 deletions network_tools/test/host_scanner_test.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,78 @@
import 'package:network_tools/network_tools.dart';
import 'package:test/test.dart';
import 'package:universal_io/io.dart';

void main() {
group('Testing Host Scanner', () {
String interfaceIp = "127.0.0";
String myOwnHost = "127.0.0.1";
// Fetching interfaceIp and hostIp
setUp(() async {
final interfaceList =
await NetworkInterface.list(); //will give interface list
if (interfaceList.isNotEmpty) {
final localInterface =
interfaceList.elementAt(0); //fetching first interface like en0/eth0
if (localInterface.addresses.isNotEmpty) {
final address = localInterface.addresses
.elementAt(0)
.address; //gives IP address of GHA local machine.
myOwnHost = address;
interfaceIp = address.substring(0, address.lastIndexOf('.'));
}
}
});

test('Running getAllPingableDevices tests', () {
expectLater(
//There should be at least one device pingable in network
HostScanner.getAllPingableDevices(interfaceIp),
emits(isA<ActiveHost>()),
);
expectLater(
//Should emit at least our own local machine when pinging all hosts.
HostScanner.getAllPingableDevices(interfaceIp),
emitsThrough(ActiveHost(internetAddress: InternetAddress(myOwnHost))),
);
});

test('Running scanDevicesForSinglePort tests', () {
expectLater(
HostScanner.scanDevicesForSinglePort(
interfaceIp,
22, //ssh should be running at least in any host
), // hence some host will be emitted
emits(isA<ActiveHost>()),
);
});

test('Running getMaxHost tests', () {
expect(() => HostScanner.getMaxHost(""), throwsArgumentError);
expect(() => HostScanner.getMaxHost("x"), throwsFormatException);
expect(() => HostScanner.getMaxHost("x.x.x"), throwsFormatException);
expect(() => HostScanner.getMaxHost("0"), throwsRangeError);
expect(() => HostScanner.getMaxHost("0.0.0.0"), throwsRangeError);
expect(() => HostScanner.getMaxHost("256.0.0.0"), throwsRangeError);

expect(HostScanner.getMaxHost("10.0.0.0"), HostScanner.classASubnets);
expect(HostScanner.getMaxHost("164.0.0.0"), HostScanner.classBSubnets);
expect(HostScanner.getMaxHost("200.0.0.0"), HostScanner.classCSubnets);

expect(
![HostScanner.classASubnets, HostScanner.classCSubnets]
.contains(HostScanner.getMaxHost("164.0.0.0")),
true,
);
expect(
![HostScanner.classBSubnets, HostScanner.classCSubnets]
.contains(HostScanner.getMaxHost("10.0.0.0")),
true,
);
expect(
![HostScanner.classASubnets, HostScanner.classBSubnets]
.contains(HostScanner.getMaxHost("200.0.0.0")),
true,
);
});
});
}

0 comments on commit 0c00513

Please sign in to comment.