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

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

Issue 2940873002: Implement tracking of BUILD.gn files used to define target, toolchain or (Closed)
Patch Set: Fix compilation after rebase. Created 3 years, 5 months 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
« no previous file with comments | « tools/gn/analyzer.cc ('k') | tools/gn/builder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "tools/gn/analyzer.h"
6 #include "base/memory/ptr_util.h"
5 #include "testing/gtest/include/gtest/gtest.h" 7 #include "testing/gtest/include/gtest/gtest.h"
6 #include "tools/gn/analyzer.h"
7 #include "tools/gn/build_settings.h" 8 #include "tools/gn/build_settings.h"
8 #include "tools/gn/builder.h" 9 #include "tools/gn/builder.h"
10 #include "tools/gn/input_file.h"
9 #include "tools/gn/loader.h" 11 #include "tools/gn/loader.h"
10 #include "tools/gn/settings.h" 12 #include "tools/gn/settings.h"
11 #include "tools/gn/source_file.h" 13 #include "tools/gn/source_file.h"
12 14
13
14 namespace { 15 namespace {
15 16
16 class MockLoader : public Loader { 17 class MockLoader : public Loader {
17 public: 18 public:
18 MockLoader() {} 19 MockLoader() {}
19 20
20 void Load(const SourceFile& file, 21 void Load(const SourceFile& file,
21 const LocationRange& origin, 22 const LocationRange& origin,
22 const Label& toolchain_name) override {} 23 const Label& toolchain_name) override {}
23 void ToolchainLoaded(const Toolchain* toolchain) override {} 24 void ToolchainLoaded(const Toolchain* toolchain) override {}
24 Label GetDefaultToolchain() const override { 25 Label GetDefaultToolchain() const override {
25 return Label(SourceDir("//tc/"), "default"); 26 return Label(SourceDir("//tc/"), "default");
26 } 27 }
27 const Settings* GetToolchainSettings(const Label& label) const override { 28 const Settings* GetToolchainSettings(const Label& label) const override {
28 return nullptr; 29 return nullptr;
29 } 30 }
30 31
31 private: 32 private:
32 ~MockLoader() override {} 33 ~MockLoader() override {}
33 }; 34 };
34 35
35 class AnalyzerTest : public testing::Test { 36 class AnalyzerTest : public testing::Test {
36 public: 37 public:
38 using InputFileMap = base::hash_map<SourceFile, std::unique_ptr<InputFile>>;
37 AnalyzerTest() 39 AnalyzerTest()
38 : loader_(new MockLoader), 40 : loader_(new MockLoader),
39 builder_(loader_.get()), 41 builder_(loader_.get()),
40 settings_(&build_settings_, std::string()) { 42 settings_(&build_settings_, std::string()) {
41 build_settings_.SetBuildDir(SourceDir("//out/")); 43 build_settings_.SetBuildDir(SourceDir("//out/"));
42 settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default")); 44 settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default"));
43 settings_.set_default_toolchain_label(settings_.toolchain_label()); 45 settings_.set_default_toolchain_label(settings_.toolchain_label());
44 tc_dir_ = settings_.toolchain_label().dir(); 46 tc_dir_ = settings_.toolchain_label().dir();
45 tc_name_ = settings_.toolchain_label().name(); 47 tc_name_ = settings_.toolchain_label().name();
46 } 48 }
47 49
48 Target* MakeTarget(const std::string dir, 50 Target* MakeTarget(const std::string dir,
49 const std::string name, 51 const std::string name,
50 Target::OutputType type, 52 Target::OutputType type,
51 const std::vector<std::string>& sources, 53 const std::vector<std::string>& sources,
52 const std::vector<Target*>& deps) { 54 const std::vector<Target*>& deps,
55 const std::vector<std::string>& gn_files) {
53 Label lbl(SourceDir(dir), name, tc_dir_, tc_name_); 56 Label lbl(SourceDir(dir), name, tc_dir_, tc_name_);
54 Target* target = new Target(&settings_, lbl); 57 InputFileSet input_files;
58 for (const auto& gn : gn_files) {
59 SourceFile source_file(gn);
60 auto found_input_file = input_files_.find(source_file);
61 if (found_input_file != input_files_.end()) {
62 input_files.insert(found_input_file->second.get());
63 } else {
64 auto input_file = base::MakeUnique<InputFile>(source_file);
65 input_files.insert(input_file.get());
66 input_files_.insert(std::make_pair(source_file, std::move(input_file)));
67 }
68 }
69 Target* target = new Target(&settings_, lbl, input_files);
55 target->set_output_type(type); 70 target->set_output_type(type);
56 for (const auto& s : sources) 71 for (const auto& s : sources)
57 target->sources().push_back(SourceFile(s)); 72 target->sources().push_back(SourceFile(s));
58 for (const auto* d : deps) 73 for (const auto* d : deps)
59 target->public_deps().push_back(LabelTargetPair(d)); 74 target->public_deps().push_back(LabelTargetPair(d));
60 builder_.ItemDefined(std::unique_ptr<Item>(target)); 75 builder_.ItemDefined(std::unique_ptr<Item>(target));
61 return target; 76 return target;
62 } 77 }
63 78
64 void AddSource(Target* a, std::string path) {} 79 void AddSource(Target* a, std::string path) {}
65 80
66 void AddDep(Target* a, Target* b) {} 81 void AddDep(Target* a, Target* b) {}
67 82
68 void SetUpABasicBuildGraph() { 83 void SetUpABasicBuildGraph() {
69 std::vector<std::string> no_sources; 84 std::vector<std::string> no_sources;
70 std::vector<Target*> no_deps; 85 std::vector<Target*> no_deps;
71 86
72 // All of the targets below are owned by the builder, so none of them 87 // All of the targets below are owned by the builder, so none of them
73 // get leaked. 88 // get leaked.
74 89
75 // Ignore the returned target since nothing depends on it. 90 // Ignore the returned target since nothing depends on it.
76 MakeTarget("//", "a", Target::EXECUTABLE, {"//a.cc"}, no_deps); 91 MakeTarget("//", "a", Target::EXECUTABLE, {"//a.cc"}, no_deps,
92 {"//BUILD.gn", "//features.gni"});
77 93
78 Target* b = 94 Target* b = MakeTarget("//d", "b", Target::SOURCE_SET, {"//d/b.cc"},
79 MakeTarget("//d", "b", Target::SOURCE_SET, {"//d/b.cc"}, no_deps); 95 no_deps, {"//d/BUILD.gn"});
80 96
81 Target* b_unittests = MakeTarget("//d", "b_unittests", Target::EXECUTABLE, 97 Target* b_unittests =
82 {"//d/b_unittest.cc"}, {b}); 98 MakeTarget("//d", "b_unittests", Target::EXECUTABLE,
99 {"//d/b_unittest.cc"}, {b}, {"//d/BUILD.gn"});
83 100
84 Target* c = MakeTarget("//d", "c", Target::EXECUTABLE, {"//d/c.cc"}, {b}); 101 Target* c = MakeTarget("//d", "c", Target::EXECUTABLE, {"//d/c.cc"}, {b},
102 {"//d/BUILD.gn"});
85 103
86 Target* b_unittests_and_c = 104 Target* b_unittests_and_c =
87 MakeTarget("//d", "b_unittests_and_c", Target::GROUP, no_sources, 105 MakeTarget("//d", "b_unittests_and_c", Target::GROUP, no_sources,
88 {b_unittests, c}); 106 {b_unittests, c}, {"//d/BUILD.gn"});
89 107
90 Target* e = 108 Target* e = MakeTarget("//d", "e", Target::EXECUTABLE, {"//d/e.cc"},
91 MakeTarget("//d", "e", Target::EXECUTABLE, {"//d/e.cc"}, no_deps); 109 no_deps, {"//d/BUILD.gn"});
92 110
93 // Also ignore this returned target since nothing depends on it. 111 // Also ignore this returned target since nothing depends on it.
94 MakeTarget("//d", "d", Target::GROUP, no_sources, {b_unittests_and_c, e}); 112 MakeTarget("//d", "d", Target::GROUP, no_sources, {b_unittests_and_c, e},
113 {"//d/BUILD.gn"});
95 } 114 }
96 115
97 void RunBasicTest(const std::string& input, 116 void RunBasicTest(const std::string& input,
98 const std::string& expected_output) { 117 const std::string& expected_output) {
99 SetUpABasicBuildGraph(); 118 SetUpABasicBuildGraph();
100 Err err; 119 Err err;
101 std::string actual_output = Analyzer(builder_).Analyze(input, &err); 120 Analyzer analyzer(builder_, build_settings_.build_config_file(),
121 SourceFile("//.gn"));
122 std::string actual_output = analyzer.Analyze(input, &err);
102 EXPECT_EQ(err.has_error(), false); 123 EXPECT_EQ(err.has_error(), false);
103 EXPECT_EQ(expected_output, actual_output); 124 EXPECT_EQ(expected_output, actual_output);
104 } 125 }
105 126
106 protected: 127 protected:
107 scoped_refptr<MockLoader> loader_; 128 scoped_refptr<MockLoader> loader_;
108 Builder builder_; 129 Builder builder_;
109 BuildSettings build_settings_; 130 BuildSettings build_settings_;
110 Settings settings_; 131 Settings settings_;
111 SourceDir tc_dir_; 132 SourceDir tc_dir_;
112 std::string tc_name_; 133 std::string tc_name_;
134 InputFileMap input_files_;
113 }; 135 };
114 136
115 } // namespace 137 } // namespace
116 138
117 // TODO: clean this up when raw string literals are allowed. 139 // TODO: clean this up when raw string literals are allowed.
118 140
119 TEST_F(AnalyzerTest, AllWasPruned) { 141 TEST_F(AnalyzerTest, AllWasPruned) {
120 RunBasicTest( 142 RunBasicTest(
121 "{" 143 "{"
122 " \"files\": [ \"//d/b.cc\" ]," 144 " \"files\": [ \"//d/b.cc\" ],"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 " \"test_targets\": [ \"//:a\" ]" 216 " \"test_targets\": [ \"//:a\" ]"
195 "}", 217 "}",
196 "{" 218 "{"
197 "\"error\":" 219 "\"error\":"
198 "\"Input does not have a key named " 220 "\"Input does not have a key named "
199 "\\\"additional_compile_targets\\\" with a list value.\"," 221 "\\\"additional_compile_targets\\\" with a list value.\","
200 "\"invalid_targets\":[]" 222 "\"invalid_targets\":[]"
201 "}"); 223 "}");
202 } 224 }
203 225
204 TEST_F(AnalyzerTest, BuildFilesWereModified) { 226 TEST_F(AnalyzerTest, DotGnFileWasModified) {
205 // This tests that if a build file is modified, we bail out early with
206 // "Found dependency (all)" error since we can't handle changes to
207 // build files yet (crbug.com/555273).
208 RunBasicTest( 227 RunBasicTest(
209 "{" 228 "{"
210 " \"files\": [ \"//a.cc\", \"//BUILD.gn\" ]," 229 " \"files\": [ \"//.gn\" ],"
211 " \"additional_compile_targets\": []," 230 " \"additional_compile_targets\": [],"
212 " \"test_targets\": [ \"//:a\" ]" 231 " \"test_targets\": [ \"//:a\" ]"
213 "}", 232 "}",
214 "{" 233 "{"
215 "\"compile_targets\":[\"//:a\"]," 234 "\"compile_targets\":[\"//:a\"],"
216 "\"status\":\"Found dependency (all)\"," 235 "\"status\":\"Found dependency (all)\","
217 "\"test_targets\":[\"//:a\"]" 236 "\"test_targets\":[\"//:a\"]"
218 "}"); 237 "}");
219 } 238 }
220 239
221 TEST_F(AnalyzerTest, BuildFilesWereModifiedAndCompilingAll) { 240 TEST_F(AnalyzerTest, DotGnFileWasModifiedAndCompilingAll) {
222 // This tests that if a build file is modified, we bail out early with
223 // "Found dependency (all)" error since we can't handle changes to
224 // build files yet (crbug.com/555273).
225 RunBasicTest( 241 RunBasicTest(
226 "{" 242 "{"
227 " \"files\": [ \"//a.cc\", \"//BUILD.gn\" ]," 243 " \"files\": [ \"//.gn\" ],"
228 " \"additional_compile_targets\": [ \"all\" ]," 244 " \"additional_compile_targets\": [ \"all\" ],"
229 " \"test_targets\": [ \"//:a\" ]" 245 " \"test_targets\": [ \"//:a\" ]"
230 "}", 246 "}",
231 "{" 247 "{"
232 "\"compile_targets\":[\"all\"]," 248 "\"compile_targets\":[\"all\"],"
233 "\"status\":\"Found dependency (all)\"," 249 "\"status\":\"Found dependency (all)\","
234 "\"test_targets\":[\"//:a\"]" 250 "\"test_targets\":[\"//:a\"]"
235 "}"); 251 "}");
236 } 252 }
253
254 TEST_F(AnalyzerTest, BuildFileWasModified) {
255 RunBasicTest(
256 "{"
257 " \"files\": [ \"//BUILD.gn\" ],"
258 " \"additional_compile_targets\": [],"
259 " \"test_targets\": [ \"//:a\" ]"
260 "}",
261 "{"
262 "\"compile_targets\":[],"
263 "\"status\":\"Found dependency\","
264 "\"test_targets\":[\"//:a\"]"
265 "}");
266 }
267
268 TEST_F(AnalyzerTest, BuildFileWasModifiedAndCompilingAll) {
269 RunBasicTest(
270 "{"
271 " \"files\": [ \"//BUILD.gn\" ],"
272 " \"additional_compile_targets\": [ \"all\" ],"
273 " \"test_targets\": [ \"//:a\" ]"
274 "}",
275 "{"
276 "\"compile_targets\":[\"//:a\"],"
277 "\"status\":\"Found dependency\","
278 "\"test_targets\":[\"//:a\"]"
279 "}");
280 }
281
282 TEST_F(AnalyzerTest, UnnededBuildFileWasModified) {
283 RunBasicTest(
284 "{"
285 " \"files\": [ \"//BUILD.gn\" ],"
286 " \"additional_compile_targets\": [],"
287 " \"test_targets\": [ \"//d:b_unittests\" ]"
288 "}",
289 "{"
290 "\"compile_targets\":[],"
291 "\"status\":\"No dependency\","
292 "\"test_targets\":[]"
293 "}");
294 }
OLDNEW
« no previous file with comments | « tools/gn/analyzer.cc ('k') | tools/gn/builder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698