This source file includes following definitions.
- CreateURLFetcher
- SetUp
- TearDown
- SetUpExternalDataManager
- ConstructMetadata
- SetExternalDataReference
- ConstructFetchCallback
- ResetCallbackData
- OnFetchDone
- FetchAll
- SetFakeResponse
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base.h"
#include <map>
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/test_simple_task_runner.h"
#include "base/values.h"
#include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
#include "components/policy/core/common/cloud/resource_cache.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_test_utils.h"
#include "components/policy/core/common/policy_types.h"
#include "crypto/sha2.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace policy {
namespace {
const char kStringPolicy[] = "StringPolicy";
const char k10BytePolicy[] = "10BytePolicy";
const char k20BytePolicy[] = "20BytePolicy";
const char kUnknownPolicy[] = "UnknownPolicy";
const char k10BytePolicyURL[] = "http://localhost/10_bytes";
const char k20BytePolicyURL[] = "http://localhost/20_bytes";
const char k10ByteData[] = "10 bytes..";
const char k20ByteData[] = "20 bytes............";
const PolicyDetails kPolicyDetails[] = {
{ false, false, 1, 0 },
{ false, false, 2, 10 },
{ false, false, 3, 20 },
};
const char kCacheKey[] = "data";
class FakeURLFetcherFactory : public net::FakeURLFetcherFactory {
public:
FakeURLFetcherFactory();
virtual ~FakeURLFetcherFactory();
virtual net::URLFetcher* CreateURLFetcher(
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
net::URLFetcherDelegate* delegate) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory);
};
FakeURLFetcherFactory::FakeURLFetcherFactory()
: net::FakeURLFetcherFactory(NULL) {
}
FakeURLFetcherFactory::~FakeURLFetcherFactory() {
}
net::URLFetcher* FakeURLFetcherFactory::CreateURLFetcher(
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
net::URLFetcherDelegate* delegate) {
net::URLFetcher* fetcher = net::FakeURLFetcherFactory::CreateURLFetcher(
id, url, request_type, delegate);
EXPECT_TRUE(fetcher);
return fetcher;
}
}
class CloudExternalDataManagerBaseTest : public testing::Test {
protected:
CloudExternalDataManagerBaseTest();
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
void SetUpExternalDataManager();
scoped_ptr<base::DictionaryValue> ConstructMetadata(const std::string& url,
const std::string& hash);
void SetExternalDataReference(const std::string& policy,
scoped_ptr<base::DictionaryValue> metadata);
ExternalDataFetcher::FetchCallback ConstructFetchCallback(int id);
void ResetCallbackData();
void OnFetchDone(int id, scoped_ptr<std::string> data);
void FetchAll();
void SetFakeResponse(const std::string& url,
const std::string& repsonse_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status);
base::MessageLoop message_loop_;
base::ScopedTempDir temp_dir_;
scoped_ptr<ResourceCache> resource_cache_;
MockCloudPolicyStore cloud_policy_store_;
scoped_refptr<net::TestURLRequestContextGetter> request_content_getter_;
FakeURLFetcherFactory fetcher_factory_;
scoped_ptr<CloudExternalDataManagerBase> external_data_manager_;
std::map<int, std::string*> callback_data_;
PolicyDetailsMap policy_details_;
DISALLOW_COPY_AND_ASSIGN(CloudExternalDataManagerBaseTest);
};
CloudExternalDataManagerBaseTest::CloudExternalDataManagerBaseTest() {
}
void CloudExternalDataManagerBaseTest::SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
resource_cache_.reset(new ResourceCache(temp_dir_.path(),
message_loop_.message_loop_proxy()));
SetUpExternalDataManager();
cloud_policy_store_.policy_map_.Set(kStringPolicy,
POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER,
new base::StringValue(std::string()),
NULL);
SetExternalDataReference(
k10BytePolicy,
ConstructMetadata(k10BytePolicyURL,
crypto::SHA256HashString(k10ByteData)));
SetExternalDataReference(
k20BytePolicy,
ConstructMetadata(k20BytePolicyURL,
crypto::SHA256HashString(k20ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
request_content_getter_ = new net::TestURLRequestContextGetter(
base::MessageLoopProxy::current());
policy_details_.SetDetails(kStringPolicy, &kPolicyDetails[0]);
policy_details_.SetDetails(k10BytePolicy, &kPolicyDetails[1]);
policy_details_.SetDetails(k20BytePolicy, &kPolicyDetails[2]);
}
void CloudExternalDataManagerBaseTest::TearDown() {
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
ResetCallbackData();
}
void CloudExternalDataManagerBaseTest::SetUpExternalDataManager() {
external_data_manager_.reset(new CloudExternalDataManagerBase(
policy_details_.GetCallback(),
message_loop_.message_loop_proxy(),
message_loop_.message_loop_proxy()));
external_data_manager_->SetExternalDataStore(make_scoped_ptr(
new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get())));
external_data_manager_->SetPolicyStore(&cloud_policy_store_);
}
scoped_ptr<base::DictionaryValue>
CloudExternalDataManagerBaseTest::ConstructMetadata(
const std::string& url,
const std::string& hash) {
scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue);
metadata->SetStringWithoutPathExpansion("url", url);
metadata->SetStringWithoutPathExpansion("hash", base::HexEncode(hash.c_str(),
hash.size()));
return metadata.Pass();
}
void CloudExternalDataManagerBaseTest::SetExternalDataReference(
const std::string& policy,
scoped_ptr<base::DictionaryValue> metadata) {
cloud_policy_store_.policy_map_.Set(
policy,
POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER,
metadata.release(),
new ExternalDataFetcher(
external_data_manager_->weak_factory_.GetWeakPtr(), policy));
}
ExternalDataFetcher::FetchCallback
CloudExternalDataManagerBaseTest::ConstructFetchCallback(int id) {
return base::Bind(&CloudExternalDataManagerBaseTest::OnFetchDone,
base::Unretained(this),
id);
}
void CloudExternalDataManagerBaseTest::ResetCallbackData() {
STLDeleteValues(&callback_data_);
}
void CloudExternalDataManagerBaseTest::OnFetchDone(
int id,
scoped_ptr<std::string> data) {
delete callback_data_[id];
callback_data_[id] = data.release();
}
void CloudExternalDataManagerBaseTest::FetchAll() {
external_data_manager_->FetchAll();
}
void CloudExternalDataManagerBaseTest::SetFakeResponse(
const std::string& url,
const std::string& response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
fetcher_factory_.SetFakeResponse(
GURL(url), response_data, response_code, status);
}
TEST_F(CloudExternalDataManagerBaseTest, FailToFetchInvalid) {
external_data_manager_->Connect(request_content_getter_);
external_data_manager_->Fetch(kStringPolicy, ConstructFetchCallback(0));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
EXPECT_FALSE(callback_data_[0]);
ResetCallbackData();
external_data_manager_->Fetch(kUnknownPolicy, ConstructFetchCallback(1));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
EXPECT_TRUE(callback_data_.find(1) != callback_data_.end());
EXPECT_FALSE(callback_data_[1]);
ResetCallbackData();
SetExternalDataReference(k10BytePolicy,
ConstructMetadata(std::string(), std::string()));
cloud_policy_store_.NotifyStoreLoaded();
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
EXPECT_TRUE(callback_data_.find(2) != callback_data_.end());
EXPECT_FALSE(callback_data_[2]);
ResetCallbackData();
}
TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCache) {
SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
external_data_manager_->Connect(request_content_getter_);
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[0]);
EXPECT_EQ(k10ByteData, *callback_data_[0]);
ResetCallbackData();
fetcher_factory_.ClearFakeResponses();
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(1));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[1]);
EXPECT_EQ(k10ByteData, *callback_data_[1]);
ResetCallbackData();
external_data_manager_->Disconnect();
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[2]);
EXPECT_EQ(k10ByteData, *callback_data_[2]);
ResetCallbackData();
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
std::string data;
EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()).Load(
k10BytePolicy, crypto::SHA256HashString(k10ByteData), 10, &data));
EXPECT_EQ(k10ByteData, data);
}
TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCacheAll) {
SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
external_data_manager_->Connect(request_content_getter_);
FetchAll();
base::RunLoop().RunUntilIdle();
fetcher_factory_.ClearFakeResponses();
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, callback_data_.size());
ASSERT_TRUE(callback_data_[0]);
EXPECT_EQ(k10ByteData, *callback_data_[0]);
ASSERT_TRUE(callback_data_[1]);
EXPECT_EQ(k20ByteData, *callback_data_[1]);
ResetCallbackData();
external_data_manager_->Disconnect();
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2u, callback_data_.size());
ASSERT_TRUE(callback_data_[2]);
EXPECT_EQ(k10ByteData, *callback_data_[2]);
ASSERT_TRUE(callback_data_[3]);
EXPECT_EQ(k20ByteData, *callback_data_[3]);
ResetCallbackData();
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
CloudExternalDataStore cache(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get());
std::string data;
EXPECT_TRUE(cache.Load(k10BytePolicy,
crypto::SHA256HashString(k10ByteData),
10,
&data));
EXPECT_EQ(k10ByteData, data);
EXPECT_TRUE(cache.Load(k20BytePolicy,
crypto::SHA256HashString(k20ByteData),
20,
&data));
EXPECT_EQ(k20ByteData, data);
}
TEST_F(CloudExternalDataManagerBaseTest, DownloadAfterConnect) {
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_data_.empty());
ResetCallbackData();
SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
external_data_manager_->Connect(request_content_getter_);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[0]);
EXPECT_EQ(k10ByteData, *callback_data_[0]);
ResetCallbackData();
}
TEST_F(CloudExternalDataManagerBaseTest, DownloadError) {
SetFakeResponse(k20BytePolicyURL, std::string(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
external_data_manager_->Connect(request_content_getter_);
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(0));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_data_.empty());
ResetCallbackData();
SetExternalDataReference(
k20BytePolicy,
ConstructMetadata(k20BytePolicyURL,
crypto::SHA256HashString(k10ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_data_.empty());
ResetCallbackData();
SetExternalDataReference(
k20BytePolicy,
ConstructMetadata(k20BytePolicyURL,
crypto::SHA256HashString(k20ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(2));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_data_.empty());
ResetCallbackData();
SetExternalDataReference(
k20BytePolicy,
ConstructMetadata(k20BytePolicyURL,
crypto::SHA256HashString(k10ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(4u, callback_data_.size());
ASSERT_TRUE(callback_data_[0]);
EXPECT_EQ(k10ByteData, *callback_data_[0]);
ASSERT_TRUE(callback_data_[1]);
EXPECT_EQ(k10ByteData, *callback_data_[1]);
ASSERT_TRUE(callback_data_[2]);
EXPECT_EQ(k10ByteData, *callback_data_[2]);
ASSERT_TRUE(callback_data_[3]);
EXPECT_EQ(k10ByteData, *callback_data_[3]);
ResetCallbackData();
}
TEST_F(CloudExternalDataManagerBaseTest, LoadFromCache) {
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()).Store(
k10BytePolicy, crypto::SHA256HashString(k10ByteData), k10ByteData));
SetUpExternalDataManager();
external_data_manager_->Connect(request_content_getter_);
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[0]);
EXPECT_EQ(k10ByteData, *callback_data_[0]);
ResetCallbackData();
}
TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnStartup) {
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
scoped_ptr<CloudExternalDataStore>
cache(new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()));
EXPECT_TRUE(cache->Store(k10BytePolicy,
crypto::SHA256HashString(k10ByteData),
k10ByteData));
EXPECT_TRUE(cache->Store(k20BytePolicy,
crypto::SHA256HashString(k10ByteData),
k10ByteData));
EXPECT_TRUE(cache->Store(kUnknownPolicy,
crypto::SHA256HashString(k10ByteData),
k10ByteData));
cache.reset();
SetUpExternalDataManager();
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
cache.reset(new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()));
std::string data;
EXPECT_TRUE(cache->Load(k10BytePolicy,
crypto::SHA256HashString(k10ByteData),
10,
&data));
EXPECT_EQ(k10ByteData, data);
EXPECT_FALSE(cache->Load(k20BytePolicy,
crypto::SHA256HashString(k10ByteData),
20,
&data));
EXPECT_FALSE(cache->Load(kUnknownPolicy,
crypto::SHA256HashString(k10ByteData),
20,
&data));
}
TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnChange) {
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
scoped_ptr<CloudExternalDataStore>
cache(new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()));
EXPECT_TRUE(cache->Store(k20BytePolicy,
crypto::SHA256HashString(k20ByteData),
k20ByteData));
cache.reset();
SetUpExternalDataManager();
external_data_manager_->Connect(request_content_getter_);
SetExternalDataReference(
k20BytePolicy,
ConstructMetadata(k20BytePolicyURL,
crypto::SHA256HashString(k10ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
cache.reset(new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()));
std::string data;
EXPECT_FALSE(cache->Load(k20BytePolicy,
crypto::SHA256HashString(k20ByteData),
20,
&data));
}
TEST_F(CloudExternalDataManagerBaseTest, CacheCorruption) {
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
scoped_ptr<CloudExternalDataStore>
cache(new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()));
EXPECT_TRUE(cache->Store(k10BytePolicy,
crypto::SHA256HashString(k20ByteData),
k20ByteData));
EXPECT_TRUE(cache->Store(k20BytePolicy,
crypto::SHA256HashString(k20ByteData),
k10ByteData));
cache.reset();
SetUpExternalDataManager();
SetFakeResponse(k10BytePolicyURL, k20ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
external_data_manager_->Connect(request_content_getter_);
SetExternalDataReference(
k10BytePolicy,
ConstructMetadata(k10BytePolicyURL,
crypto::SHA256HashString(k20ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_data_.empty());
ResetCallbackData();
SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[1]);
EXPECT_EQ(k20ByteData, *callback_data_[1]);
ResetCallbackData();
external_data_manager_.reset();
base::RunLoop().RunUntilIdle();
cache.reset(new CloudExternalDataStore(kCacheKey,
message_loop_.message_loop_proxy(),
resource_cache_.get()));
std::string data;
EXPECT_FALSE(cache->Load(k10BytePolicy,
crypto::SHA256HashString(k20ByteData),
20,
&data));
EXPECT_TRUE(cache->Load(k20BytePolicy,
crypto::SHA256HashString(k20ByteData),
20,
&data));
EXPECT_EQ(k20ByteData, data);
}
TEST_F(CloudExternalDataManagerBaseTest, PolicyChangeWhileDownloadPending) {
SetFakeResponse(k10BytePolicyURL, std::string(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
SetFakeResponse(k20BytePolicyURL, std::string(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
external_data_manager_->Connect(request_content_getter_);
external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(callback_data_.empty());
ResetCallbackData();
cloud_policy_store_.policy_map_.Erase(k10BytePolicy);
cloud_policy_store_.NotifyStoreLoaded();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
EXPECT_FALSE(callback_data_[0]);
ResetCallbackData();
fetcher_factory_.ClearFakeResponses();
SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
SetExternalDataReference(
k20BytePolicy,
ConstructMetadata(k20BytePolicyURL,
crypto::SHA256HashString(k10ByteData)));
cloud_policy_store_.NotifyStoreLoaded();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, callback_data_.size());
ASSERT_TRUE(callback_data_[1]);
EXPECT_EQ(k10ByteData, *callback_data_[1]);
ResetCallbackData();
}
}