diff options
Diffstat (limited to 'netwerk/test/gtest/TestPACMan.cpp')
-rw-r--r-- | netwerk/test/gtest/TestPACMan.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/netwerk/test/gtest/TestPACMan.cpp b/netwerk/test/gtest/TestPACMan.cpp new file mode 100644 index 0000000000..46c57cfc79 --- /dev/null +++ b/netwerk/test/gtest/TestPACMan.cpp @@ -0,0 +1,246 @@ +#include <utility> + +#include "gtest/gtest.h" +#include "nsServiceManagerUtils.h" +#include "../../../xpcom/threads/nsThreadManager.h" +#include "nsIDHCPClient.h" +#include "nsIPrefBranch.h" +#include "nsComponentManager.h" +#include "nsIPrefService.h" +#include "nsNetCID.h" +#include "mozilla/ModuleUtils.h" +#include "mozilla/GenericFactory.h" +#include "../../base/nsPACMan.h" + +#define TEST_WPAD_DHCP_OPTION "http://pac/pac.dat" +#define TEST_ASSIGNED_PAC_URL "http://assignedpac/pac.dat" +#define WPAD_PREF 4 +#define NETWORK_PROXY_TYPE_PREF_NAME "network.proxy.type" +#define GETTING_NETWORK_PROXY_TYPE_FAILED (-1) + +nsCString WPADOptionResult; + +namespace mozilla { +namespace net { + +nsresult SetNetworkProxyType(int32_t pref) { + nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); + + if (!prefs) { + return NS_ERROR_FACTORY_NOT_REGISTERED; + } + return prefs->SetIntPref(NETWORK_PROXY_TYPE_PREF_NAME, pref); +} + +nsresult GetNetworkProxyType(int32_t* pref) { + nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); + + if (!prefs) { + return NS_ERROR_FACTORY_NOT_REGISTERED; + } + return prefs->GetIntPref(NETWORK_PROXY_TYPE_PREF_NAME, pref); +} + +class nsTestDHCPClient final : public nsIDHCPClient { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIDHCPCLIENT + + nsTestDHCPClient() = default; + + nsresult Init() { return NS_OK; }; + + private: + ~nsTestDHCPClient() = default; +}; + +NS_IMETHODIMP +nsTestDHCPClient::GetOption(uint8_t option, nsACString& _retval) { + _retval.Assign(WPADOptionResult); + return NS_OK; +} + +NS_IMPL_ISUPPORTS(nsTestDHCPClient, nsIDHCPClient) + +#define NS_TESTDHCPCLIENTSERVICE_CID /* {FEBF1D69-4D7D-4891-9524-045AD18B5593} \ + */ \ + { \ + 0xFEBF1D69, 0x4D7D, 0x4891, { \ + 0x95, 0x24, 0x04, 0x5a, 0xd1, 0x8b, 0x55, 0x93 \ + } \ + } + +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsTestDHCPClient, Init) +NS_DEFINE_NAMED_CID(NS_TESTDHCPCLIENTSERVICE_CID); + +void SetOptionResult(const char* result) { WPADOptionResult.Assign(result); } + +class ProcessPendingEventsAction final : public Runnable { + public: + ProcessPendingEventsAction() : Runnable("net::ProcessPendingEventsAction") {} + + NS_IMETHOD + Run() override { + if (NS_HasPendingEvents(nullptr)) { + NS_WARNING("Found pending requests on PAC thread"); + nsresult rv; + rv = NS_ProcessPendingEvents(nullptr); + EXPECT_EQ(NS_OK, rv); + } + NS_WARNING("No pending requests on PAC thread"); + return NS_OK; + } +}; + +class TestPACMan : public ::testing::Test { + protected: + RefPtr<nsPACMan> mPACMan; + + void ProcessAllEvents() { + ProcessPendingEventsOnPACThread(); + nsresult rv; + while (NS_HasPendingEvents(nullptr)) { + NS_WARNING("Pending events on main thread"); + rv = NS_ProcessPendingEvents(nullptr); + ASSERT_EQ(NS_OK, rv); + ProcessPendingEventsOnPACThread(); + } + NS_WARNING("End of pending events on main thread"); + } + + // This method is used to ensure that all pending events on the main thread + // and the Proxy thread are processsed. + // It iterates over ProcessAllEvents because simply calling ProcessAllEvents + // once did not reliably process the events on both threads on all platforms. + void ProcessAllEventsTenTimes() { + for (int i = 0; i < 10; i++) { + ProcessAllEvents(); + } + } + + virtual void SetUp() { + ASSERT_EQ(NS_OK, GetNetworkProxyType(&originalNetworkProxyTypePref)); + nsCOMPtr<nsIFactory> factory; + nsresult rv = nsComponentManagerImpl::gComponentManager->GetClassObject( + kNS_TESTDHCPCLIENTSERVICE_CID, NS_GET_IID(nsIFactory), + getter_AddRefs(factory)); + if (NS_SUCCEEDED(rv) && factory) { + rv = nsComponentManagerImpl::gComponentManager->UnregisterFactory( + kNS_TESTDHCPCLIENTSERVICE_CID, factory); + ASSERT_EQ(NS_OK, rv); + } + factory = new mozilla::GenericFactory(nsTestDHCPClientConstructor); + nsComponentManagerImpl::gComponentManager->RegisterFactory( + kNS_TESTDHCPCLIENTSERVICE_CID, "nsTestDHCPClient", + NS_DHCPCLIENT_CONTRACTID, factory); + + mPACMan = new nsPACMan(nullptr); + mPACMan->SetWPADOverDHCPEnabled(true); + mPACMan->Init(nullptr); + ASSERT_EQ(NS_OK, SetNetworkProxyType(WPAD_PREF)); + } + + virtual void TearDown() { + mPACMan->Shutdown(); + if (originalNetworkProxyTypePref != GETTING_NETWORK_PROXY_TYPE_FAILED) { + ASSERT_EQ(NS_OK, SetNetworkProxyType(originalNetworkProxyTypePref)); + } + } + + nsCOMPtr<nsIDHCPClient> GetPACManDHCPCient() { return mPACMan->mDHCPClient; } + + void SetPACManDHCPCient(nsCOMPtr<nsIDHCPClient> aValue) { + mPACMan->mDHCPClient = std::move(aValue); + } + + void AssertPACSpecEqualTo(const char* aExpected) { + ASSERT_STREQ(aExpected, mPACMan->mPACURISpec.Data()); + } + + private: + int32_t originalNetworkProxyTypePref = GETTING_NETWORK_PROXY_TYPE_FAILED; + + void ProcessPendingEventsOnPACThread() { + RefPtr<ProcessPendingEventsAction> action = + new ProcessPendingEventsAction(); + + mPACMan->DispatchToPAC(action.forget(), /*aSync =*/true); + } +}; + +TEST_F(TestPACMan, TestCreateDHCPClientAndGetOption) { + SetOptionResult(TEST_WPAD_DHCP_OPTION); + nsCString spec; + + GetPACManDHCPCient()->GetOption(252, spec); + + ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, spec.Data()); +} + +TEST_F(TestPACMan, TestCreateDHCPClientAndGetEmptyOption) { + SetOptionResult(""); + nsCString spec; + spec.AssignLiteral(TEST_ASSIGNED_PAC_URL); + + GetPACManDHCPCient()->GetOption(252, spec); + + ASSERT_TRUE(spec.IsEmpty()); +} + +TEST_F(TestPACMan, + WhenTheDHCPClientExistsAndDHCPIsNonEmptyDHCPOptionIsUsedAsPACUri) { + SetOptionResult(TEST_WPAD_DHCP_OPTION); + + mPACMan->LoadPACFromURI(""_ns); + ProcessAllEventsTenTimes(); + + ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data()); + AssertPACSpecEqualTo(TEST_WPAD_DHCP_OPTION); +} + +TEST_F(TestPACMan, WhenTheDHCPResponseIsEmptyWPADDefaultsToStandardURL) { + SetOptionResult(""_ns.Data()); + + mPACMan->LoadPACFromURI(""_ns); + ASSERT_TRUE(NS_HasPendingEvents(nullptr)); + ProcessAllEventsTenTimes(); + + ASSERT_STREQ("", WPADOptionResult.Data()); + AssertPACSpecEqualTo("http://wpad/wpad.dat"); +} + +TEST_F(TestPACMan, WhenThereIsNoDHCPClientWPADDefaultsToStandardURL) { + SetOptionResult(TEST_WPAD_DHCP_OPTION); + SetPACManDHCPCient(nullptr); + + mPACMan->LoadPACFromURI(""_ns); + ProcessAllEventsTenTimes(); + + ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data()); + AssertPACSpecEqualTo("http://wpad/wpad.dat"); +} + +TEST_F(TestPACMan, WhenWPADOverDHCPIsPreffedOffWPADDefaultsToStandardURL) { + SetOptionResult(TEST_WPAD_DHCP_OPTION); + mPACMan->SetWPADOverDHCPEnabled(false); + + mPACMan->LoadPACFromURI(""_ns); + ProcessAllEventsTenTimes(); + + ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data()); + AssertPACSpecEqualTo("http://wpad/wpad.dat"); +} + +TEST_F(TestPACMan, WhenPACUriIsSetDirectlyItIsUsedRatherThanWPAD) { + SetOptionResult(TEST_WPAD_DHCP_OPTION); + nsCString spec; + spec.AssignLiteral(TEST_ASSIGNED_PAC_URL); + + mPACMan->LoadPACFromURI(spec); + ProcessAllEventsTenTimes(); + + AssertPACSpecEqualTo(TEST_ASSIGNED_PAC_URL); +} + +} // namespace net +} // namespace mozilla |