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

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: Use base::flat_set instead of std::set. 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
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(build_settings_, builder_);
121 std::string actual_output = analyzer.Analyze(input, &err);
102 EXPECT_EQ(err.has_error(), false); 122 EXPECT_EQ(err.has_error(), false);
103 EXPECT_EQ(expected_output, actual_output); 123 EXPECT_EQ(expected_output, actual_output);
104 } 124 }
105 125
106 protected: 126 protected:
107 scoped_refptr<MockLoader> loader_; 127 scoped_refptr<MockLoader> loader_;
108 Builder builder_; 128 Builder builder_;
109 BuildSettings build_settings_; 129 BuildSettings build_settings_;
110 Settings settings_; 130 Settings settings_;
111 SourceDir tc_dir_; 131 SourceDir tc_dir_;
112 std::string tc_name_; 132 std::string tc_name_;
133 InputFileMap input_files_;
113 }; 134 };
114 135
115 } // namespace 136 } // namespace
116 137
117 // TODO: clean this up when raw string literals are allowed. 138 // TODO: clean this up when raw string literals are allowed.
118 139
119 TEST_F(AnalyzerTest, AllWasPruned) { 140 TEST_F(AnalyzerTest, AllWasPruned) {
120 RunBasicTest( 141 RunBasicTest(
121 "{" 142 "{"
122 " \"files\": [ \"//d/b.cc\" ]," 143 " \"files\": [ \"//d/b.cc\" ],"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 " \"test_targets\": [ \"//:a\" ]" 215 " \"test_targets\": [ \"//:a\" ]"
195 "}", 216 "}",
196 "{" 217 "{"
197 "\"error\":" 218 "\"error\":"
198 "\"Input does not have a key named " 219 "\"Input does not have a key named "
199 "\\\"additional_compile_targets\\\" with a list value.\"," 220 "\\\"additional_compile_targets\\\" with a list value.\","
200 "\"invalid_targets\":[]" 221 "\"invalid_targets\":[]"
201 "}"); 222 "}");
202 } 223 }
203 224
204 TEST_F(AnalyzerTest, BuildFilesWereModified) { 225 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( 226 RunBasicTest(
209 "{" 227 "{"
210 " \"files\": [ \"//a.cc\", \"//BUILD.gn\" ]," 228 " \"files\": [ \"//.gn\" ],"
211 " \"additional_compile_targets\": []," 229 " \"additional_compile_targets\": [],"
212 " \"test_targets\": [ \"//:a\" ]" 230 " \"test_targets\": [ \"//:a\" ]"
213 "}", 231 "}",
214 "{" 232 "{"
215 "\"compile_targets\":[\"//:a\"]," 233 "\"compile_targets\":[\"//:a\"],"
216 "\"status\":\"Found dependency (all)\"," 234 "\"status\":\"Found dependency (all)\","
217 "\"test_targets\":[\"//:a\"]" 235 "\"test_targets\":[\"//:a\"]"
218 "}"); 236 "}");
219 } 237 }
220 238
221 TEST_F(AnalyzerTest, BuildFilesWereModifiedAndCompilingAll) { 239 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( 240 RunBasicTest(
226 "{" 241 "{"
227 " \"files\": [ \"//a.cc\", \"//BUILD.gn\" ]," 242 " \"files\": [ \"//.gn\" ],"
228 " \"additional_compile_targets\": [ \"all\" ]," 243 " \"additional_compile_targets\": [ \"all\" ],"
229 " \"test_targets\": [ \"//:a\" ]" 244 " \"test_targets\": [ \"//:a\" ]"
230 "}", 245 "}",
231 "{" 246 "{"
232 "\"compile_targets\":[\"all\"]," 247 "\"compile_targets\":[\"all\"],"
233 "\"status\":\"Found dependency (all)\"," 248 "\"status\":\"Found dependency (all)\","
234 "\"test_targets\":[\"//:a\"]" 249 "\"test_targets\":[\"//:a\"]"
235 "}"); 250 "}");
236 } 251 }
252
253 TEST_F(AnalyzerTest, BuildFileWasModified) {
254 RunBasicTest(
255 "{"
256 " \"files\": [ \"//BUILD.gn\" ],"
257 " \"additional_compile_targets\": [],"
258 " \"test_targets\": [ \"//:a\" ]"
259 "}",
260 "{"
261 "\"compile_targets\":[],"
262 "\"status\":\"Found dependency\","
263 "\"test_targets\":[\"//:a\"]"
264 "}");
265 }
266
267 TEST_F(AnalyzerTest, BuildFileWasModifiedAndCompilingAll) {
268 RunBasicTest(
269 "{"
270 " \"files\": [ \"//BUILD.gn\" ],"
271 " \"additional_compile_targets\": [ \"all\" ],"
272 " \"test_targets\": [ \"//:a\" ]"
273 "}",
274 "{"
275 "\"compile_targets\":[\"//:a\"],"
276 "\"status\":\"Found dependency\","
277 "\"test_targets\":[\"//:a\"]"
278 "}");
279 }
280
281 TEST_F(AnalyzerTest, UnnededBuildFileWasModified) {
282 RunBasicTest(
283 "{"
284 " \"files\": [ \"//BUILD.gn\" ],"
285 " \"additional_compile_targets\": [],"
286 " \"test_targets\": [ \"//d:b_unittests\" ]"
287 "}",
288 "{"
289 "\"compile_targets\":[],"
290 "\"status\":\"No dependency\","
291 "\"test_targets\":[]"
292 "}");
293 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698