Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / profiles / profile_destroyer_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/profiles/profile_destroyer.h"
6
7 #include "chrome/test/base/browser_with_test_window_test.h"
8 #include "chrome/test/base/testing_profile.h"
9 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/site_instance.h"
11
12 class TestingOffTheRecordDestructionProfile : public TestingProfile {
13  public:
14   TestingOffTheRecordDestructionProfile()
15       : TestingProfile(base::FilePath(),
16                        NULL,
17                        scoped_refptr<ExtensionSpecialStoragePolicy>()
18                        scoped_ptr<PrefServiceSyncable>(),
19                        true,
20                        TestingFactories()),
21         destroyed_otr_profile_(false) {
22     set_incognito(true);
23   }
24   virtual void DestroyOffTheRecordProfile() override {
25     destroyed_otr_profile_ = true;
26   }
27   bool destroyed_otr_profile_;
28
29   DISALLOW_COPY_AND_ASSIGN(TestingOffTheRecordDestructionProfile);
30 };
31
32 class TestingOriginalDestructionProfile : public TestingProfile {
33  public:
34   TestingOriginalDestructionProfile() : destroyed_otr_profile_(false) {
35     DCHECK_EQ(kNull, living_instance_);
36     living_instance_ = this;
37   }
38   virtual ~TestingOriginalDestructionProfile() {
39     DCHECK_EQ(this, living_instance_);
40     living_instance_ = NULL;
41   }
42   virtual void DestroyOffTheRecordProfile() override {
43     SetOffTheRecordProfile(NULL);
44     destroyed_otr_profile_ = true;
45   }
46   bool destroyed_otr_profile_;
47   static TestingOriginalDestructionProfile* living_instance_;
48
49   // This is to avoid type casting in DCHECK_EQ & EXPECT_NE.
50   static const TestingOriginalDestructionProfile* kNull;
51
52   DISALLOW_COPY_AND_ASSIGN(TestingOriginalDestructionProfile);
53 };
54 const TestingOriginalDestructionProfile*
55     TestingOriginalDestructionProfile::kNull = NULL;
56
57 TestingOriginalDestructionProfile*
58     TestingOriginalDestructionProfile::living_instance_ = NULL;
59
60 class ProfileDestroyerTest : public BrowserWithTestWindowTest {
61  public:
62   ProfileDestroyerTest() : off_the_record_profile_(NULL) {}
63
64  protected:
65   virtual TestingProfile* CreateProfile() override {
66     if (off_the_record_profile_ == NULL)
67       off_the_record_profile_ = new TestingOffTheRecordDestructionProfile();
68     return off_the_record_profile_;
69   }
70   TestingOffTheRecordDestructionProfile* off_the_record_profile_;
71
72   DISALLOW_COPY_AND_ASSIGN(ProfileDestroyerTest);
73 };
74
75 TEST_F(ProfileDestroyerTest, DelayProfileDestruction) {
76   scoped_refptr<content::SiteInstance> instance1(
77       content::SiteInstance::Create(off_the_record_profile_));
78   scoped_ptr<content::RenderProcessHost> render_process_host1;
79   render_process_host1.reset(instance1->GetProcess());
80   ASSERT_TRUE(render_process_host1.get() != NULL);
81
82   scoped_refptr<content::SiteInstance> instance2(
83       content::SiteInstance::Create(off_the_record_profile_));
84   scoped_ptr<content::RenderProcessHost> render_process_host2;
85   render_process_host2.reset(instance2->GetProcess());
86   ASSERT_TRUE(render_process_host2.get() != NULL);
87
88   // destroying the browser should not destroy the off the record profile...
89   set_browser(NULL);
90   EXPECT_FALSE(off_the_record_profile_->destroyed_otr_profile_);
91
92   // until we destroy the render process host holding on to it...
93   render_process_host1.release()->Cleanup();
94
95   // And asynchronicity kicked in properly.
96   base::MessageLoop::current()->RunUntilIdle();
97   EXPECT_FALSE(off_the_record_profile_->destroyed_otr_profile_);
98
99   // I meant, ALL the render process hosts... :-)
100   render_process_host2.release()->Cleanup();
101   base::MessageLoop::current()->RunUntilIdle();
102   EXPECT_TRUE(off_the_record_profile_->destroyed_otr_profile_);
103 }
104
105 TEST_F(ProfileDestroyerTest, DelayOriginalProfileDestruction) {
106   TestingOriginalDestructionProfile* original_profile =
107       new TestingOriginalDestructionProfile;
108
109   TestingOffTheRecordDestructionProfile* off_the_record_profile =
110       new TestingOffTheRecordDestructionProfile;
111
112   original_profile->SetOffTheRecordProfile(off_the_record_profile);
113
114   scoped_refptr<content::SiteInstance> instance1(
115       content::SiteInstance::Create(off_the_record_profile));
116   scoped_ptr<content::RenderProcessHost> render_process_host1;
117   render_process_host1.reset(instance1->GetProcess());
118   ASSERT_TRUE(render_process_host1.get() != NULL);
119
120   // Trying to destroy the original profile should be delayed until associated
121   // off the record profile is released by all render process hosts.
122   ProfileDestroyer::DestroyProfileWhenAppropriate(original_profile);
123   EXPECT_NE(TestingOriginalDestructionProfile::kNull,
124             TestingOriginalDestructionProfile::living_instance_);
125   EXPECT_FALSE(original_profile->destroyed_otr_profile_);
126
127   render_process_host1.release()->Cleanup();
128   base::MessageLoop::current()->RunUntilIdle();
129   EXPECT_EQ(NULL, TestingOriginalDestructionProfile::living_instance_);
130
131   // And the same protection should apply to the main profile.
132   TestingOriginalDestructionProfile* main_profile =
133       new TestingOriginalDestructionProfile;
134   scoped_refptr<content::SiteInstance> instance2(
135       content::SiteInstance::Create(main_profile));
136   scoped_ptr<content::RenderProcessHost> render_process_host2;
137   render_process_host2.reset(instance2->GetProcess());
138   ASSERT_TRUE(render_process_host2.get() != NULL);
139
140   ProfileDestroyer::DestroyProfileWhenAppropriate(main_profile);
141   EXPECT_EQ(main_profile, TestingOriginalDestructionProfile::living_instance_);
142   render_process_host2.release()->Cleanup();
143   base::MessageLoop::current()->RunUntilIdle();
144   EXPECT_EQ(NULL, TestingOriginalDestructionProfile::living_instance_);
145 }