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
10class ProfileDependencyManagerUnittests : public ::testing::Test {
11 protected:
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:
19  void DependOn(ProfileKeyedServiceFactory* child,
20                ProfileKeyedServiceFactory* parent) {
21    child->DependsOn(parent);
22  }
23
24  ProfileDependencyManager* manager() { return &dependency_manager_; }
25
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
34class TestService : public ProfileKeyedServiceFactory {
35 public:
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
44  virtual ProfileKeyedService* BuildServiceInstanceFor(
45      Profile* profile) const {
46    ADD_FAILURE() << "This isn't part of the tests!";
47    return NULL;
48  }
49
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.
60TEST_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.
70TEST_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
83TEST_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
99TEST_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.
124TEST_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.
147TEST_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