summaryrefslogtreecommitdiffstats
path: root/netwerk/test/gtest/TestPACMan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/gtest/TestPACMan.cpp')
-rw-r--r--netwerk/test/gtest/TestPACMan.cpp246
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