| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "testing/gtest/include/gtest/gtest.h" | 5 #include "testing/gtest/include/gtest/gtest.h" |
| 6 #include "tools/gn/builder.h" | 6 #include "tools/gn/builder.h" |
| 7 #include "tools/gn/config.h" | 7 #include "tools/gn/config.h" |
| 8 #include "tools/gn/loader.h" | 8 #include "tools/gn/loader.h" |
| 9 #include "tools/gn/target.h" | 9 #include "tools/gn/target.h" |
| 10 #include "tools/gn/test_with_scope.h" | 10 #include "tools/gn/test_with_scope.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 private: | 60 private: |
| 61 ~MockLoader() override {} | 61 ~MockLoader() override {} |
| 62 | 62 |
| 63 std::vector<SourceFile> files_; | 63 std::vector<SourceFile> files_; |
| 64 }; | 64 }; |
| 65 | 65 |
| 66 class BuilderTest : public testing::Test { | 66 class BuilderTest : public testing::Test { |
| 67 public: | 67 public: |
| 68 BuilderTest() | 68 BuilderTest() |
| 69 : loader_(new MockLoader), | 69 : loader_(new MockLoader), |
| 70 builder_(new Builder(loader_.get())), | 70 builder_(loader_.get()), |
| 71 settings_(&build_settings_, std::string()), | 71 settings_(&build_settings_, std::string()), |
| 72 scope_(&settings_) { | 72 scope_(&settings_) { |
| 73 build_settings_.SetBuildDir(SourceDir("//out/")); | 73 build_settings_.SetBuildDir(SourceDir("//out/")); |
| 74 settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default")); | 74 settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default")); |
| 75 settings_.set_default_toolchain_label(settings_.toolchain_label()); | 75 settings_.set_default_toolchain_label(settings_.toolchain_label()); |
| 76 } | 76 } |
| 77 | 77 |
| 78 Toolchain* DefineToolchain() { | 78 Toolchain* DefineToolchain() { |
| 79 Toolchain* tc = new Toolchain(&settings_, settings_.toolchain_label()); | 79 Toolchain* tc = new Toolchain(&settings_, settings_.toolchain_label()); |
| 80 TestWithScope::SetupToolchain(tc); | 80 TestWithScope::SetupToolchain(tc); |
| 81 builder_->ItemDefined(std::unique_ptr<Item>(tc)); | 81 builder_.ItemDefined(std::unique_ptr<Item>(tc)); |
| 82 return tc; | 82 return tc; |
| 83 } | 83 } |
| 84 | 84 |
| 85 protected: | 85 protected: |
| 86 scoped_refptr<MockLoader> loader_; | 86 scoped_refptr<MockLoader> loader_; |
| 87 scoped_refptr<Builder> builder_; | 87 Builder builder_; |
| 88 BuildSettings build_settings_; | 88 BuildSettings build_settings_; |
| 89 Settings settings_; | 89 Settings settings_; |
| 90 Scope scope_; | 90 Scope scope_; |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 } // namespace | 93 } // namespace |
| 94 | 94 |
| 95 TEST_F(BuilderTest, BasicDeps) { | 95 TEST_F(BuilderTest, BasicDeps) { |
| 96 SourceDir toolchain_dir = settings_.toolchain_label().dir(); | 96 SourceDir toolchain_dir = settings_.toolchain_label().dir(); |
| 97 std::string toolchain_name = settings_.toolchain_label().name(); | 97 std::string toolchain_name = settings_.toolchain_label().name(); |
| 98 | 98 |
| 99 // Construct a dependency chain: A -> B -> C. Define A first with a | 99 // Construct a dependency chain: A -> B -> C. Define A first with a |
| 100 // forward-reference to B, then C, then B to test the different orders that | 100 // forward-reference to B, then C, then B to test the different orders that |
| 101 // the dependencies are hooked up. | 101 // the dependencies are hooked up. |
| 102 Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name); | 102 Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name); |
| 103 Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name); | 103 Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name); |
| 104 Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name); | 104 Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name); |
| 105 | 105 |
| 106 // The builder will take ownership of the pointers. | 106 // The builder will take ownership of the pointers. |
| 107 Target* a = new Target(&settings_, a_label); | 107 Target* a = new Target(&settings_, a_label); |
| 108 a->public_deps().push_back(LabelTargetPair(b_label)); | 108 a->public_deps().push_back(LabelTargetPair(b_label)); |
| 109 a->set_output_type(Target::EXECUTABLE); | 109 a->set_output_type(Target::EXECUTABLE); |
| 110 builder_->ItemDefined(std::unique_ptr<Item>(a)); | 110 builder_.ItemDefined(std::unique_ptr<Item>(a)); |
| 111 | 111 |
| 112 // Should have requested that B and the toolchain is loaded. | 112 // Should have requested that B and the toolchain is loaded. |
| 113 EXPECT_TRUE(loader_->HasLoadedTwo(SourceFile("//tc/BUILD.gn"), | 113 EXPECT_TRUE(loader_->HasLoadedTwo(SourceFile("//tc/BUILD.gn"), |
| 114 SourceFile("//b/BUILD.gn"))); | 114 SourceFile("//b/BUILD.gn"))); |
| 115 | 115 |
| 116 // Define the toolchain. | 116 // Define the toolchain. |
| 117 DefineToolchain(); | 117 DefineToolchain(); |
| 118 BuilderRecord* toolchain_record = | 118 BuilderRecord* toolchain_record = |
| 119 builder_->GetRecord(settings_.toolchain_label()); | 119 builder_.GetRecord(settings_.toolchain_label()); |
| 120 ASSERT_TRUE(toolchain_record); | 120 ASSERT_TRUE(toolchain_record); |
| 121 EXPECT_EQ(BuilderRecord::ITEM_TOOLCHAIN, toolchain_record->type()); | 121 EXPECT_EQ(BuilderRecord::ITEM_TOOLCHAIN, toolchain_record->type()); |
| 122 | 122 |
| 123 // A should be unresolved with an item | 123 // A should be unresolved with an item |
| 124 BuilderRecord* a_record = builder_->GetRecord(a_label); | 124 BuilderRecord* a_record = builder_.GetRecord(a_label); |
| 125 EXPECT_TRUE(a_record->item()); | 125 EXPECT_TRUE(a_record->item()); |
| 126 EXPECT_FALSE(a_record->resolved()); | 126 EXPECT_FALSE(a_record->resolved()); |
| 127 EXPECT_FALSE(a_record->can_resolve()); | 127 EXPECT_FALSE(a_record->can_resolve()); |
| 128 | 128 |
| 129 // B should be unresolved, have no item, and no deps. | 129 // B should be unresolved, have no item, and no deps. |
| 130 BuilderRecord* b_record = builder_->GetRecord(b_label); | 130 BuilderRecord* b_record = builder_.GetRecord(b_label); |
| 131 EXPECT_FALSE(b_record->item()); | 131 EXPECT_FALSE(b_record->item()); |
| 132 EXPECT_FALSE(b_record->resolved()); | 132 EXPECT_FALSE(b_record->resolved()); |
| 133 EXPECT_FALSE(b_record->can_resolve()); | 133 EXPECT_FALSE(b_record->can_resolve()); |
| 134 EXPECT_TRUE(b_record->all_deps().empty()); | 134 EXPECT_TRUE(b_record->all_deps().empty()); |
| 135 | 135 |
| 136 // A should have two deps: B and the toolchain. Only B should be unresolved. | 136 // A should have two deps: B and the toolchain. Only B should be unresolved. |
| 137 EXPECT_EQ(2u, a_record->all_deps().size()); | 137 EXPECT_EQ(2u, a_record->all_deps().size()); |
| 138 EXPECT_EQ(1u, a_record->unresolved_deps().size()); | 138 EXPECT_EQ(1u, a_record->unresolved_deps().size()); |
| 139 EXPECT_NE(a_record->all_deps().end(), | 139 EXPECT_NE(a_record->all_deps().end(), |
| 140 a_record->all_deps().find(toolchain_record)); | 140 a_record->all_deps().find(toolchain_record)); |
| 141 EXPECT_NE(a_record->all_deps().end(), | 141 EXPECT_NE(a_record->all_deps().end(), |
| 142 a_record->all_deps().find(b_record)); | 142 a_record->all_deps().find(b_record)); |
| 143 EXPECT_NE(a_record->unresolved_deps().end(), | 143 EXPECT_NE(a_record->unresolved_deps().end(), |
| 144 a_record->unresolved_deps().find(b_record)); | 144 a_record->unresolved_deps().find(b_record)); |
| 145 | 145 |
| 146 // B should be marked as having A waiting on it. | 146 // B should be marked as having A waiting on it. |
| 147 EXPECT_EQ(1u, b_record->waiting_on_resolution().size()); | 147 EXPECT_EQ(1u, b_record->waiting_on_resolution().size()); |
| 148 EXPECT_NE(b_record->waiting_on_resolution().end(), | 148 EXPECT_NE(b_record->waiting_on_resolution().end(), |
| 149 b_record->waiting_on_resolution().find(a_record)); | 149 b_record->waiting_on_resolution().find(a_record)); |
| 150 | 150 |
| 151 // Add the C target. | 151 // Add the C target. |
| 152 Target* c = new Target(&settings_, c_label); | 152 Target* c = new Target(&settings_, c_label); |
| 153 c->set_output_type(Target::STATIC_LIBRARY); | 153 c->set_output_type(Target::STATIC_LIBRARY); |
| 154 c->visibility().SetPublic(); | 154 c->visibility().SetPublic(); |
| 155 builder_->ItemDefined(std::unique_ptr<Item>(c)); | 155 builder_.ItemDefined(std::unique_ptr<Item>(c)); |
| 156 | 156 |
| 157 // C only depends on the already-loaded toolchain so we shouldn't have | 157 // C only depends on the already-loaded toolchain so we shouldn't have |
| 158 // requested anything else. | 158 // requested anything else. |
| 159 EXPECT_TRUE(loader_->HasLoadedNone()); | 159 EXPECT_TRUE(loader_->HasLoadedNone()); |
| 160 | 160 |
| 161 // Add the B target. | 161 // Add the B target. |
| 162 Target* b = new Target(&settings_, b_label); | 162 Target* b = new Target(&settings_, b_label); |
| 163 a->public_deps().push_back(LabelTargetPair(c_label)); | 163 a->public_deps().push_back(LabelTargetPair(c_label)); |
| 164 b->set_output_type(Target::SHARED_LIBRARY); | 164 b->set_output_type(Target::SHARED_LIBRARY); |
| 165 b->visibility().SetPublic(); | 165 b->visibility().SetPublic(); |
| 166 builder_->ItemDefined(std::unique_ptr<Item>(b)); | 166 builder_.ItemDefined(std::unique_ptr<Item>(b)); |
| 167 | 167 |
| 168 // B depends only on the already-loaded C and toolchain so we shouldn't have | 168 // B depends only on the already-loaded C and toolchain so we shouldn't have |
| 169 // requested anything else. | 169 // requested anything else. |
| 170 EXPECT_TRUE(loader_->HasLoadedNone()); | 170 EXPECT_TRUE(loader_->HasLoadedNone()); |
| 171 | 171 |
| 172 // All targets should now be resolved. | 172 // All targets should now be resolved. |
| 173 BuilderRecord* c_record = builder_->GetRecord(c_label); | 173 BuilderRecord* c_record = builder_.GetRecord(c_label); |
| 174 EXPECT_TRUE(a_record->resolved()); | 174 EXPECT_TRUE(a_record->resolved()); |
| 175 EXPECT_TRUE(b_record->resolved()); | 175 EXPECT_TRUE(b_record->resolved()); |
| 176 EXPECT_TRUE(c_record->resolved()); | 176 EXPECT_TRUE(c_record->resolved()); |
| 177 | 177 |
| 178 EXPECT_TRUE(a_record->unresolved_deps().empty()); | 178 EXPECT_TRUE(a_record->unresolved_deps().empty()); |
| 179 EXPECT_TRUE(b_record->unresolved_deps().empty()); | 179 EXPECT_TRUE(b_record->unresolved_deps().empty()); |
| 180 EXPECT_TRUE(c_record->unresolved_deps().empty()); | 180 EXPECT_TRUE(c_record->unresolved_deps().empty()); |
| 181 | 181 |
| 182 EXPECT_TRUE(a_record->waiting_on_resolution().empty()); | 182 EXPECT_TRUE(a_record->waiting_on_resolution().empty()); |
| 183 EXPECT_TRUE(b_record->waiting_on_resolution().empty()); | 183 EXPECT_TRUE(b_record->waiting_on_resolution().empty()); |
| 184 EXPECT_TRUE(c_record->waiting_on_resolution().empty()); | 184 EXPECT_TRUE(c_record->waiting_on_resolution().empty()); |
| 185 } | 185 } |
| 186 | 186 |
| 187 // Tests that the "should generate" flag is set and propagated properly. | 187 // Tests that the "should generate" flag is set and propagated properly. |
| 188 TEST_F(BuilderTest, ShouldGenerate) { | 188 TEST_F(BuilderTest, ShouldGenerate) { |
| 189 DefineToolchain(); | 189 DefineToolchain(); |
| 190 | 190 |
| 191 // Define a secondary toolchain. | 191 // Define a secondary toolchain. |
| 192 Settings settings2(&build_settings_, "secondary/"); | 192 Settings settings2(&build_settings_, "secondary/"); |
| 193 Label toolchain_label2(SourceDir("//tc/"), "secondary"); | 193 Label toolchain_label2(SourceDir("//tc/"), "secondary"); |
| 194 settings2.set_toolchain_label(toolchain_label2); | 194 settings2.set_toolchain_label(toolchain_label2); |
| 195 Toolchain* tc2 = new Toolchain(&settings2, toolchain_label2); | 195 Toolchain* tc2 = new Toolchain(&settings2, toolchain_label2); |
| 196 TestWithScope::SetupToolchain(tc2); | 196 TestWithScope::SetupToolchain(tc2); |
| 197 builder_->ItemDefined(std::unique_ptr<Item>(tc2)); | 197 builder_.ItemDefined(std::unique_ptr<Item>(tc2)); |
| 198 | 198 |
| 199 // Construct a dependency chain: A -> B. A is in the default toolchain, B | 199 // Construct a dependency chain: A -> B. A is in the default toolchain, B |
| 200 // is not. | 200 // is not. |
| 201 Label a_label(SourceDir("//foo/"), "a", | 201 Label a_label(SourceDir("//foo/"), "a", |
| 202 settings_.toolchain_label().dir(), "a"); | 202 settings_.toolchain_label().dir(), "a"); |
| 203 Label b_label(SourceDir("//foo/"), "b", | 203 Label b_label(SourceDir("//foo/"), "b", |
| 204 toolchain_label2.dir(), toolchain_label2.name()); | 204 toolchain_label2.dir(), toolchain_label2.name()); |
| 205 | 205 |
| 206 // First define B. | 206 // First define B. |
| 207 Target* b = new Target(&settings2, b_label); | 207 Target* b = new Target(&settings2, b_label); |
| 208 b->visibility().SetPublic(); | 208 b->visibility().SetPublic(); |
| 209 b->set_output_type(Target::EXECUTABLE); | 209 b->set_output_type(Target::EXECUTABLE); |
| 210 builder_->ItemDefined(std::unique_ptr<Item>(b)); | 210 builder_.ItemDefined(std::unique_ptr<Item>(b)); |
| 211 | 211 |
| 212 // B should not be marked generated by default. | 212 // B should not be marked generated by default. |
| 213 BuilderRecord* b_record = builder_->GetRecord(b_label); | 213 BuilderRecord* b_record = builder_.GetRecord(b_label); |
| 214 EXPECT_FALSE(b_record->should_generate()); | 214 EXPECT_FALSE(b_record->should_generate()); |
| 215 | 215 |
| 216 // Define A with a dependency on B. | 216 // Define A with a dependency on B. |
| 217 Target* a = new Target(&settings_, a_label); | 217 Target* a = new Target(&settings_, a_label); |
| 218 a->public_deps().push_back(LabelTargetPair(b_label)); | 218 a->public_deps().push_back(LabelTargetPair(b_label)); |
| 219 a->set_output_type(Target::EXECUTABLE); | 219 a->set_output_type(Target::EXECUTABLE); |
| 220 builder_->ItemDefined(std::unique_ptr<Item>(a)); | 220 builder_.ItemDefined(std::unique_ptr<Item>(a)); |
| 221 | 221 |
| 222 // A should have the generate bit set since it's in the default toolchain. | 222 // A should have the generate bit set since it's in the default toolchain. |
| 223 BuilderRecord* a_record = builder_->GetRecord(a_label); | 223 BuilderRecord* a_record = builder_.GetRecord(a_label); |
| 224 EXPECT_TRUE(a_record->should_generate()); | 224 EXPECT_TRUE(a_record->should_generate()); |
| 225 | 225 |
| 226 // It should have gotten pushed to B. | 226 // It should have gotten pushed to B. |
| 227 EXPECT_TRUE(b_record->should_generate()); | 227 EXPECT_TRUE(b_record->should_generate()); |
| 228 } | 228 } |
| 229 | 229 |
| 230 // Tests that configs applied to a config get loaded (bug 536844). | 230 // Tests that configs applied to a config get loaded (bug 536844). |
| 231 TEST_F(BuilderTest, ConfigLoad) { | 231 TEST_F(BuilderTest, ConfigLoad) { |
| 232 SourceDir toolchain_dir = settings_.toolchain_label().dir(); | 232 SourceDir toolchain_dir = settings_.toolchain_label().dir(); |
| 233 std::string toolchain_name = settings_.toolchain_label().name(); | 233 std::string toolchain_name = settings_.toolchain_label().name(); |
| 234 | 234 |
| 235 // Construct a dependency chain: A -> B -> C. Define A first with a | 235 // Construct a dependency chain: A -> B -> C. Define A first with a |
| 236 // forward-reference to B, then C, then B to test the different orders that | 236 // forward-reference to B, then C, then B to test the different orders that |
| 237 // the dependencies are hooked up. | 237 // the dependencies are hooked up. |
| 238 Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name); | 238 Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name); |
| 239 Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name); | 239 Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name); |
| 240 Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name); | 240 Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name); |
| 241 | 241 |
| 242 // The builder will take ownership of the pointers. | 242 // The builder will take ownership of the pointers. |
| 243 Config* a = new Config(&settings_, a_label); | 243 Config* a = new Config(&settings_, a_label); |
| 244 a->configs().push_back(LabelConfigPair(b_label)); | 244 a->configs().push_back(LabelConfigPair(b_label)); |
| 245 builder_->ItemDefined(std::unique_ptr<Item>(a)); | 245 builder_.ItemDefined(std::unique_ptr<Item>(a)); |
| 246 | 246 |
| 247 // Should have requested that B is loaded. | 247 // Should have requested that B is loaded. |
| 248 EXPECT_TRUE(loader_->HasLoadedOne(SourceFile("//b/BUILD.gn"))); | 248 EXPECT_TRUE(loader_->HasLoadedOne(SourceFile("//b/BUILD.gn"))); |
| 249 } | 249 } |
| OLD | NEW |