| Index: chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
|
| diff --git a/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm b/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
|
| index d96a31a295989fa1bba7e2de8554ee49c931ea21..a30595785d44387710f0f88e3bc44d61b94d7a3e 100644
|
| --- a/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
|
| +++ b/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
|
| @@ -6,6 +6,7 @@
|
| #include <stdint.h>
|
|
|
| #include "base/bind.h"
|
| +#include "base/callback.h"
|
| #include "base/mac/scoped_nsobject.h"
|
| #include "base/macros.h"
|
| #include "base/run_loop.h"
|
| @@ -19,8 +20,8 @@
|
|
|
| @interface TestNSNetService : NSNetService {
|
| @private
|
| - NSData* data_;
|
| - NSArray* addresses_;
|
| + base::scoped_nsobject<NSData> data_;
|
| + base::scoped_nsobject<NSArray> addresses_;
|
| }
|
| - (id)initWithData:(NSData*)data;
|
| - (void)setAddresses:(NSArray*)addresses;
|
| @@ -30,13 +31,13 @@
|
|
|
| - (id)initWithData:(NSData*)data {
|
| if ((self = [super init])) {
|
| - data_ = data;
|
| + data_.reset([data retain]);
|
| }
|
| return self;
|
| }
|
|
|
| - (void)setAddresses:(NSArray*)addresses {
|
| - addresses_ = addresses;
|
| + addresses_.reset([addresses copy]);
|
| }
|
|
|
| - (NSArray*)addresses {
|
| @@ -53,9 +54,10 @@ namespace local_discovery {
|
|
|
| class ServiceDiscoveryClientMacTest : public CocoaTest {
|
| public:
|
| - ServiceDiscoveryClientMacTest() : num_updates_(0), num_resolves_(0) {
|
| - client_mac_ = new ServiceDiscoveryClientMac();
|
| - client_ = client_mac_.get();
|
| + ServiceDiscoveryClientMacTest()
|
| + : client_(new ServiceDiscoveryClientMac()),
|
| + num_updates_(0),
|
| + num_resolves_(0) {
|
| }
|
|
|
| void OnServiceUpdated(
|
| @@ -66,7 +68,6 @@ class ServiceDiscoveryClientMacTest : public CocoaTest {
|
| num_updates_++;
|
| }
|
|
|
| -
|
| void OnResolveComplete(
|
| ServiceResolver::RequestStatus status,
|
| const ServiceDescription& service_description) {
|
| @@ -75,11 +76,12 @@ class ServiceDiscoveryClientMacTest : public CocoaTest {
|
| num_resolves_++;
|
| }
|
|
|
| + ServiceDiscoveryClient* client() { return client_.get(); }
|
| +
|
| protected:
|
| content::TestBrowserThreadBundle thread_bundle_;
|
|
|
| - scoped_refptr<ServiceDiscoveryClientMac> client_mac_;
|
| - ServiceDiscoveryClient* client_; // weak
|
| + scoped_refptr<ServiceDiscoveryClientMac> client_;
|
|
|
| ServiceWatcher::UpdateType last_update_;
|
| std::string last_service_name_;
|
| @@ -93,7 +95,7 @@ TEST_F(ServiceDiscoveryClientMacTest, ServiceWatcher) {
|
| const std::string test_service_type = "_testing._tcp.local";
|
| const std::string test_service_name = "Test.123";
|
|
|
| - std::unique_ptr<ServiceWatcher> watcher = client_->CreateServiceWatcher(
|
| + std::unique_ptr<ServiceWatcher> watcher = client()->CreateServiceWatcher(
|
| test_service_type,
|
| base::Bind(&ServiceDiscoveryClientMacTest::OnServiceUpdated,
|
| base::Unretained(this)));
|
| @@ -115,15 +117,15 @@ TEST_F(ServiceDiscoveryClientMacTest, ServiceWatcher) {
|
|
|
| TEST_F(ServiceDiscoveryClientMacTest, ServiceResolver) {
|
| const std::string test_service_name = "Test.123._testing._tcp.local";
|
| - std::unique_ptr<ServiceResolver> resolver = client_->CreateServiceResolver(
|
| + std::unique_ptr<ServiceResolver> resolver = client()->CreateServiceResolver(
|
| test_service_name,
|
| base::Bind(&ServiceDiscoveryClientMacTest::OnResolveComplete,
|
| base::Unretained(this)));
|
|
|
| const uint8_t record_bytes[] = {2, 'a', 'b', 3, 'd', '=', 'e'};
|
| base::scoped_nsobject<TestNSNetService> test_service([[TestNSNetService alloc]
|
| - initWithData:[[NSData alloc] initWithBytes:record_bytes
|
| - length:arraysize(record_bytes)]]);
|
| + initWithData:[NSData dataWithBytes:record_bytes
|
| + length:arraysize(record_bytes)]]);
|
|
|
| const std::string kIp = "2001:4860:4860::8844";
|
| const uint16_t kPort = 4321;
|
| @@ -149,10 +151,101 @@ TEST_F(ServiceDiscoveryClientMacTest, ServiceResolver) {
|
| base::RunLoop().RunUntilIdle();
|
|
|
| EXPECT_EQ(1, num_resolves_);
|
| - EXPECT_EQ(2u, last_service_description_.metadata.size());
|
| +
|
| + const std::vector<std::string>& metadata =
|
| + last_service_description_.metadata;
|
| + EXPECT_EQ(2u, metadata.size());
|
| + EXPECT_NE(metadata.end(),
|
| + std::find(metadata.begin(), metadata.end(), "ab"));
|
| + EXPECT_NE(metadata.end(),
|
| + std::find(metadata.begin(), metadata.end(), "d=e"));
|
| +
|
| + EXPECT_EQ(ip_address, last_service_description_.ip_address);
|
| + EXPECT_EQ(kPort, last_service_description_.address.port());
|
| + EXPECT_EQ(kIp, last_service_description_.address.host());
|
| +}
|
| +
|
| +// https://crbug.com/586628
|
| +TEST_F(ServiceDiscoveryClientMacTest, ResolveInvalidUnicodeRecord) {
|
| + const std::string test_service_name = "Test.123._testing._tcp.local";
|
| + std::unique_ptr<ServiceResolver> resolver = client()->CreateServiceResolver(
|
| + test_service_name,
|
| + base::Bind(&ServiceDiscoveryClientMacTest::OnResolveComplete,
|
| + base::Unretained(this)));
|
| +
|
| + const uint8_t record_bytes[] = {
|
| + 3, 'a', '=', 'b',
|
| + // The bytes after name= are the UTF-8 encoded representation of
|
| + // U+1F4A9, with the first two bytes of the code unit sequence transposed.
|
| + 9, 'n', 'a', 'm', 'e', '=', 0x9F, 0xF0, 0x92, 0xA9,
|
| + 5, 'c', 'd', '=', 'e', '9',
|
| + };
|
| + base::scoped_nsobject<TestNSNetService> test_service([[TestNSNetService alloc]
|
| + initWithData:[NSData dataWithBytes:record_bytes
|
| + length:arraysize(record_bytes)]]);
|
| +
|
| + const std::string kIp = "2001:4860:4860::8844";
|
| + const uint16_t kPort = 4321;
|
| + net::IPAddress ip_address;
|
| + ASSERT_TRUE(ip_address.AssignFromIPLiteral(kIp));
|
| + net::IPEndPoint endpoint(ip_address, kPort);
|
| + net::SockaddrStorage storage;
|
| + ASSERT_TRUE(endpoint.ToSockAddr(storage.addr, &storage.addr_len));
|
| + NSData* discovery_host =
|
| + [NSData dataWithBytes:storage.addr length:storage.addr_len];
|
| + NSArray* addresses = @[ discovery_host ];
|
| + [test_service setAddresses:addresses];
|
| +
|
| + ServiceResolverImplMac* resolver_impl =
|
| + static_cast<ServiceResolverImplMac*>(resolver.get());
|
| + resolver_impl->GetContainerForTesting()->SetServiceForTesting(
|
| + base::scoped_nsobject<NSNetService>(test_service));
|
| + resolver->StartResolving();
|
| +
|
| + resolver_impl->GetContainerForTesting()->OnResolveUpdate(
|
| + ServiceResolver::STATUS_SUCCESS);
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_EQ(1, num_resolves_);
|
| +
|
| + const std::vector<std::string>& metadata =
|
| + last_service_description_.metadata;
|
| + EXPECT_EQ(2u, metadata.size());
|
| + EXPECT_NE(metadata.end(),
|
| + std::find(metadata.begin(), metadata.end(), "a=b"));
|
| + EXPECT_NE(metadata.end(),
|
| + std::find(metadata.begin(), metadata.end(), "cd=e9"));
|
| +
|
| EXPECT_EQ(ip_address, last_service_description_.ip_address);
|
| EXPECT_EQ(kPort, last_service_description_.address.port());
|
| EXPECT_EQ(kIp, last_service_description_.address.host());
|
| }
|
|
|
| +TEST_F(ServiceDiscoveryClientMacTest, ResolveInvalidServiceName) {
|
| + base::RunLoop run_loop;
|
| +
|
| + // This is the same invalid U+1F4A9 code unit sequence as in
|
| + // ResolveInvalidUnicodeRecord.
|
| + const std::string test_service_name =
|
| + "Test\x9F\xF0\x92\xA9.123._testing._tcp.local";
|
| + std::unique_ptr<ServiceResolver> resolver = client()->CreateServiceResolver(
|
| + test_service_name,
|
| + base::Bind(
|
| + [](ServiceDiscoveryClientMacTest* test,
|
| + base::Closure quit_closure,
|
| + ServiceResolver::RequestStatus status,
|
| + const ServiceDescription& service_description) {
|
| + test->OnResolveComplete(status, service_description);
|
| + quit_closure.Run();
|
| + },
|
| + base::Unretained(this), run_loop.QuitClosure()));
|
| + resolver->StartResolving();
|
| +
|
| + run_loop.Run();
|
| +
|
| + EXPECT_EQ(1, num_resolves_);
|
| + EXPECT_EQ(ServiceResolver::STATUS_KNOWN_NONEXISTENT, last_status_);
|
| +}
|
| +
|
| } // namespace local_discovery
|
|
|