This source file includes following definitions.
- GetURLRequestContext
- GetNetworkTaskRunner
- core_
- SetUp
- TearDown
- RunUntilIdle
- Connect
- LoadStore
- InitializeRegistry
- PopulateCache
- CreateResponse
- CreateSerializedResponse
- CreateTestSchema
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "components/policy/core/common/cloud/component_cloud_policy_service.h"
#include <map>
#include <string>
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
#include "components/policy/core/common/cloud/policy_builder.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_types.h"
#include "components/policy/core/common/schema.h"
#include "components/policy/core/common/schema_map.h"
#include "crypto/sha2.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "policy/proto/chrome_extension_policy.pb.h"
#include "policy/proto/device_management_backend.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace em = enterprise_management;
using testing::Mock;
namespace policy {
namespace {
const char kTestExtension[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const char kTestExtension2[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const char kTestDownload[] = "http://example.com/getpolicy?id=123";
const char kTestPolicy[] =
"{"
" \"Name\": {"
" \"Value\": \"disabled\""
" },"
" \"Second\": {"
" \"Value\": \"maybe\","
" \"Level\": \"Recommended\""
" }"
"}";
const char kInvalidTestPolicy[] =
"{"
" \"Name\": {"
" \"Value\": \"published\""
" },"
" \"Undeclared Name\": {"
" \"Value\": \"not published\""
" }"
"}";
const char kTestSchema[] =
"{"
" \"type\": \"object\","
" \"properties\": {"
" \"Name\": { \"type\": \"string\" },"
" \"Second\": { \"type\": \"string\" }"
" }"
"}";
class MockComponentCloudPolicyDelegate
: public ComponentCloudPolicyService::Delegate {
public:
virtual ~MockComponentCloudPolicyDelegate() {}
MOCK_METHOD0(OnComponentCloudPolicyUpdated, void());
};
class TestURLRequestContextGetter : public net::URLRequestContextGetter {
public:
explicit TestURLRequestContextGetter(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(task_runner) {}
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
return NULL;
}
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const OVERRIDE {
return task_runner_;
}
private:
virtual ~TestURLRequestContextGetter() {}
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
}
class ComponentCloudPolicyServiceTest : public testing::Test {
protected:
ComponentCloudPolicyServiceTest()
: client_(NULL),
core_(PolicyNamespaceKey(GetChromeUserPolicyType(), ""),
&store_,
loop_.message_loop_proxy()) {}
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
cache_ = new ResourceCache(temp_dir_.path(), loop_.message_loop_proxy());
request_context_ =
new TestURLRequestContextGetter(loop_.message_loop_proxy());
service_.reset(new ComponentCloudPolicyService(
&delegate_,
®istry_,
&core_,
make_scoped_ptr(cache_),
request_context_,
loop_.message_loop_proxy(),
loop_.message_loop_proxy()));
builder_.policy_data().set_policy_type(
dm_protocol::kChromeExtensionPolicyType);
builder_.policy_data().set_settings_entity_id(kTestExtension);
builder_.payload().set_download_url(kTestDownload);
builder_.payload().set_secure_hash(crypto::SHA256HashString(kTestPolicy));
expected_policy_.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
base::Value::CreateStringValue("disabled"), NULL);
expected_policy_.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
base::Value::CreateStringValue("maybe"), NULL);
}
virtual void TearDown() OVERRIDE {
service_.reset();
RunUntilIdle();
}
void RunUntilIdle() {
base::RunLoop().RunUntilIdle();
}
void Connect(size_t expected_namespaces_in_client) {
client_ = new MockCloudPolicyClient();
client_->SetDMToken(ComponentPolicyBuilder::kFakeToken);
EXPECT_EQ(0u, client_->namespaces_to_fetch_.size());
core_.Connect(scoped_ptr<CloudPolicyClient>(client_));
EXPECT_EQ(expected_namespaces_in_client,
client_->namespaces_to_fetch_.size());
if (!store_.has_policy())
EXPECT_CALL(*client_, FetchPolicy());
core_.StartRefreshScheduler();
RunUntilIdle();
Mock::VerifyAndClearExpectations(client_);
}
void LoadStore() {
EXPECT_FALSE(store_.is_initialized());
em::PolicyData* data = new em::PolicyData();
data->set_username(ComponentPolicyBuilder::kFakeUsername);
data->set_request_token(ComponentPolicyBuilder::kFakeToken);
store_.policy_.reset(data);
store_.NotifyStoreLoaded();
RunUntilIdle();
EXPECT_TRUE(store_.is_initialized());
}
void InitializeRegistry() {
registry_.RegisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
CreateTestSchema());
registry_.SetReady(POLICY_DOMAIN_CHROME);
registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
}
void PopulateCache() {
EXPECT_TRUE(cache_->Store(
"extension-policy", kTestExtension, CreateSerializedResponse()));
EXPECT_TRUE(
cache_->Store("extension-policy-data", kTestExtension, kTestPolicy));
builder_.policy_data().set_settings_entity_id(kTestExtension2);
EXPECT_TRUE(cache_->Store(
"extension-policy", kTestExtension2, CreateSerializedResponse()));
EXPECT_TRUE(
cache_->Store("extension-policy-data", kTestExtension2, kTestPolicy));
}
scoped_ptr<em::PolicyFetchResponse> CreateResponse() {
builder_.Build();
return make_scoped_ptr(new em::PolicyFetchResponse(builder_.policy()));
}
std::string CreateSerializedResponse() {
builder_.Build();
return builder_.GetBlob();
}
Schema CreateTestSchema() {
std::string error;
Schema schema = Schema::Parse(kTestSchema, &error);
EXPECT_TRUE(schema.valid()) << error;
return schema;
}
base::MessageLoop loop_;
base::ScopedTempDir temp_dir_;
scoped_refptr<TestURLRequestContextGetter> request_context_;
net::TestURLFetcherFactory fetcher_factory_;
MockComponentCloudPolicyDelegate delegate_;
ResourceCache* cache_;
MockCloudPolicyClient* client_;
MockCloudPolicyStore store_;
CloudPolicyCore core_;
SchemaRegistry registry_;
scoped_ptr<ComponentCloudPolicyService> service_;
ComponentPolicyBuilder builder_;
PolicyMap expected_policy_;
};
TEST_F(ComponentCloudPolicyServiceTest, InitializedAtConstructionTime) {
service_.reset();
Connect(1u);
LoadStore();
InitializeRegistry();
cache_ = new ResourceCache(temp_dir_.path(), loop_.message_loop_proxy());
service_.reset(new ComponentCloudPolicyService(&delegate_,
®istry_,
&core_,
make_scoped_ptr(cache_),
request_context_,
loop_.message_loop_proxy(),
loop_.message_loop_proxy()));
EXPECT_FALSE(service_->is_initialized());
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
EXPECT_CALL(*client_, FetchPolicy());
RunUntilIdle();
Mock::VerifyAndClearExpectations(&client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_TRUE(service_->is_initialized());
EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
const PolicyBundle empty_bundle;
EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, InitializeStoreThenRegistry) {
Connect(1u);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(0);
EXPECT_CALL(*client_, FetchPolicy()).Times(0);
LoadStore();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_FALSE(service_->is_initialized());
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
EXPECT_CALL(*client_, FetchPolicy());
InitializeRegistry();
RunUntilIdle();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_TRUE(service_->is_initialized());
const PolicyBundle empty_bundle;
EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, InitializeRegistryThenStore) {
Connect(1u);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated()).Times(0);
EXPECT_CALL(*client_, FetchPolicy()).Times(0);
InitializeRegistry();
RunUntilIdle();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_FALSE(service_->is_initialized());
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
EXPECT_CALL(*client_, FetchPolicy());
LoadStore();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_TRUE(service_->is_initialized());
EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
const PolicyBundle empty_bundle;
EXPECT_TRUE(service_->policy().Equals(empty_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, InitializeWithCachedPolicy) {
PopulateCache();
Connect(1u);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
EXPECT_CALL(*client_, FetchPolicy());
InitializeRegistry();
LoadStore();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_TRUE(service_->is_initialized());
EXPECT_EQ(2u, client_->namespaces_to_fetch_.size());
std::map<std::string, std::string> contents;
cache_->LoadAllSubkeys("extension-policy", &contents);
ASSERT_EQ(1u, contents.size());
EXPECT_EQ(kTestExtension, contents.begin()->first);
PolicyBundle expected_bundle;
const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
expected_bundle.Get(ns).CopyFrom(expected_policy_);
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, FetchPolicy) {
Connect(1u);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
EXPECT_CALL(*client_, FetchPolicy()).Times(0);
registry_.SetReady(POLICY_DOMAIN_CHROME);
registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
LoadStore();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_TRUE(service_->is_initialized());
EXPECT_CALL(*client_, FetchPolicy());
registry_.RegisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
CreateTestSchema());
RunUntilIdle();
Mock::VerifyAndClearExpectations(client_);
client_->SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType,
kTestExtension),
*CreateResponse());
service_->OnPolicyFetched(client_);
RunUntilIdle();
net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
EXPECT_EQ(GURL(kTestDownload), fetcher->GetOriginalURL());
fetcher->set_response_code(200);
fetcher->SetResponseString(kTestPolicy);
fetcher->delegate()->OnURLFetchComplete(fetcher);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
PolicyBundle expected_bundle;
expected_bundle.Get(ns).CopyFrom(expected_policy_);
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, LoadAndPurgeCache) {
Connect(1u);
PopulateCache();
registry_.RegisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension2),
CreateTestSchema());
InitializeRegistry();
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
EXPECT_CALL(*client_, FetchPolicy());
LoadStore();
Mock::VerifyAndClearExpectations(client_);
Mock::VerifyAndClearExpectations(&delegate_);
PolicyBundle expected_bundle;
PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
expected_bundle.Get(ns).CopyFrom(expected_policy_);
ns.component_id = kTestExtension2;
expected_bundle.Get(ns).CopyFrom(expected_policy_);
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
registry_.UnregisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension));
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
ns.component_id = kTestExtension;
expected_bundle.Get(ns).Clear();
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
std::map<std::string, std::string> contents;
cache_->LoadAllSubkeys("extension-policy", &contents);
EXPECT_EQ(1u, contents.size());
EXPECT_TRUE(ContainsKey(contents, kTestExtension2));
}
TEST_F(ComponentCloudPolicyServiceTest, SignInAfterStartup) {
registry_.SetReady(POLICY_DOMAIN_CHROME);
registry_.SetReady(POLICY_DOMAIN_EXTENSIONS);
EXPECT_FALSE(store_.is_initialized());
EXPECT_FALSE(service_->is_initialized());
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
store_.NotifyStoreLoaded();
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
EXPECT_TRUE(service_->is_initialized());
registry_.RegisterComponent(
PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kTestExtension),
CreateTestSchema());
RunUntilIdle();
Connect(2u);
client_->SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeExtensionPolicyType,
kTestExtension),
*CreateResponse());
service_->OnPolicyFetched(client_);
RunUntilIdle();
net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
EXPECT_FALSE(fetcher);
em::PolicyData* data = new em::PolicyData();
data->set_username(ComponentPolicyBuilder::kFakeUsername);
data->set_request_token(ComponentPolicyBuilder::kFakeToken);
store_.policy_.reset(data);
store_.NotifyStoreLoaded();
RunUntilIdle();
fetcher = fetcher_factory_.GetFetcherByID(0);
ASSERT_TRUE(fetcher);
EXPECT_EQ(GURL(kTestDownload), fetcher->GetOriginalURL());
fetcher->set_response_code(200);
fetcher->SetResponseString(kTestPolicy);
fetcher->delegate()->OnURLFetchComplete(fetcher);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
PolicyBundle expected_bundle;
expected_bundle.Get(ns).CopyFrom(expected_policy_);
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
TEST_F(ComponentCloudPolicyServiceTest, SignOut) {
PopulateCache();
LoadStore();
InitializeRegistry();
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
PolicyBundle expected_bundle;
const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
expected_bundle.Get(ns).CopyFrom(expected_policy_);
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
std::map<std::string, std::string> contents;
cache_->LoadAllSubkeys("extension-policy", &contents);
ASSERT_EQ(1u, contents.size());
Connect(2u);
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
core_.Disconnect();
store_.policy_.reset();
store_.NotifyStoreLoaded();
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
const PolicyBundle empty_bundle;
EXPECT_TRUE(service_->policy().Equals(empty_bundle));
cache_->LoadAllSubkeys("extension-policy", &contents);
ASSERT_EQ(0u, contents.size());
}
TEST_F(ComponentCloudPolicyServiceTest, LoadInvalidPolicyFromCache) {
builder_.payload().set_secure_hash(
crypto::SHA256HashString(kInvalidTestPolicy));
EXPECT_TRUE(cache_->Store(
"extension-policy", kTestExtension, CreateSerializedResponse()));
EXPECT_TRUE(cache_->Store(
"extension-policy-data", kTestExtension, kInvalidTestPolicy));
LoadStore();
InitializeRegistry();
EXPECT_CALL(delegate_, OnComponentCloudPolicyUpdated());
RunUntilIdle();
Mock::VerifyAndClearExpectations(&delegate_);
PolicyBundle expected_bundle;
const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension);
expected_bundle.Get(ns).Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
base::Value::CreateStringValue("published"),
NULL);
EXPECT_TRUE(service_->policy().Equals(expected_bundle));
}
}