Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: tools/gn/builder_unittest.cc

Issue 56433003: GN threading refactor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/builder_record.cc ('k') | tools/gn/command_desc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 #include "tools/gn/builder.h"
7 #include "tools/gn/loader.h"
8 #include "tools/gn/target.h"
9 #include "tools/gn/test_with_scope.h"
10 #include "tools/gn/toolchain.h"
11
12 namespace {
13
14 class MockLoader : public Loader {
15 public:
16 MockLoader() {
17 }
18
19 // Loader implementation:
20 virtual void Load(const SourceFile& file,
21 const Label& toolchain_name) OVERRIDE {
22 files_.push_back(file);
23 }
24 virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE {
25 }
26 virtual Label GetDefaultToolchain() const OVERRIDE {
27 return Label();
28 }
29 virtual const Settings* GetToolchainSettings(const Label& label) OVERRIDE {
30 return NULL;
31 }
32
33 bool HasLoadedNone() const {
34 return files_.empty();
35 }
36
37 // Returns true if one load has been requested and it matches the given
38 // file. This will clear the records so it will be empty for the next call.
39 bool HasLoadedOne(const SourceFile& f) {
40 if (files_.size() != 1u) {
41 files_.clear();
42 return false;
43 }
44
45 bool match = (files_[0] == f);
46 files_.clear();
47 return match;
48 }
49
50 // Like HasLoadedOne above. Accepts any ordering.
51 bool HasLoadedTwo(const SourceFile& a, const SourceFile& b) {
52 if (files_.size() != 2u) {
53 files_.clear();
54 return false;
55 }
56
57 bool match = (
58 (files_[0] == a && files_[1] == b) ||
59 (files_[0] == b && files_[0] == a));
60 files_.clear();
61 return match;
62 }
63
64 private:
65 virtual ~MockLoader() {}
66
67 std::vector<SourceFile> files_;
68 };
69
70 class BuilderTest : public testing::Test {
71 public:
72 BuilderTest()
73 : loader_(new MockLoader),
74 builder_(new Builder(loader_.get())),
75 settings_(&build_settings_, std::string()),
76 scope_(&settings_) {
77 build_settings_.SetBuildDir(SourceDir("//out/"));
78 settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default"));
79 settings_.set_default_toolchain_label(settings_.toolchain_label());
80 }
81
82 Toolchain* DefineToolchain() {
83 Toolchain* tc = new Toolchain(&settings_, settings_.toolchain_label());
84 builder_->ItemDefined(scoped_ptr<Item>(tc));
85 return tc;
86 }
87
88 protected:
89 scoped_refptr<MockLoader> loader_;
90 scoped_refptr<Builder> builder_;
91 BuildSettings build_settings_;
92 Settings settings_;
93 Scope scope_;
94 };
95
96 } // namespace
97
98 TEST_F(BuilderTest, BasicDeps) {
99 SourceDir toolchain_dir = settings_.toolchain_label().dir();
100 std::string toolchain_name = settings_.toolchain_label().name();
101
102 DefineToolchain();
103 BuilderRecord* toolchain_record =
104 builder_->GetRecord(settings_.toolchain_label());
105 ASSERT_TRUE(toolchain_record);
106 EXPECT_EQ(BuilderRecord::ITEM_TOOLCHAIN, toolchain_record->type());
107
108 // Construct a dependency chain: A -> B -> C. Define A first with a
109 // forward-reference to B, then C, then B to test the different orders that
110 // the dependencies are hooked up.
111 Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name);
112 Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name);
113 Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name);
114
115 // The builder will take ownership of the pointers.
116 Target* a = new Target(&settings_, a_label);
117 a->deps().push_back(LabelTargetPair(b_label));
118 a->set_output_type(Target::EXECUTABLE);
119 builder_->ItemDefined(scoped_ptr<Item>(a));
120
121 // Should have requested that B and the toolchain is loaded.
122 EXPECT_TRUE(loader_->HasLoadedTwo(SourceFile("//tc/BUILD.gn"),
123 SourceFile("//b/BUILD.gn")));
124
125 // A should be unresolved with an item
126 BuilderRecord* a_record = builder_->GetRecord(a_label);
127 EXPECT_TRUE(a_record->item());
128 EXPECT_FALSE(a_record->resolved());
129 EXPECT_FALSE(a_record->can_resolve());
130
131 // B should be unresolved, have no item, and no deps.
132 BuilderRecord* b_record = builder_->GetRecord(b_label);
133 EXPECT_FALSE(b_record->item());
134 EXPECT_FALSE(b_record->resolved());
135 EXPECT_FALSE(b_record->can_resolve());
136 EXPECT_TRUE(b_record->all_deps().empty());
137
138 // A should have two deps: B and the toolchain. Only B should be unresolved.
139 EXPECT_EQ(2u, a_record->all_deps().size());
140 EXPECT_EQ(1u, a_record->unresolved_deps().size());
141 EXPECT_NE(a_record->all_deps().end(),
142 a_record->all_deps().find(toolchain_record));
143 EXPECT_NE(a_record->all_deps().end(),
144 a_record->all_deps().find(b_record));
145 EXPECT_NE(a_record->unresolved_deps().end(),
146 a_record->unresolved_deps().find(b_record));
147
148 // B should be marked as having A waiting on it.
149 EXPECT_EQ(1u, b_record->waiting_on_resolution().size());
150 EXPECT_NE(b_record->waiting_on_resolution().end(),
151 b_record->waiting_on_resolution().find(a_record));
152
153 // Add the C target.
154 Target* c = new Target(&settings_, c_label);
155 c->set_output_type(Target::STATIC_LIBRARY);
156 builder_->ItemDefined(scoped_ptr<Item>(c));
157
158 // C only depends on the already-loaded toolchain so we shouldn't have
159 // requested anything else.
160 EXPECT_TRUE(loader_->HasLoadedNone());
161
162 // Add the B target.
163 Target* b = new Target(&settings_, b_label);
164 a->deps().push_back(LabelTargetPair(c_label));
165 b->set_output_type(Target::SHARED_LIBRARY);
166 builder_->ItemDefined(scoped_ptr<Item>(b));
167
168 // B depends only on the already-loaded C and toolchain so we shouldn't have
169 // requested anything else.
170 EXPECT_TRUE(loader_->HasLoadedNone());
171
172 // All targets should now be resolved.
173 BuilderRecord* c_record = builder_->GetRecord(c_label);
174 EXPECT_TRUE(a_record->resolved());
175 EXPECT_TRUE(b_record->resolved());
176 EXPECT_TRUE(c_record->resolved());
177
178 EXPECT_TRUE(a_record->unresolved_deps().empty());
179 EXPECT_TRUE(b_record->unresolved_deps().empty());
180 EXPECT_TRUE(c_record->unresolved_deps().empty());
181
182 EXPECT_TRUE(a_record->waiting_on_resolution().empty());
183 EXPECT_TRUE(b_record->waiting_on_resolution().empty());
184 EXPECT_TRUE(c_record->waiting_on_resolution().empty());
185 }
186
187 // Tests that the should generate bit is set and propogated properly.
188 TEST_F(BuilderTest, ShouldGenerate) {
189 DefineToolchain();
190
191 // Define a secondary toolchain.
192 Settings settings2(&build_settings_, "secondary");
193 Label toolchain_label2(SourceDir("//tc/"), "secondary");
194 settings2.set_toolchain_label(toolchain_label2);
195 Toolchain* tc2 = new Toolchain(&settings2, toolchain_label2);
196 builder_->ItemDefined(scoped_ptr<Item>(tc2));
197
198 // Construct a dependency chain: A -> B. A is in the default toolchain, B
199 // is not.
200 Label a_label(SourceDir("//foo/"), "a",
201 settings_.toolchain_label().dir(), "a");
202 Label b_label(SourceDir("//foo/"), "b",
203 toolchain_label2.dir(), toolchain_label2.name());
204
205 // First define B.
206 Target* b = new Target(&settings2, b_label);
207 b->set_output_type(Target::EXECUTABLE);
208 builder_->ItemDefined(scoped_ptr<Item>(b));
209
210 // B should not be marked generated by default.
211 BuilderRecord* b_record = builder_->GetRecord(b_label);
212 EXPECT_FALSE(b_record->should_generate());
213
214 // Define A with a dependency on B.
215 Target* a = new Target(&settings_, a_label);
216 a->deps().push_back(LabelTargetPair(b_label));
217 a->set_output_type(Target::EXECUTABLE);
218 builder_->ItemDefined(scoped_ptr<Item>(a));
219
220 // A should have the generate bit set since it's in the default toolchain.
221 BuilderRecord* a_record = builder_->GetRecord(a_label);
222 EXPECT_TRUE(a_record->should_generate());
223
224 // It should have gotten pushed to B.
225 EXPECT_TRUE(b_record->should_generate());
226 }
OLDNEW
« no previous file with comments | « tools/gn/builder_record.cc ('k') | tools/gn/command_desc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698