summaryrefslogtreecommitdiffhomepage
path: root/windows
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2019-10-24 15:36:09 +0200
committerDavid Lönnhager <david.l@mullvad.net>2019-10-30 14:58:41 +0100
commit244580c77486ea891b6cd9ba7a554fa07e1435fd (patch)
tree65805603448d183a7954b7a7a971b104bf7b9ce5 /windows
parentf811029e68668b6e82f52abafa2b14e4203f98f4 (diff)
downloadmullvadvpn-244580c77486ea891b6cd9ba7a554fa07e1435fd.tar.xz
mullvadvpn-244580c77486ea891b6cd9ba7a554fa07e1435fd.zip
Add unit test for NetworkAdapterMonitor filter
Diffstat (limited to 'windows')
-rw-r--r--windows/winnet/src/extras/tests/adaptermonitor.cpp181
-rw-r--r--windows/winnet/src/extras/tests/testadapterutil.cpp14
2 files changed, 188 insertions, 7 deletions
diff --git a/windows/winnet/src/extras/tests/adaptermonitor.cpp b/windows/winnet/src/extras/tests/adaptermonitor.cpp
index 292b15d2b4..bfb3da8d5e 100644
--- a/windows/winnet/src/extras/tests/adaptermonitor.cpp
+++ b/windows/winnet/src/extras/tests/adaptermonitor.cpp
@@ -34,6 +34,36 @@ void logFunc(common::logging::Severity severity, const char *msg)
std::cout << msg << std::endl;
}
+enum class LastEvent
+{
+ NoEvent,
+ Add,
+ Delete,
+ Update
+};
+
+}
+
+namespace Microsoft::VisualStudio::CppUnitTestFramework
+{
+
+template<>
+static std::wstring ToString<LastEvent>(const enum class LastEvent& t)
+{
+ switch (t)
+ {
+ case LastEvent::NoEvent:
+ return L"LastEvent::NoEvent";
+ case LastEvent::Add:
+ return L"LastEvent::Add";
+ case LastEvent::Delete:
+ return L"LastEvent::Delete";
+ case LastEvent::Update:
+ return L"LastEvent::Update";
+ }
+ return L"LastEvent::<Unknown value>";
+}
+
}
TEST_CLASS(NetworkAdapterMonitorTests)
@@ -632,4 +662,155 @@ public:
L"Expected no adapter (0 IP interfaces)"
);
}
+
+ TEST_METHOD(filter)
+ {
+ auto logSink = std::make_shared<common::logging::LogSink>(logFunc);
+
+ const auto testProvider = std::make_shared<TestDataProvider>();
+
+ //
+ // Exclude adapters not connected to the internet,
+ // loopback devices, and software adapters
+ //
+
+ const auto filter = [](const MIB_IF_ROW2 &row) -> bool
+ {
+ switch (row.InterfaceLuid.Info.IfType)
+ {
+ case IF_TYPE_SOFTWARE_LOOPBACK:
+ {
+ return false;
+ }
+ }
+
+ if (FALSE == row.InterfaceAndOperStatusFlags.HardwareInterface)
+ {
+ return false;
+ }
+ return IfOperStatusUp == row.OperStatus
+ && MediaConnectStateConnected == row.MediaConnectState;
+ };
+
+ size_t adapterCount = 0;
+ LastEvent lastEvent = LastEvent::NoEvent;
+
+ NetworkAdapterMonitor inst(
+ logSink,
+ [&adapterCount, &lastEvent](const std::vector<MIB_IF_ROW2> &adapters, const MIB_IF_ROW2 *adapter, UpdateType updateType) -> void
+ {
+ switch (updateType)
+ {
+ case UpdateType::Add:
+ lastEvent = LastEvent::Add;
+ break;
+ case UpdateType::Delete:
+ lastEvent = LastEvent::Delete;
+ break;
+ case UpdateType::Update:
+ lastEvent = LastEvent::Update;
+ break;
+ default:
+ Assert::Fail(L"Unhandled update type");
+ }
+
+ adapterCount = adapters.size();
+ },
+ filter,
+ testProvider
+ );
+
+ //
+ // Our filter should ignore loopback devices
+ //
+
+ constexpr size_t loopbackLuid = 1;
+
+ MIB_IF_ROW2 adapter = { 0 };
+ adapter.AdminStatus = NET_IF_ADMIN_STATUS_UP;
+ adapter.InterfaceLuid.Value = loopbackLuid;
+ adapter.InterfaceLuid.Info.IfType = IF_TYPE_SOFTWARE_LOOPBACK;
+ adapter.MediaConnectState = MediaConnectStateConnected;
+ adapter.InterfaceAndOperStatusFlags.HardwareInterface = TRUE;
+ adapter.OperStatus = IfOperStatusUp;
+
+ MIB_IPINTERFACE_ROW iface4 = { 0 };
+ iface4.InterfaceLuid.Value = loopbackLuid;
+ iface4.Family = AF_INET;
+
+ lastEvent = LastEvent::NoEvent;
+
+ testProvider->addIpInterface(adapter, iface4);
+ testProvider->sendEvent(&iface4, MibAddInstance);
+
+ Assert::AreEqual(LastEvent::NoEvent, lastEvent, L"Unexpectedly received event for loopback adapter");
+
+ Assert::AreEqual(
+ 0ULL,
+ adapterCount,
+ L"Loopback adapter was not filtered correctly"
+ );
+
+ testProvider->removeIpInterface(iface4);
+ testProvider->sendEvent(&iface4, MibDeleteInstance);
+ testProvider->removeAdapter(adapter);
+
+ Assert::AreEqual(LastEvent::NoEvent, lastEvent, L"Unexpectedly received event for loopback adapter");
+
+ //
+ // Our filter should ignore devices not connected to the internet
+ //
+
+ constexpr size_t disconnectedLuid = 2;
+
+ adapter = { 0 };
+ adapter.AdminStatus = NET_IF_ADMIN_STATUS_UP;
+ adapter.InterfaceLuid.Value = disconnectedLuid;
+ adapter.MediaConnectState = MediaConnectStateDisconnected;
+ adapter.InterfaceAndOperStatusFlags.HardwareInterface = TRUE;
+ adapter.OperStatus = IfOperStatusUp;
+
+ iface4 = { 0 };
+ iface4.InterfaceLuid.Value = disconnectedLuid;
+ iface4.Family = AF_INET;
+ testProvider->addIpInterface(adapter, iface4);
+ testProvider->sendEvent(&iface4, MibAddInstance);
+
+ Assert::AreEqual(LastEvent::NoEvent, lastEvent, L"Unexpectedly received event for disconnected adapter");
+
+ testProvider->removeIpInterface(iface4);
+ testProvider->sendEvent(&iface4, MibDeleteInstance);
+ testProvider->removeAdapter(adapter);
+
+ Assert::AreEqual(LastEvent::NoEvent, lastEvent, L"Unexpectedly received event for disconnected adapter");
+
+ //
+ // Report events for hardware devices
+ //
+
+ constexpr size_t onlineHardwareLuid = 3;
+
+ adapter = { 0 };
+ adapter.AdminStatus = NET_IF_ADMIN_STATUS_UP;
+ adapter.InterfaceLuid.Value = onlineHardwareLuid;
+ adapter.MediaConnectState = MediaConnectStateConnected;
+ adapter.InterfaceAndOperStatusFlags.HardwareInterface = TRUE;
+ adapter.OperStatus = IfOperStatusUp;
+
+ iface4 = { 0 };
+ iface4.InterfaceLuid.Value = onlineHardwareLuid;
+ iface4.Family = AF_INET;
+ testProvider->addIpInterface(adapter, iface4);
+ testProvider->sendEvent(&iface4, MibAddInstance);
+
+ Assert::AreEqual(LastEvent::Add, lastEvent, L"Expected event for connected adapter was not received");
+
+ lastEvent = LastEvent::NoEvent;
+
+ testProvider->removeIpInterface(iface4);
+ testProvider->sendEvent(&iface4, MibDeleteInstance);
+ testProvider->removeAdapter(adapter);
+
+ Assert::AreEqual(LastEvent::Delete, lastEvent, L"Expected event for connected adapter was not received");
+ }
};
diff --git a/windows/winnet/src/extras/tests/testadapterutil.cpp b/windows/winnet/src/extras/tests/testadapterutil.cpp
index c38ffe81ab..09d488bc27 100644
--- a/windows/winnet/src/extras/tests/testadapterutil.cpp
+++ b/windows/winnet/src/extras/tests/testadapterutil.cpp
@@ -117,7 +117,7 @@ DWORD TestDataProvider::getIfEntry2(PMIB_IF_ROW2 Row)
// TODO: accept InterfaceIndex as well
// FIXME: should ERROR_INVALID_PARAMETER be returned if LUID = 0?
- if (Row == nullptr)
+ if (nullptr == Row)
{
return ERROR_INVALID_PARAMETER;
}
@@ -146,29 +146,29 @@ DWORD TestDataProvider::getIpInterfaceEntry(PMIB_IPINTERFACE_ROW Row)
// TODO: accept InterfaceIndex as well
// FIXME: should ERROR_INVALID_PARAMETER be returned if LUID = 0?
- if (Row == nullptr)
+ if (nullptr == Row)
{
return ERROR_INVALID_PARAMETER;
}
- if (Row->Family != AF_INET && Row->Family != AF_INET6)
+ if (AF_INET != Row->Family && AF_INET6 != Row->Family)
{
return ERROR_INVALID_PARAMETER;
}
bool foundMatchingLuid = false;
- for (auto it = m_ipInterfaces.begin(); m_ipInterfaces.end() != it; ++it)
+ for (const auto &candidate : m_ipInterfaces)
{
- if (it->InterfaceLuid.Value != Row->InterfaceLuid.Value)
+ if (candidate.InterfaceLuid.Value != Row->InterfaceLuid.Value)
{
continue;
}
foundMatchingLuid = true;
- if (Row->Family == it->Family)
+ if (Row->Family == candidate.Family)
{
- *Row = *it;
+ *Row = candidate;
return NO_ERROR;
}
}