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 "base/macros.h"
8 #include "base/run_loop.h"
9 #include "chrome/test/base/browser_with_test_window_test.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/site_instance.h"
13
14 class ProfileDestroyerTest : public BrowserWithTestWindowTest {
15 public:
16 ProfileDestroyerTest() = default;
17
SetUp()18 void SetUp() override {
19 BrowserWithTestWindowTest::SetUp();
20 GetOriginalProfile()->SetProfileDestructionObserver(
21 base::BindOnce(&ProfileDestroyerTest::SetOriginalProfileDestroyed,
22 base::Unretained(this)));
23 }
24
GetOriginalProfile()25 TestingProfile* GetOriginalProfile() { return GetProfile(); }
26
GetIncognitoProfile()27 TestingProfile* GetIncognitoProfile() {
28 if (!incognito_profile_) {
29 TestingProfile::Builder builder;
30 incognito_profile_ = builder.BuildIncognito(GetOriginalProfile());
31 incognito_profile_->SetProfileDestructionObserver(
32 base::BindOnce(&ProfileDestroyerTest::SetIncognitoProfileDestroyed,
33 base::Unretained(this)));
34 }
35 return incognito_profile_;
36 }
37
SetOriginalProfileDestroyed()38 void SetOriginalProfileDestroyed() { original_profile_destroyed_ = true; }
SetIncognitoProfileDestroyed()39 void SetIncognitoProfileDestroyed() { incognito_profile_destroyed_ = true; }
40
IsOriginalProfileDestroyed()41 bool IsOriginalProfileDestroyed() { return original_profile_destroyed_; }
IsIncognitoProfileDestroyed()42 bool IsIncognitoProfileDestroyed() { return incognito_profile_destroyed_; }
43
44 // Creates a render process host based on a new site instance given the
45 // |profile| and mark it as used.
CreatedRendererProcessHost(Profile * profile)46 std::unique_ptr<content::RenderProcessHost> CreatedRendererProcessHost(
47 Profile* profile) {
48 site_instances_.emplace_back(content::SiteInstance::Create(profile));
49
50 std::unique_ptr<content::RenderProcessHost> render_process_host;
51 render_process_host.reset(site_instances_.back()->GetProcess());
52 render_process_host->SetIsUsed();
53 EXPECT_NE(render_process_host.get(), nullptr);
54
55 return render_process_host;
56 }
57
58 protected:
59 bool original_profile_destroyed_{false};
60 bool incognito_profile_destroyed_{false};
61 TestingProfile* incognito_profile_{nullptr};
62
63 std::vector<scoped_refptr<content::SiteInstance>> site_instances_;
64
65 DISALLOW_COPY_AND_ASSIGN(ProfileDestroyerTest);
66 };
67
68 // Expect immediate incognito profile destruction when no pending renderer
69 // process host exists.
TEST_F(ProfileDestroyerTest,ImmediateIncognitoProfileDestruction)70 TEST_F(ProfileDestroyerTest, ImmediateIncognitoProfileDestruction) {
71 TestingProfile* incognito_profile = GetIncognitoProfile();
72
73 // Destroying the regular browser does not result in destruction of regular
74 // profile and hence should not destroy the incognito profile.
75 set_browser(nullptr);
76 EXPECT_FALSE(IsOriginalProfileDestroyed());
77 EXPECT_FALSE(IsIncognitoProfileDestroyed());
78
79 // Ask for destruction of Incognito profile, and expect immediate destruction.
80 ProfileDestroyer::DestroyProfileWhenAppropriate(incognito_profile);
81 EXPECT_TRUE(IsIncognitoProfileDestroyed());
82 }
83
84 // Expect pending renderer process hosts delay incognito profile destruction.
TEST_F(ProfileDestroyerTest,DelayedIncognitoProfileDestruction)85 TEST_F(ProfileDestroyerTest, DelayedIncognitoProfileDestruction) {
86 TestingProfile* incognito_profile = GetIncognitoProfile();
87
88 // Create two render process hosts.
89 std::unique_ptr<content::RenderProcessHost> render_process_host1 =
90 CreatedRendererProcessHost(incognito_profile);
91 std::unique_ptr<content::RenderProcessHost> render_process_host2 =
92 CreatedRendererProcessHost(incognito_profile);
93
94 // Ask for destruction of Incognito profile, but expect it to be delayed.
95 ProfileDestroyer::DestroyProfileWhenAppropriate(incognito_profile);
96 EXPECT_FALSE(IsIncognitoProfileDestroyed());
97
98 // Destroy the first pending render process host, and expect it not to destroy
99 // the incognito profile.
100 render_process_host1.release()->Cleanup();
101 base::RunLoop().RunUntilIdle();
102 EXPECT_FALSE(IsIncognitoProfileDestroyed());
103
104 // Destroy the other renderer process, and expect destruction of incognito
105 // profile.
106 render_process_host2.release()->Cleanup();
107 base::RunLoop().RunUntilIdle();
108 EXPECT_TRUE(IsIncognitoProfileDestroyed());
109 }
110
111 // TODO(https://crbug.com/1033903): Add tests for non-primary OTRs.
112