diff options
author | noamsml@chromium.org <noamsml@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-05 06:04:08 +0000 |
---|---|---|
committer | noamsml@chromium.org <noamsml@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-05 06:04:08 +0000 |
commit | f4eb2765683b2a9f7eb3ec1553e6f0c205982945 (patch) | |
tree | 7f6dcf5ecee00f1038390af6a5c23df8a6620b7a | |
parent | e7aa6daf77a7efce902150c0ff05b3f4ae4e2edb (diff) | |
download | chromium_src-f4eb2765683b2a9f7eb3ec1553e6f0c205982945.zip chromium_src-f4eb2765683b2a9f7eb3ec1553e6f0c205982945.tar.gz chromium_src-f4eb2765683b2a9f7eb3ec1553e6f0c205982945.tar.bz2 |
Modified LocalDiscoveryUIBrowsertest to use actual ServiceDiscoveryClientImpl
Removed mock PrivetDeviceLister, changed LocalDiscoveryUIBrowsertest to use a
testing ServiceDiscoverySharedClient that delegates to a
ServiceDiscoveryClientImpl with a mocked network, allowing the test to be
written in terms of packets rather than calls to method of PrivetDeviceLister.
BUG=
Review URL: https://codereview.chromium.org/25649002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227197 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 247 insertions, 108 deletions
diff --git a/chrome/browser/local_discovery/DEPS b/chrome/browser/local_discovery/DEPS new file mode 100644 index 0000000..cc56ec5b --- /dev/null +++ b/chrome/browser/local_discovery/DEPS @@ -0,0 +1,6 @@ +specific_include_rules = { + # For tests, it's fine to include utility process code. + 'test_service_discovery_client\.cc': [ + "+chrome/utility/local_discovery/service_discovery_client_impl.h" + ], +}
\ No newline at end of file diff --git a/chrome/browser/local_discovery/test_service_discovery_client.cc b/chrome/browser/local_discovery/test_service_discovery_client.cc new file mode 100644 index 0000000..60be86f --- /dev/null +++ b/chrome/browser/local_discovery/test_service_discovery_client.cc @@ -0,0 +1,60 @@ +// Copyright 2013 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 "chrome/browser/local_discovery/test_service_discovery_client.h" + +#include "chrome/utility/local_discovery/service_discovery_client_impl.h" +#include "net/dns/mdns_client_impl.h" + +namespace local_discovery { + +TestServiceDiscoveryClient::TestServiceDiscoveryClient() { +} + +TestServiceDiscoveryClient::~TestServiceDiscoveryClient() { +} + +void TestServiceDiscoveryClient::Start() { + mock_socket_factory_ = new net::MockMDnsSocketFactory(); + mdns_client_.reset(new net::MDnsClientImpl( + scoped_ptr<net::MDnsConnection::SocketFactory>(mock_socket_factory_))); + service_discovery_client_impl_.reset(new ServiceDiscoveryClientImpl( + mdns_client_.get())); + mdns_client_->StartListening(); + + EXPECT_CALL(*mock_socket_factory_, OnSendTo(testing::_)) + .Times(testing::AnyNumber()) + .WillRepeatedly(testing::Invoke(this, + &TestServiceDiscoveryClient::OnSendTo)); +} + +scoped_ptr<ServiceWatcher> TestServiceDiscoveryClient::CreateServiceWatcher( + const std::string& service_type, + const ServiceWatcher::UpdatedCallback& callback) { + return service_discovery_client_impl_->CreateServiceWatcher(service_type, + callback); +} + +scoped_ptr<ServiceResolver> TestServiceDiscoveryClient::CreateServiceResolver( + const std::string& service_name, + const ServiceResolver::ResolveCompleteCallback& callback) { + return service_discovery_client_impl_->CreateServiceResolver(service_name, + callback); +} + +scoped_ptr<LocalDomainResolver> +TestServiceDiscoveryClient::CreateLocalDomainResolver( + const std::string& domain, + net::AddressFamily address_family, + const LocalDomainResolver::IPAddressCallback& callback) { + return service_discovery_client_impl_->CreateLocalDomainResolver( + domain, address_family, callback); +} + +void TestServiceDiscoveryClient::SimulateReceive(const uint8* packet, + int size) { + mock_socket_factory_->SimulateReceive(packet, size); +} + +} // namespace local_discovery diff --git a/chrome/browser/local_discovery/test_service_discovery_client.h b/chrome/browser/local_discovery/test_service_discovery_client.h new file mode 100644 index 0000000..3d9fb81 --- /dev/null +++ b/chrome/browser/local_discovery/test_service_discovery_client.h @@ -0,0 +1,48 @@ +// Copyright 2013 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. + +#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_TEST_SERVICE_DISCOVERY_CLIENT_H_ +#define CHROME_BROWSER_LOCAL_DISCOVERY_TEST_SERVICE_DISCOVERY_CLIENT_H_ + +#include "chrome/browser/local_discovery/service_discovery_shared_client.h" +#include "chrome/common/local_discovery/service_discovery_client.h" +#include "net/dns/mdns_client.h" +#include "net/dns/mock_mdns_socket_factory.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace local_discovery { + +class TestServiceDiscoveryClient : public ServiceDiscoverySharedClient { + public: + TestServiceDiscoveryClient(); + + void Start(); + + virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher( + const std::string& service_type, + const ServiceWatcher::UpdatedCallback& callback) OVERRIDE; + virtual scoped_ptr<ServiceResolver> CreateServiceResolver( + const std::string& service_name, + const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE; + virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver( + const std::string& domain, + net::AddressFamily address_family, + const LocalDomainResolver::IPAddressCallback& callback) OVERRIDE; + + MOCK_METHOD1(OnSendTo, void(const std::string& data)); + + void SimulateReceive(const uint8* packet, int size); + + private: + ~TestServiceDiscoveryClient(); + + // Owned by mdns_client_impl_. + net::MockMDnsSocketFactory* mock_socket_factory_; + scoped_ptr<net::MDnsClient> mdns_client_; + scoped_ptr<ServiceDiscoveryClient> service_discovery_client_impl_; +}; + +} // namespace local_discovery + +#endif // CHROME_BROWSER_LOCAL_DISCOVERY_TEST_SERVICE_DISCOVERY_CLIENT_H_ diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui.cc index fb88448..3383e18 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui.cc @@ -113,7 +113,7 @@ LocalDiscoveryUI::LocalDiscoveryUI(content::WebUI* web_ui) // TODO(gene): Use LocalDiscoveryUIHandler to send updated to the devices // page. For example - web_ui->AddMessageHandler(local_discovery::LocalDiscoveryUIHandler::Create()); + web_ui->AddMessageHandler(new local_discovery::LocalDiscoveryUIHandler()); web_ui->AddMessageHandler(new MetricsHandler()); } diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc index 78d04ff..b1895d7 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc @@ -9,16 +9,114 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" +#include "chrome/browser/local_discovery/test_service_discovery_client.h" #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.cc" #include "chrome/test/base/web_ui_browsertest.h" +using testing::InvokeWithoutArgs; +using testing::Return; +using testing::AtLeast; + namespace local_discovery { namespace { +const uint8 kQueryData[] = { + // Header + 0x00, 0x00, + 0x00, 0x00, // Flags not set. + 0x00, 0x01, // Set QDCOUNT (question count) to 1, all the + // rest are 0 for a query. + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + + // Question + 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', + 0x04, '_', 't', 'c', 'p', + 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + + 0x00, 0x0c, // QTYPE: A query. + 0x00, 0x01, // QCLASS: IN class. Unicast bit not set. +}; + +const uint8 kAnnouncePacket[] = { + // Header + 0x00, 0x00, // ID is zeroed out + 0x80, 0x00, // Standard query response, no error + 0x00, 0x00, // No questions (for simplicity) + 0x00, 0x03, // 1 RR (answers) + 0x00, 0x00, // 0 authority RRs + 0x00, 0x00, // 0 additional RRs + + 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', + 0x04, '_', 't', 'c', 'p', + 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + 0x00, 0x0c, // TYPE is PTR. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, // TTL (4 bytes) is 32768 second. + 0x10, 0x00, + 0x00, 0x0c, // RDLENGTH is 12 bytes. + 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e', + 0xc0, 0x0c, + + 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e', + 0xc0, 0x0c, + 0x00, 0x10, // TYPE is TXT. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, // TTL (4 bytes) is 32768 seconds. + 0x01, 0x00, + 0x00, 0x34, // RDLENGTH is 69 bytes. + 0x03, 'i', 'd', '=', + 0x10, 't', 'y', '=', 'S', 'a', 'm', 'p', 'l', 'e', ' ', + 'd', 'e', 'v', 'i', 'c', 'e', + 0x1e, 'n', 'o', 't', 'e', '=', + 'S', 'a', 'm', 'p', 'l', 'e', ' ', 'd', 'e', 'v', 'i', 'c', 'e', ' ', + 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', + + 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e', + 0xc0, 0x0c, + 0x00, 0x21, // Type is SRV + 0x00, 0x01, // CLASS is IN + 0x00, 0x00, // TTL (4 bytes) is 32768 second. + 0x10, 0x00, + 0x00, 0x17, // RDLENGTH is 23 + 0x00, 0x00, + 0x00, 0x00, + 0x22, 0xb8, // port 8888 + 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e', + 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00 +}; + + +const uint8 kGoodbyePacket[] = { + // Header + 0x00, 0x00, // ID is zeroed out + 0x80, 0x00, // Standard query response, RA, no error + 0x00, 0x00, // No questions (for simplicity) + 0x00, 0x01, // 1 RR (answers) + 0x00, 0x00, // 0 authority RRs + 0x00, 0x00, // 0 additional RRs + + 0x07, '_', 'p', 'r', 'i', 'v', 'e', 't', + 0x04, '_', 't', 'c', 'p', + 0x05, 'l', 'o', 'c', 'a', 'l', + 0x00, + 0x00, 0x0c, // TYPE is PTR. + 0x00, 0x01, // CLASS is IN. + 0x00, 0x00, // TTL (4 bytes) is 0 seconds. + 0x00, 0x00, + 0x00, 0x0c, // RDLENGTH is 12 bytes. + 0x09, 'm', 'y', 'S', 'e', 'r', 'v', 'i', 'c', 'e', + 0xc0, 0x0c, +}; + const char kSampleServiceName[] = "myService._privet._tcp.local"; class TestMessageLoopCondition { @@ -54,69 +152,6 @@ class TestMessageLoopCondition { DISALLOW_COPY_AND_ASSIGN(TestMessageLoopCondition); }; -class FakePrivetDeviceLister : public PrivetDeviceLister { - public: - explicit FakePrivetDeviceLister(const base::Closure& discover_devices_called) - : discover_devices_called_(discover_devices_called) { - } - - virtual ~FakePrivetDeviceLister() { - } - - // PrivetDeviceLister implementation. - virtual void Start() OVERRIDE { - } - - virtual void DiscoverNewDevices(bool force_referesh) OVERRIDE { - discover_devices_called_.Run(); - } - - void set_delegate(Delegate* delegate) { delegate_ = delegate; } - Delegate* delegate() { return delegate_; } - - private: - Delegate* delegate_; - base::Closure discover_devices_called_; - - DISALLOW_COPY_AND_ASSIGN(FakePrivetDeviceLister); -}; - -class FakeLocalDiscoveryUIFactory : public LocalDiscoveryUIHandler::Factory { - public: - explicit FakeLocalDiscoveryUIFactory( - scoped_ptr<FakePrivetDeviceLister> privet_lister) { - owned_privet_lister_ = privet_lister.Pass(); - privet_lister_ = owned_privet_lister_.get(); - LocalDiscoveryUIHandler::SetFactory(this); - } - - virtual ~FakeLocalDiscoveryUIFactory() { - LocalDiscoveryUIHandler::SetFactory(NULL); - } - - // LocalDiscoveryUIHandler::Factory implementation. - virtual LocalDiscoveryUIHandler* CreateLocalDiscoveryUIHandler() OVERRIDE { - DCHECK(owned_privet_lister_); // This factory is a one-use factory. - scoped_ptr<LocalDiscoveryUIHandler> handler( - new LocalDiscoveryUIHandler( - owned_privet_lister_.PassAs<PrivetDeviceLister>())); - privet_lister_->set_delegate(handler.get()); - return handler.release(); - } - - FakePrivetDeviceLister* privet_lister() { return privet_lister_; } - - private: - // FakePrivetDeviceLister is owned either by the factory or, once it creates a - // LocalDiscoveryUI, by the LocalDiscoveryUI. |privet_lister_| points to the - // FakePrivetDeviceLister whereas |owned_privet_lister_| manages the ownership - // of the pointer when it is owned by the factory. - scoped_ptr<FakePrivetDeviceLister> owned_privet_lister_; - FakePrivetDeviceLister* privet_lister_; - - DISALLOW_COPY_AND_ASSIGN(FakeLocalDiscoveryUIFactory); -}; - class LocalDiscoveryUITest : public WebUIBrowserTest { public: LocalDiscoveryUITest() { @@ -127,13 +162,15 @@ class LocalDiscoveryUITest : public WebUIBrowserTest { virtual void SetUpOnMainThread() OVERRIDE { WebUIBrowserTest::SetUpOnMainThread(); - scoped_ptr<FakePrivetDeviceLister> fake_lister; - fake_lister.reset(new FakePrivetDeviceLister( - base::Bind(&TestMessageLoopCondition::Signal, - base::Unretained(&condition_devices_listed_)))); - - ui_factory_.reset(new FakeLocalDiscoveryUIFactory( - fake_lister.Pass())); + test_service_discovery_client_ = new TestServiceDiscoveryClient(); + test_service_discovery_client_->Start(); + EXPECT_CALL(*test_service_discovery_client_, OnSendTo( + std::string((const char*)kQueryData, + sizeof(kQueryData)))) + .Times(AtLeast(2)) + .WillOnce(InvokeWithoutArgs(&condition_devices_listed_, + &TestMessageLoopCondition::Signal)) + .WillRepeatedly(Return()); AddLibrary(base::FilePath(FILE_PATH_LITERAL("local_discovery_ui_test.js"))); } @@ -142,13 +179,27 @@ class LocalDiscoveryUITest : public WebUIBrowserTest { WebUIBrowserTest::SetUpCommandLine(command_line); } - FakeLocalDiscoveryUIFactory* ui_factory() { return ui_factory_.get(); } + void RunFor(base::TimeDelta time_period) { + base::CancelableCallback<void()> callback(base::Bind( + &base::MessageLoop::Quit, base::Unretained( + base::MessageLoop::current()))); + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, callback.callback(), time_period); + + base::MessageLoop::current()->Run(); + callback.Cancel(); + } + + TestServiceDiscoveryClient* test_service_discovery_client() { + return test_service_discovery_client_.get(); + } + TestMessageLoopCondition& condition_devices_listed() { return condition_devices_listed_; } private: - scoped_ptr<FakeLocalDiscoveryUIFactory> ui_factory_; + scoped_refptr<TestServiceDiscoveryClient> test_service_discovery_client_; TestMessageLoopCondition condition_devices_listed_; DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryUITest); @@ -165,18 +216,18 @@ IN_PROC_BROWSER_TEST_F(LocalDiscoveryUITest, AddRowTest) { ui_test_utils::NavigateToURL(browser(), GURL( chrome::kChromeUIDevicesURL)); condition_devices_listed().Wait(); - DeviceDescription description; - description.name = "Sample device"; - description.description = "Sample device description"; + test_service_discovery_client()->SimulateReceive( + kAnnouncePacket, sizeof(kAnnouncePacket)); - ui_factory()->privet_lister()->delegate()->DeviceChanged( - true, kSampleServiceName, description); + base::MessageLoop::current()->RunUntilIdle(); EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkOneDevice")); - ui_factory()->privet_lister()->delegate()->DeviceRemoved( - kSampleServiceName); + test_service_discovery_client()->SimulateReceive( + kGoodbyePacket, sizeof(kGoodbyePacket)); + + RunFor(base::TimeDelta::FromMilliseconds(1100)); EXPECT_TRUE(WebUIBrowserTest::RunJavascriptTest("checkNoDevices")); } diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc index 5faa5e0..7c9bb88 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc @@ -61,7 +61,6 @@ const int kInitialRequeryTimeSeconds = 1; const int kMaxRequeryTimeSeconds = 2; // Time for last requery const int kRequeryExpontentialGrowthBase = 2; -LocalDiscoveryUIHandler::Factory* g_factory = NULL; int g_num_visible = 0; } // namespace @@ -83,28 +82,12 @@ LocalDiscoveryUIHandler::LocalDiscoveryUIHandler() : is_visible_(false) { #endif // !defined(OS_MACOSX) } -LocalDiscoveryUIHandler::LocalDiscoveryUIHandler( - scoped_ptr<PrivetDeviceLister> privet_lister) : is_visible_(false) { - privet_lister.swap(privet_lister_); -} - LocalDiscoveryUIHandler::~LocalDiscoveryUIHandler() { ResetCurrentRegistration(); SetIsVisible(false); } // static -LocalDiscoveryUIHandler* LocalDiscoveryUIHandler::Create() { - if (g_factory) return g_factory->CreateLocalDiscoveryUIHandler(); - return new LocalDiscoveryUIHandler(); -} - -// static -void LocalDiscoveryUIHandler::SetFactory(Factory* factory) { - g_factory = factory; -} - -// static bool LocalDiscoveryUIHandler::GetHasVisible() { return g_num_visible != 0; } diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h index da7b698..ebe4c35 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h @@ -40,20 +40,9 @@ class LocalDiscoveryUIHandler : public content::WebUIMessageHandler, public CloudPrintPrinterList::Delegate, content::NotificationObserver { public: - class Factory { - public: - virtual ~Factory() {} - virtual LocalDiscoveryUIHandler* CreateLocalDiscoveryUIHandler() = 0; - }; - LocalDiscoveryUIHandler(); - // This constructor should only used by tests. - explicit LocalDiscoveryUIHandler( - scoped_ptr<PrivetDeviceLister> privet_lister); virtual ~LocalDiscoveryUIHandler(); - static LocalDiscoveryUIHandler* Create(); - static void SetFactory(Factory* factory); static bool GetHasVisible(); // WebUIMessageHandler implementation. diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 190fc6b..989c715 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1907,6 +1907,8 @@ }], ['enable_mdns==1', { 'sources' : [ + 'browser/local_discovery/test_service_discovery_client.cc', + 'browser/local_discovery/test_service_discovery_client.h', 'browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc', ] }], |