blob: 3c97302be70e48cc9a571c85576dc89a0d0c0cda [file] [log] [blame]
// Copyright (c) 2012 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 "base/memory/scoped_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/extensions/api/dns/dns_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/host_resolver.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
using content::BrowserThread;
using extension_function_test_utils::CreateEmptyExtension;
using extension_function_test_utils::RunFunctionAndReturnResult;
namespace {
class DnsApiTest : public PlatformAppApiTest {
public:
static const std::string kHostname;
static const std::string kAddress;
DnsApiTest() : resolver_event_(true, false),
mock_host_resolver_(NULL) {
}
virtual void SetUpOnMainThread() OVERRIDE {
CreateMockHostResolverOnIOThread();
extensions::DnsResolveFunction::set_host_resolver_for_testing(
get_mock_host_resolver());
}
virtual void CleanUpOnMainThread() OVERRIDE {
if (mock_host_resolver_) {
extensions::DnsResolveFunction::set_host_resolver_for_testing(NULL);
DeleteMockHostResolverOnIOThread();
}
}
void CreateMockHostResolverOnIOThread() {
bool result = BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&DnsApiTest::FinishMockHostResolverCreation, this));
DCHECK(result);
base::TimeDelta max_time = base::TimeDelta::FromSeconds(5);
ASSERT_TRUE(resolver_event_.TimedWait(max_time));
}
void FinishMockHostResolverCreation() {
mock_host_resolver_ = new net::MockHostResolver();
get_mock_host_resolver()->rules()->AddRule(kHostname, kAddress);
get_mock_host_resolver()->rules()->AddSimulatedFailure(
"this.hostname.is.bogus");
resolver_event_.Signal();
}
void DeleteMockHostResolverOnIOThread() {
if (!mock_host_resolver_)
return;
resolver_event_.Reset();
bool result = BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&DnsApiTest::FinishMockHostResolverDeletion, this));
DCHECK(result);
base::TimeDelta max_time = base::TimeDelta::FromSeconds(5);
ASSERT_TRUE(resolver_event_.TimedWait(max_time));
}
void FinishMockHostResolverDeletion() {
delete(mock_host_resolver_);
resolver_event_.Signal();
}
net::MockHostResolver* get_mock_host_resolver() {
return mock_host_resolver_;
}
private:
base::WaitableEvent resolver_event_;
// The MockHostResolver asserts that it's used on the same thread on which
// it's created, which is actually a stronger rule than its real counterpart.
// But that's fine; it's good practice.
//
// Plain pointer because we have to manage lifetime manually.
net::MockHostResolver* mock_host_resolver_;
};
const std::string DnsApiTest::kHostname = "www.sowbug.org";
const std::string DnsApiTest::kAddress = "9.8.7.6";
} // namespace
IN_PROC_BROWSER_TEST_F(DnsApiTest, VerifyPermissions) {
VerifyPermissions(test_data_dir_.AppendASCII("dns/api"));
}
IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsResolveIPLiteral) {
scoped_refptr<extensions::DnsResolveFunction> resolve_function(
new extensions::DnsResolveFunction());
scoped_refptr<Extension> empty_extension(CreateEmptyExtension());
resolve_function->set_extension(empty_extension.get());
resolve_function->set_has_callback(true);
scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
resolve_function, "[\"127.0.0.1\"]", browser()));
ASSERT_EQ(base::Value::TYPE_DICTIONARY, result->GetType());
DictionaryValue *value = static_cast<DictionaryValue*>(result.get());
int resultCode;
EXPECT_TRUE(value->GetInteger("resultCode", &resultCode));
EXPECT_EQ(net::OK, resultCode);
std::string address;
EXPECT_TRUE(value->GetString("address", &address));
EXPECT_EQ("127.0.0.1", address);
}
IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsResolveHostname) {
scoped_refptr<extensions::DnsResolveFunction> resolve_function(
new extensions::DnsResolveFunction());
scoped_refptr<Extension> empty_extension(CreateEmptyExtension());
resolve_function->set_extension(empty_extension.get());
resolve_function->set_has_callback(true);
std::string function_arguments("[\"");
function_arguments += DnsApiTest::kHostname;
function_arguments += "\"]";
scoped_ptr<base::Value> result(
RunFunctionAndReturnResult(resolve_function.get(),
function_arguments, browser()));
ASSERT_EQ(base::Value::TYPE_DICTIONARY, result->GetType());
DictionaryValue *value = static_cast<DictionaryValue*>(result.get());
int resultCode;
EXPECT_TRUE(value->GetInteger("resultCode", &resultCode));
EXPECT_EQ(net::OK, resultCode);
std::string address;
EXPECT_TRUE(value->GetString("address", &address));
EXPECT_EQ(DnsApiTest::kAddress, address);
}
IN_PROC_BROWSER_TEST_F(DnsApiTest, DnsExtension) {
ASSERT_TRUE(RunExtensionTest("dns/api")) << message_;
}