Index: content/renderer/p2p/filtering_network_manager_unittest.cc |
diff --git a/content/renderer/p2p/filtering_network_manager_unittest.cc b/content/renderer/p2p/filtering_network_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..23e133f319ac5f7a35217a0efd59342f6fd7c8db |
--- /dev/null |
+++ b/content/renderer/p2p/filtering_network_manager_unittest.cc |
@@ -0,0 +1,357 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/renderer/p2p/filtering_network_manager.h" |
+ |
+#include "base/logging.h" |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/test/test_simple_task_runner.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "content/renderer/p2p/empty_network_manager.h" |
+#include "media/base/media_permission.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/webrtc/base/ipaddress.h" |
+ |
+using NetworkList = rtc::NetworkManager::NetworkList; |
+ |
+namespace { |
+ |
+enum EventType { |
+ MIC_DENIED, // Receive mic permission denied. |
+ MIC_GRANTED, // Receive mic permission granted. |
+ CAMERA_DENIED, // Receive camera permission denied. |
+ CAMERA_GRANTED, // Receive camera permission granted. |
+ START_UPDATING, // Client calls StartUpdating() on FilteringNetworkManager. |
+ STOP_UPDATING, // Client calls StopUpdating() on FilteringNetworkManager. |
+ MOCK_NETWORKS_CHANGED, // MockNetworkManager has signaled networks changed |
+ // event. |
+}; |
+ |
+enum ResultType { |
+ NO_SIGNAL, // Do not expect SignalNetworksChanged fired. |
+ SIGNAL_ENUMERATION_BLOCKED, // Expect SignalNetworksChanged and |
+ // ENUMERATION_BLOCKED. |
+ SIGNAL_ENUMERATION_ALLOWED, // Expect SignalNetworksChanged and |
+ // ENUMERATION_ALLOWED. |
+}; |
+ |
+struct TestEntry { |
+ EventType event; |
+ ResultType expected_result; |
+}; |
+ |
+class MockNetworkManager : public rtc::NetworkManager { |
+ public: |
+ MockNetworkManager() { |
+ network_.reset(new rtc::Network("test_eth0", "Test Network Adapter 1", |
+ rtc::IPAddress(0x12345600U), 24, |
+ rtc::ADAPTER_TYPE_ETHERNET)); |
+ } |
+ // Mimic the current behavior that once the first signal is sent, any future |
+ // StartUpdating() will trigger another one. |
+ void StartUpdating() override { |
+ if (sent_first_update_) |
+ SignalNetworksChanged(); |
+ } |
+ void StopUpdating() override {} |
+ void GetNetworks(NetworkList* networks) const override { |
+ networks->push_back(network_.get()); |
+ } |
+ |
+ void SendNetworksChanged() { |
+ sent_first_update_ = true; |
+ SignalNetworksChanged(); |
+ } |
+ |
+ private: |
+ bool sent_first_update_ = false; |
+ scoped_ptr<rtc::Network> network_; |
+}; |
+ |
+class MockMediaPermission : public media::MediaPermission { |
+ public: |
+ MockMediaPermission() {} |
+ ~MockMediaPermission() override {} |
+ |
+ void RequestPermission( |
+ Type type, |
+ const GURL& security_origin, |
+ const PermissionStatusCB& permission_status_cb) override { |
+ NOTIMPLEMENTED(); |
+ } |
+ |
+ void HasPermission(Type type, |
+ const GURL& security_origin, |
+ const PermissionStatusCB& permission_status_cb) override { |
+ if (type == MediaPermission::AUDIO_CAPTURE) { |
+ DCHECK(mic_callback_.is_null()); |
+ mic_callback_ = permission_status_cb; |
+ } else { |
+ DCHECK(type == MediaPermission::VIDEO_CAPTURE); |
+ DCHECK(camera_callback_.is_null()); |
+ camera_callback_ = permission_status_cb; |
+ } |
+ } |
+ |
+ void SetMicPermission(bool granted) { |
+ if (mic_callback_.is_null()) |
+ return; |
+ |
+ mic_callback_.Run(granted); |
+ mic_callback_ = PermissionStatusCB(); |
+ } |
+ |
+ void SetCameraPermission(bool granted) { |
+ if (camera_callback_.is_null()) |
+ return; |
+ |
+ camera_callback_.Run(granted); |
+ camera_callback_ = PermissionStatusCB(); |
+ } |
+ |
+ private: |
+ PermissionStatusCB mic_callback_; |
+ PermissionStatusCB camera_callback_; |
+}; |
+ |
+} // namespace |
+ |
+namespace content { |
+ |
+class FilteringNetworkManagerTest : public testing::Test, |
+ public sigslot::has_slots<> { |
+ public: |
+ FilteringNetworkManagerTest() |
+ : task_runner_(new base::TestSimpleTaskRunner()), |
+ task_runner_handle_(task_runner_) {} |
+ void SetupNetworkManager(bool multiple_routes_requested) { |
+ mock_network_manager_.reset(new MockNetworkManager()); |
+ |
+ scoped_ptr<MockMediaPermission> media_permission(new MockMediaPermission()); |
+ media_permission_ = media_permission.get(); |
+ if (multiple_routes_requested) { |
+ FilteringNetworkManager* filtering_network_manager = |
+ new FilteringNetworkManager(mock_network_manager_.get(), GURL(), |
+ media_permission.Pass()); |
+ filtering_network_manager->Initialize(); |
+ network_manager_.reset(filtering_network_manager); |
+ } else { |
+ network_manager_.reset(new EmptyNetworkManager()); |
+ } |
+ network_manager_->SignalNetworksChanged.connect( |
+ this, &FilteringNetworkManagerTest::OnNetworksChanged); |
+ } |
+ |
+ void RunTests(TestEntry* tests, size_t size) { |
+ for (size_t i = 0; i < size; ++i) { |
+ EXPECT_EQ(tests[i].expected_result, ProcessEvent(tests[i].event)) |
+ << " in step: " << i; |
+ } |
+ } |
+ |
+ ResultType ProcessEvent(EventType event) { |
+ clear_callback_called(); |
+ switch (event) { |
+ case MIC_DENIED: |
+ case MIC_GRANTED: |
+ media_permission_->SetMicPermission(event == MIC_GRANTED); |
+ break; |
+ case CAMERA_DENIED: |
+ case CAMERA_GRANTED: |
+ media_permission_->SetCameraPermission(event == CAMERA_GRANTED); |
+ break; |
+ case START_UPDATING: |
+ network_manager_->StartUpdating(); |
+ break; |
+ case STOP_UPDATING: |
+ network_manager_->StopUpdating(); |
+ break; |
+ case MOCK_NETWORKS_CHANGED: |
+ mock_network_manager_->SendNetworksChanged(); |
+ break; |
+ } |
+ |
+ task_runner_->RunUntilIdle(); |
+ |
+ if (!callback_called_) |
+ return NO_SIGNAL; |
+ |
+ if (network_manager_->enumeration_permission() == |
+ rtc::NetworkManager::ENUMERATION_BLOCKED) { |
+ EXPECT_EQ(0u, GetP2PNetworkList().size()); |
+ return SIGNAL_ENUMERATION_BLOCKED; |
+ } |
+ EXPECT_EQ(1u, GetP2PNetworkList().size()); |
+ return SIGNAL_ENUMERATION_ALLOWED; |
+ } |
+ |
+ protected: |
+ const NetworkList& GetP2PNetworkList() { |
+ network_list_.clear(); |
+ network_manager_->GetNetworks(&network_list_); |
+ return network_list_; |
+ } |
+ |
+ void OnNetworksChanged() { callback_called_ = true; } |
+ void clear_callback_called() { callback_called_ = false; } |
+ |
+ bool callback_called_ = false; |
+ scoped_ptr<rtc::NetworkManager> network_manager_; |
+ scoped_ptr<MockNetworkManager> mock_network_manager_; |
+ |
+ // Raw pointer to MockMediaPermission. It's owned by FilteringNetworkManager. |
+ MockMediaPermission* media_permission_ = nullptr; |
+ |
+ NetworkList network_list_; |
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
+ base::ThreadTaskRunnerHandle task_runner_handle_; |
+}; |
+ |
+// Test that when multiple routes is not requested, SignalNetworksChanged is |
+// fired right after the StartUpdating(). |
+TEST_F(FilteringNetworkManagerTest, MultipleRoutesNotRequested) { |
+ SetupNetworkManager(false); |
+ TestEntry tests[] = { |
+ // Underneath network manager signals, no callback as StartUpdating() is |
+ // not called. |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ // StartUpdating() is called, should receive callback as the multiple |
+ // routes is not requested. |
+ {START_UPDATING, SIGNAL_ENUMERATION_BLOCKED}, |
+ // Further network signal shouldn't trigger callback in |
+ // ENUMERATION_BLOCKED mode. |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ // New StartUpdating() should trigger callback. |
+ {START_UPDATING, SIGNAL_ENUMERATION_BLOCKED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ }; |
+ |
+ RunTests(tests, arraysize(tests)); |
+} |
+ |
+// Test that multiple routes request is blocked and signaled right after |
+// StartUpdating() since mic/camera permissions are denied. |
+TEST_F(FilteringNetworkManagerTest, BlockMultipleRoutesByStartUpdating) { |
+ SetupNetworkManager(true); |
+ |
+ TestEntry tests[] = { |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ // Both mic and camera are denied. |
+ {MIC_DENIED, NO_SIGNAL}, |
+ {CAMERA_DENIED, NO_SIGNAL}, |
+ // Once StartUpdating() is called, signal network changed event with |
+ // ENUMERATION_BLOCKED. |
+ {START_UPDATING, SIGNAL_ENUMERATION_BLOCKED}, |
+ // Further network signal shouldn't trigger callback. |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ // New StartUpdating() should trigger callback. |
+ {START_UPDATING, SIGNAL_ENUMERATION_BLOCKED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ }; |
+ |
+ RunTests(tests, arraysize(tests)); |
+} |
+ |
+// Test that multiple routes request is blocked and signaled right after |
+// last pending permission check is denied since StartUpdating() has been called |
+// previously. |
+TEST_F(FilteringNetworkManagerTest, BlockMultipleRoutesByPermissionsDenied) { |
+ SetupNetworkManager(true); |
+ |
+ TestEntry tests[] = { |
+ {START_UPDATING, NO_SIGNAL}, |
+ {MIC_DENIED, NO_SIGNAL}, |
+ // Once camera is denied, no need to wait for networkchanged event from |
+ // network_manager_. |
+ {CAMERA_DENIED, SIGNAL_ENUMERATION_BLOCKED}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ {START_UPDATING, SIGNAL_ENUMERATION_BLOCKED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ }; |
+ |
+ RunTests(tests, arraysize(tests)); |
+} |
+ |
+// Test that multiple routes request is granted and signaled right after |
+// a pending permission check is granted since StartUpdating() has been called |
+// previously. |
+TEST_F(FilteringNetworkManagerTest, AllowMultipleRoutesByPermissionsGranted) { |
+ SetupNetworkManager(true); |
+ |
+ TestEntry tests[] = { |
+ {START_UPDATING, NO_SIGNAL}, |
+ {MIC_DENIED, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ // Once one media type is granted, signal networkschanged with |
+ // ENUMERATION_ALLOWED. |
+ {CAMERA_GRANTED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {START_UPDATING, SIGNAL_ENUMERATION_ALLOWED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ // If there is any outstanding StartUpdating(), new event from underneath |
+ // network manger should trigger SignalNetworksChanged. |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ // No outstanding StartUpdating(), no more signal. |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ }; |
+ |
+ RunTests(tests, arraysize(tests)); |
+} |
+ |
+// Test that multiple routes request is granted and signaled right after |
+// StartUpdating() since there is at least one media permission granted. |
+TEST_F(FilteringNetworkManagerTest, AllowMultipleRoutesByStartUpdating) { |
+ SetupNetworkManager(true); |
+ |
+ TestEntry tests[] = { |
+ {MIC_DENIED, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ {CAMERA_GRANTED, NO_SIGNAL}, |
+ // StartUpdating() should trigger the event since at least one media is |
+ // granted and network information is populated. |
+ {START_UPDATING, SIGNAL_ENUMERATION_ALLOWED}, |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {START_UPDATING, SIGNAL_ENUMERATION_ALLOWED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ }; |
+ |
+ RunTests(tests, arraysize(tests)); |
+} |
+ |
+// Test that multiple routes request is granted and signaled right after |
+// underneath NetworkManager's SignalNetworksChanged() as at least one |
+// permission is granted and StartUpdating() has been called. |
+TEST_F(FilteringNetworkManagerTest, AllowMultipleRoutesByNetworksChanged) { |
+ SetupNetworkManager(true); |
+ |
+ TestEntry tests[] = { |
+ {START_UPDATING, NO_SIGNAL}, |
+ {CAMERA_GRANTED, NO_SIGNAL}, |
+ // Underneath network manager's signal networks changed should trigger |
+ // SignalNetworksChanged with ENUMERATION_ALLOWED. |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {MIC_DENIED, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {START_UPDATING, SIGNAL_ENUMERATION_ALLOWED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, SIGNAL_ENUMERATION_ALLOWED}, |
+ {STOP_UPDATING, NO_SIGNAL}, |
+ {MOCK_NETWORKS_CHANGED, NO_SIGNAL}, |
+ }; |
+ |
+ RunTests(tests, arraysize(tests)); |
+} |
+ |
+} // namespace content |