1 // Copyright (c) 2011 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 "testing/gtest/include/gtest/gtest.h"
6
7 #include "chrome/browser/profiles/profile_dependency_manager.h"
8 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
9
10 class ProfileDependencyManagerUnittests : public ::testing::Test {
11 protected:
~ProfileDependencyManagerUnittests()12 virtual ~ProfileDependencyManagerUnittests() {
13 EXPECT_TRUE(dependency_manager_.all_components_.empty());
14 EXPECT_TRUE(dependency_manager_.edges_.empty());
15 EXPECT_TRUE(dependency_manager_.destruction_order_.empty());
16 }
17
18 // To get around class access:
DependOn(ProfileKeyedServiceFactory * child,ProfileKeyedServiceFactory * parent)19 void DependOn(ProfileKeyedServiceFactory* child,
20 ProfileKeyedServiceFactory* parent) {
21 child->DependsOn(parent);
22 }
23
manager()24 ProfileDependencyManager* manager() { return &dependency_manager_; }
25
shutdown_order()26 std::vector<std::string>* shutdown_order() { return &shutdown_order_; }
27
28 private:
29 ProfileDependencyManager dependency_manager_;
30
31 std::vector<std::string> shutdown_order_;
32 };
33
34 class TestService : public ProfileKeyedServiceFactory {
35 public:
TestService(const std::string & name,std::vector<std::string> * fill_on_shutdown,ProfileDependencyManager * manager)36 TestService(const std::string& name,
37 std::vector<std::string>* fill_on_shutdown,
38 ProfileDependencyManager* manager)
39 : ProfileKeyedServiceFactory(manager),
40 name_(name),
41 fill_on_shutdown_(fill_on_shutdown) {
42 }
43
BuildServiceInstanceFor(Profile * profile) const44 virtual ProfileKeyedService* BuildServiceInstanceFor(
45 Profile* profile) const {
46 ADD_FAILURE() << "This isn't part of the tests!";
47 return NULL;
48 }
49
ProfileShutdown(Profile * profile)50 virtual void ProfileShutdown(Profile* profile) {
51 fill_on_shutdown_->push_back(name_);
52 }
53
54 private:
55 const std::string name_;
56 std::vector<std::string>* fill_on_shutdown_;
57 };
58
59 // Tests that we can deal with a single component.
TEST_F(ProfileDependencyManagerUnittests,SingleCase)60 TEST_F(ProfileDependencyManagerUnittests, SingleCase) {
61 TestService service("service", shutdown_order(), manager());
62
63 manager()->DestroyProfileServices(NULL);
64
65 ASSERT_EQ(1U, shutdown_order()->size());
66 EXPECT_STREQ("service", (*shutdown_order())[0].c_str());
67 }
68
69 // Tests that we get a simple one component depends on the other case.
TEST_F(ProfileDependencyManagerUnittests,SimpleDependency)70 TEST_F(ProfileDependencyManagerUnittests, SimpleDependency) {
71 TestService parent("parent", shutdown_order(), manager());
72 TestService child("child", shutdown_order(), manager());
73 DependOn(&child, &parent);
74
75 manager()->DestroyProfileServices(NULL);
76
77 ASSERT_EQ(2U, shutdown_order()->size());
78 EXPECT_STREQ("child", (*shutdown_order())[0].c_str());
79 EXPECT_STREQ("parent", (*shutdown_order())[1].c_str());
80 }
81
82 // Tests two children, one parent
TEST_F(ProfileDependencyManagerUnittests,TwoChildrenOneParent)83 TEST_F(ProfileDependencyManagerUnittests, TwoChildrenOneParent) {
84 TestService parent("parent", shutdown_order(), manager());
85 TestService child1("child1", shutdown_order(), manager());
86 TestService child2("child2", shutdown_order(), manager());
87 DependOn(&child1, &parent);
88 DependOn(&child2, &parent);
89
90 manager()->DestroyProfileServices(NULL);
91
92 ASSERT_EQ(3U, shutdown_order()->size());
93 EXPECT_STREQ("child2", (*shutdown_order())[0].c_str());
94 EXPECT_STREQ("child1", (*shutdown_order())[1].c_str());
95 EXPECT_STREQ("parent", (*shutdown_order())[2].c_str());
96 }
97
98 // Tests an M configuration
TEST_F(ProfileDependencyManagerUnittests,MConfiguration)99 TEST_F(ProfileDependencyManagerUnittests, MConfiguration) {
100 TestService parent1("parent1", shutdown_order(), manager());
101 TestService parent2("parent2", shutdown_order(), manager());
102
103 TestService child_of_1("child_of_1", shutdown_order(), manager());
104 DependOn(&child_of_1, &parent1);
105
106 TestService child_of_12("child_of_12", shutdown_order(), manager());
107 DependOn(&child_of_12, &parent1);
108 DependOn(&child_of_12, &parent2);
109
110 TestService child_of_2("child_of_2", shutdown_order(), manager());
111 DependOn(&child_of_2, &parent2);
112
113 manager()->DestroyProfileServices(NULL);
114
115 ASSERT_EQ(5U, shutdown_order()->size());
116 EXPECT_STREQ("child_of_2", (*shutdown_order())[0].c_str());
117 EXPECT_STREQ("child_of_12", (*shutdown_order())[1].c_str());
118 EXPECT_STREQ("child_of_1", (*shutdown_order())[2].c_str());
119 EXPECT_STREQ("parent2", (*shutdown_order())[3].c_str());
120 EXPECT_STREQ("parent1", (*shutdown_order())[4].c_str());
121 }
122
123 // Tests that it can deal with a simple diamond.
TEST_F(ProfileDependencyManagerUnittests,DiamondConfiguration)124 TEST_F(ProfileDependencyManagerUnittests, DiamondConfiguration) {
125 TestService parent("parent", shutdown_order(), manager());
126
127 TestService middle_row_1("middle_row_1", shutdown_order(), manager());
128 DependOn(&middle_row_1, &parent);
129
130 TestService middle_row_2("middle_row_2", shutdown_order(), manager());
131 DependOn(&middle_row_2, &parent);
132
133 TestService bottom("bottom", shutdown_order(), manager());
134 DependOn(&bottom, &middle_row_1);
135 DependOn(&bottom, &middle_row_2);
136
137 manager()->DestroyProfileServices(NULL);
138
139 ASSERT_EQ(4U, shutdown_order()->size());
140 EXPECT_STREQ("bottom", (*shutdown_order())[0].c_str());
141 EXPECT_STREQ("middle_row_2", (*shutdown_order())[1].c_str());
142 EXPECT_STREQ("middle_row_1", (*shutdown_order())[2].c_str());
143 EXPECT_STREQ("parent", (*shutdown_order())[3].c_str());
144 }
145
146 // A final test that works with a more complex graph.
TEST_F(ProfileDependencyManagerUnittests,ComplexGraph)147 TEST_F(ProfileDependencyManagerUnittests, ComplexGraph) {
148 TestService everything_depends_on_me("everything_depends_on_me",
149 shutdown_order(), manager());
150
151 TestService intermediary_service("intermediary_service",
152 shutdown_order(), manager());
153 DependOn(&intermediary_service, &everything_depends_on_me);
154
155 TestService specialized_service("specialized_service",
156 shutdown_order(), manager());
157 DependOn(&specialized_service, &everything_depends_on_me);
158 DependOn(&specialized_service, &intermediary_service);
159
160 TestService other_root("other_root", shutdown_order(), manager());
161
162 TestService other_intermediary("other_intermediary",
163 shutdown_order(), manager());
164 DependOn(&other_intermediary, &other_root);
165
166 TestService bottom("bottom", shutdown_order(), manager());
167 DependOn(&bottom, &specialized_service);
168 DependOn(&bottom, &other_intermediary);
169
170 manager()->DestroyProfileServices(NULL);
171
172 ASSERT_EQ(6U, shutdown_order()->size());
173 EXPECT_STREQ("bottom", (*shutdown_order())[0].c_str());
174 EXPECT_STREQ("specialized_service", (*shutdown_order())[1].c_str());
175 EXPECT_STREQ("other_intermediary", (*shutdown_order())[2].c_str());
176 EXPECT_STREQ("intermediary_service", (*shutdown_order())[3].c_str());
177 EXPECT_STREQ("other_root", (*shutdown_order())[4].c_str());
178 EXPECT_STREQ("everything_depends_on_me", (*shutdown_order())[5].c_str());
179 }
180