diff options
| author | David Lönnhager <david.l@mullvad.net> | 2019-10-24 15:36:09 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2019-10-30 14:58:41 +0100 |
| commit | 244580c77486ea891b6cd9ba7a554fa07e1435fd (patch) | |
| tree | 65805603448d183a7954b7a7a971b104bf7b9ce5 /windows | |
| parent | f811029e68668b6e82f52abafa2b14e4203f98f4 (diff) | |
| download | mullvadvpn-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.cpp | 181 | ||||
| -rw-r--r-- | windows/winnet/src/extras/tests/testadapterutil.cpp | 14 |
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; } } |
