Flutter Engine
 
Loading...
Searching...
No Matches
license_checker_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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#include <filesystem>
5#include <fstream>
6#include "flutter/third_party/re2/re2/re2.h"
8#include "gtest/gtest.h"
9#include "third_party/abseil-cpp/absl/status/statusor.h"
10#include "third_party/abseil-cpp/absl/strings/str_cat.h"
11
12namespace fs = std::filesystem;
13
14class LicenseCheckerTest : public testing::Test {
15 public:
16 void SetUp() override {
17 std::error_code err;
18 temp_dir_base_ = fs::temp_directory_path(err);
19 ASSERT_FALSE(err);
20 }
21
22 void TearDown() override {
23 if (should_delete_temp_dir_) {
24 fs::remove_all(temp_dir_);
25 }
26 }
27
28 absl::StatusOr<fs::path> MakeTempDir() {
29 static std::atomic<int32_t> count = 0;
30 std::stringstream ss;
31 ss << "LicenseCheckerTest_" << std::time(nullptr) << "_"
32 << count.fetch_add(1);
33 temp_dir_ = temp_dir_base_ / ss.str();
34 std::error_code err;
35 fs::create_directory(temp_dir_, err);
36 if (!err) {
37 should_delete_temp_dir_ = true;
38 } else {
39 return absl::InternalError("can't make temp dir");
40 }
41
42 fs::path engine_path = temp_dir_ / "engine";
43 fs::create_directory(engine_path, err);
44 if (err) {
45 return absl::InternalError("can't make temp engine dir");
46 }
47
48 return engine_path;
49 }
50
51 private:
52 fs::path temp_dir_base_;
53 fs::path temp_dir_;
54 bool should_delete_temp_dir_;
55};
56
57namespace {
58
59const char* kHeader = R"header(
60// Copyright Test
61
62void main() {
63}
64)header";
65
66const char* kUnknownHeader = R"header(
67// Unknown Copyright
68
69void main() {
70}
71)header";
72
73const char* kCHeader = R"header(
74/*
75C Copyright Test
76*/
77
78void main() {
79}
80)header";
81
82const char* kLicense = R"lic(Test License
83v2.0
84)lic";
85
86const char* kUnknownLicense = R"lic(Unknown License
872025
88v2.0
89)lic";
90
91absl::StatusOr<Data> MakeTestData(
92 std::optional<std::string_view> include_filter_text = std::nullopt) {
93 std::stringstream include;
94 if (include_filter_text.has_value()) {
95 include << include_filter_text.value() << std::endl;
96 } else {
97 include << ".*\\.cc" << std::endl;
98 }
99 absl::StatusOr<Filter> include_filter = Filter::Open(include);
100 if (!include_filter.ok()) {
101 return include_filter.status();
102 }
103 std::stringstream exclude;
104 exclude << ".*/ignore/.*" << std::endl;
105 absl::StatusOr<Filter> exclude_filter = Filter::Open(exclude);
106 if (!exclude_filter.ok()) {
107 return exclude_filter.status();
108 }
109
110 absl::StatusOr<Catalog> catalog =
111 Catalog::Make({{"test", "Test License", R"lic(Test License
112v\d\.\d)lic"},
113 {"header", "Copyright Test", "(?:C )?Copyright Test"}});
114 if (!catalog.ok()) {
115 return catalog.status();
116 }
117
118 return Data{
119 .include_filter = std::move(*include_filter),
120 .exclude_filter = std::move(*exclude_filter),
121 .catalog = std::move(catalog.value()),
122 .secondary_dir = fs::path(),
123 };
124}
125
126absl::Status WriteFile(std::string_view data, const fs::path& path) {
127 std::ofstream of;
128 of.open(path.string(), std::ios::binary);
129 if (!of.good()) {
130 return absl::InternalError("can't open file");
131 }
132 of.write(data.data(), data.length());
133 of.close();
134 return absl::OkStatus();
135}
136
137bool FindError(const std::vector<absl::Status>& errors,
138 absl::StatusCode code,
139 std::string_view regex) {
140 return std::find_if(errors.begin(), errors.end(),
141 [code, regex](const absl::Status& status) {
142 return status.code() == code &&
143 RE2::PartialMatch(status.message(), regex);
144 }) != errors.end();
145}
146
147class Repo {
148 public:
149 void Add(const std::string& file) { files_.emplace_back(std::string(file)); }
150
151 absl::Status Commit() {
152 if (std::system("git init") != 0) {
153 return absl::InternalError("git init failed");
154 }
155 for (const std::string& file : files_) {
156 if (std::system(("git add " + file).c_str()) != 0) {
157 return absl::InternalError("git add failed: " + file);
158 }
159 }
160 if (std::system("git commit -m \"test\"") != 0) {
161 return absl::InternalError("git commit failed");
162 }
163 return absl::OkStatus();
164 }
165
166 private:
167 std::vector<std::string> files_;
168};
169
170} // namespace
171
173 absl::StatusOr<fs::path> temp_path = MakeTempDir();
174 ASSERT_TRUE(temp_path.ok());
175
176 absl::StatusOr<Data> data = MakeTestData();
177 ASSERT_TRUE(data.ok());
178
179 fs::current_path(*temp_path);
180 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
181 ASSERT_TRUE(WriteFile(kLicense, *temp_path / "LICENSE").ok());
182 Repo repo;
183 repo.Add(*temp_path / "main.cc");
184 repo.Add(*temp_path / "LICENSE");
185 ASSERT_TRUE(repo.Commit().ok());
186
187 std::stringstream ss;
188 std::vector<absl::Status> errors =
189 LicenseChecker::Run(temp_path->string(), ss, *data);
190 EXPECT_EQ(errors.size(), 0u) << errors[0];
191}
192
193TEST_F(LicenseCheckerTest, UnknownFileLicense) {
194 absl::StatusOr<fs::path> temp_path = MakeTempDir();
195 ASSERT_TRUE(temp_path.ok());
196
197 absl::StatusOr<Data> data = MakeTestData();
198 ASSERT_TRUE(data.ok());
199
200 fs::current_path(*temp_path);
201 ASSERT_TRUE(WriteFile(kUnknownHeader, *temp_path / "main.cc").ok());
202 Repo repo;
203 repo.Add(*temp_path / "main.cc");
204 ASSERT_TRUE(repo.Commit().ok());
205
206 std::stringstream ss;
207 std::vector<absl::Status> errors =
208 LicenseChecker::Run(temp_path->string(), ss, *data);
209 EXPECT_EQ(errors.size(), 1u);
210 EXPECT_TRUE(FindError(errors, absl::StatusCode::kNotFound,
211 "Expected copyright in.*main.cc"))
212 << (errors.size() > 0 ? absl::StrCat(errors[0]) : "")
213 << (errors.size() > 1 ? absl::StrCat("\n", errors[1]) : "");
214}
215
216TEST_F(LicenseCheckerTest, UnknownLicense) {
217 absl::StatusOr<fs::path> temp_path = MakeTempDir();
218 ASSERT_TRUE(temp_path.ok());
219
220 absl::StatusOr<Data> data = MakeTestData();
221 ASSERT_TRUE(data.ok());
222
223 fs::current_path(*temp_path);
224 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
225 // Make sure the error is only reported once.
226 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "foo.cc").ok());
227 ASSERT_TRUE(WriteFile(kUnknownLicense, *temp_path / "LICENSE").ok());
228 Repo repo;
229 repo.Add(*temp_path / "main.cc");
230 repo.Add(*temp_path / "foo.cc");
231 repo.Add(*temp_path / "LICENSE");
232 ASSERT_TRUE(repo.Commit().ok());
233
234 std::stringstream ss;
235 std::vector<absl::Status> errors =
236 LicenseChecker::Run(temp_path->string(), ss, *data);
237 EXPECT_EQ(errors.size(), 1u);
238 ASSERT_TRUE(!errors.empty());
239 EXPECT_TRUE(FindError(errors, absl::StatusCode::kNotFound,
240 "Unknown license in.*LICENSE"))
241 << errors[0];
242}
243
244TEST_F(LicenseCheckerTest, SimpleMissingFileLicense) {
245 absl::StatusOr<fs::path> temp_path = MakeTempDir();
246 ASSERT_TRUE(temp_path.ok());
247
248 absl::StatusOr<Data> data = MakeTestData();
249 ASSERT_TRUE(data.ok());
250
251 fs::current_path(*temp_path);
252 ASSERT_EQ(std::system("echo \"Hello world!\" > main.cc"), 0);
253 Repo repo;
254 repo.Add(*temp_path / "main.cc");
255 ASSERT_TRUE(repo.Commit().ok());
256
257 std::stringstream ss;
258 std::vector<absl::Status> errors =
259 LicenseChecker::Run(temp_path->string(), ss, *data);
260 EXPECT_EQ(errors.size(), 1u);
261 EXPECT_TRUE(FindError(errors, absl::StatusCode::kNotFound,
262 "Expected copyright in.*main.cc"))
263 << (errors.size() > 0 ? absl::StrCat(errors[0]) : "");
264}
265
266TEST_F(LicenseCheckerTest, SimpleIgnoreFile) {
267 absl::StatusOr<fs::path> temp_path = MakeTempDir();
268 ASSERT_TRUE(temp_path.ok());
269
270 absl::StatusOr<Data> data = MakeTestData();
271 ASSERT_TRUE(data.ok());
272
273 std::stringstream exclude;
274 exclude << R"regex(^main\.cc)regex" << std::endl;
275 absl::StatusOr<Filter> exclude_filter = Filter::Open(exclude);
276 ASSERT_TRUE(exclude_filter.ok());
277 data->exclude_filter = std::move(exclude_filter.value());
278
279 fs::current_path(*temp_path);
280 ASSERT_TRUE(WriteFile(kUnknownHeader, *temp_path / "main.cc").ok());
281 Repo repo;
282 repo.Add(*temp_path / "main.cc");
283 ASSERT_TRUE(repo.Commit().ok());
284
285 std::stringstream ss;
286 std::vector<absl::Status> errors =
287 LicenseChecker::Run(temp_path->string(), ss, *data);
288 EXPECT_EQ(errors.size(), 0u);
289}
290
291TEST_F(LicenseCheckerTest, CanIgnoreLicenseFiles) {
292 absl::StatusOr<fs::path> temp_path = MakeTempDir();
293 ASSERT_TRUE(temp_path.ok());
294
295 absl::StatusOr<Data> data = MakeTestData();
296 ASSERT_TRUE(data.ok());
297
298 std::stringstream exclude;
299 exclude << "^LICENSE" << std::endl;
300 absl::StatusOr<Filter> exclude_filter = Filter::Open(exclude);
301 ASSERT_TRUE(exclude_filter.ok());
302 data->exclude_filter = std::move(exclude_filter.value());
303
304 fs::current_path(*temp_path);
305 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
306 ASSERT_TRUE(WriteFile(kLicense, *temp_path / "LICENSE").ok());
307 Repo repo;
308 repo.Add(*temp_path / "main.cc");
309 repo.Add(*temp_path / "LICENSE");
310 ASSERT_TRUE(repo.Commit().ok());
311
312 std::stringstream ss;
313 std::vector<absl::Status> errors =
314 LicenseChecker::Run(temp_path->string(), ss, *data);
315 EXPECT_EQ(errors.size(), 0u) << errors[0];
316
317 EXPECT_EQ(ss.str(), R"output(engine
318
319Copyright Test
320)output");
321}
322
323TEST_F(LicenseCheckerTest, SimpleWritesFileLicensesFile) {
324 absl::StatusOr<fs::path> temp_path = MakeTempDir();
325 ASSERT_TRUE(temp_path.ok());
326
327 absl::StatusOr<Data> data = MakeTestData();
328 ASSERT_TRUE(data.ok());
329
330 fs::current_path(*temp_path);
331 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
332 Repo repo;
333 repo.Add(*temp_path / "main.cc");
334 ASSERT_TRUE(repo.Commit().ok());
335
336 std::stringstream ss;
337 std::vector<absl::Status> errors =
338 LicenseChecker::Run(temp_path->string(), ss, *data);
339 EXPECT_EQ(errors.size(), 0u) << errors[0];
340
341 EXPECT_EQ(ss.str(), R"output(engine
342
343Copyright Test
344)output");
345}
346
347TEST_F(LicenseCheckerTest, SimpleWritesTwoFileLicensesFiles) {
348 absl::StatusOr<fs::path> temp_path = MakeTempDir();
349 ASSERT_TRUE(temp_path.ok());
350
351 absl::StatusOr<Data> data = MakeTestData();
352 ASSERT_TRUE(data.ok());
353
354 fs::current_path(*temp_path);
355 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
356 ASSERT_TRUE(WriteFile(kCHeader, *temp_path / "cmain.cc").ok());
357 Repo repo;
358 repo.Add("main.cc");
359 repo.Add("cmain.cc");
360 ASSERT_TRUE(repo.Commit().ok());
361
362 std::stringstream ss;
363 std::vector<absl::Status> errors =
364 LicenseChecker::Run(temp_path->string(), ss, *data);
365 EXPECT_EQ(errors.size(), 0u);
366
367 EXPECT_EQ(ss.str(), R"output(engine
368
369C Copyright Test
370--------------------------------------------------------------------------------
371engine
372
373Copyright Test
374)output");
375}
376
377TEST_F(LicenseCheckerTest, SimpleWritesDuplicateFileLicensesFiles) {
378 absl::StatusOr<fs::path> temp_path = MakeTempDir();
379 ASSERT_TRUE(temp_path.ok());
380
381 absl::StatusOr<Data> data = MakeTestData();
382 ASSERT_TRUE(data.ok());
383
384 fs::current_path(*temp_path);
385 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "a.cc").ok());
386 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "b.cc").ok());
387 Repo repo;
388 repo.Add("a.cc");
389 repo.Add("b.cc");
390 ASSERT_TRUE(repo.Commit().ok());
391
392 std::stringstream ss;
393 std::vector<absl::Status> errors =
394 LicenseChecker::Run(temp_path->string(), ss, *data);
395 EXPECT_EQ(errors.size(), 0u);
396
397 EXPECT_EQ(ss.str(), R"output(engine
398
399Copyright Test
400)output");
401}
402
403TEST_F(LicenseCheckerTest, FileLicenseMultiplePackages) {
404 absl::StatusOr<fs::path> temp_path = MakeTempDir();
405 ASSERT_TRUE(temp_path.ok());
406
407 absl::StatusOr<Data> data = MakeTestData();
408 ASSERT_TRUE(data.ok());
409
410 fs::current_path(*temp_path);
411 ASSERT_EQ(std::system("mkdir -p third_party/foobar"), 0);
412 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "a.cc").ok());
413 ASSERT_TRUE(
414 WriteFile(kHeader, *temp_path / "third_party" / "foobar" / "b.cc").ok());
415 Repo repo;
416 repo.Add("a.cc");
417 repo.Add("third_party/foobar/b.cc");
418 ASSERT_TRUE(repo.Commit().ok());
419
420 std::stringstream ss;
421 std::vector<absl::Status> errors =
422 LicenseChecker::Run(temp_path->string(), ss, *data);
423 EXPECT_EQ(errors.size(), 0u);
424
425 EXPECT_EQ(ss.str(), R"output(engine
426foobar
427
428Copyright Test
429)output");
430}
431
432TEST_F(LicenseCheckerTest, SimpleDirectoryLicense) {
433 absl::StatusOr<fs::path> temp_path = MakeTempDir();
434 ASSERT_TRUE(temp_path.ok());
435
436 absl::StatusOr<Data> data = MakeTestData();
437 ASSERT_TRUE(data.ok());
438
439 fs::current_path(*temp_path);
440 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
441 ASSERT_TRUE(WriteFile(kLicense, *temp_path / "LICENSE").ok());
442 Repo repo;
443 repo.Add("main.cc");
444 repo.Add("LICENSE");
445 ASSERT_TRUE(repo.Commit().ok());
446
447 std::stringstream ss;
448 std::vector<absl::Status> errors =
449 LicenseChecker::Run(temp_path->string(), ss, *data);
450 EXPECT_EQ(errors.size(), 0u);
451
452 EXPECT_EQ(ss.str(), R"output(engine
453
454Copyright Test
455--------------------------------------------------------------------------------
456engine
457
458Test License
459v2.0
460)output");
461}
462
463TEST_F(LicenseCheckerTest, RootDirectoryIsStrict) {
464 absl::StatusOr<fs::path> temp_path = MakeTempDir();
465 ASSERT_TRUE(temp_path.ok());
466
467 absl::StatusOr<Data> data = MakeTestData();
468 ASSERT_TRUE(data.ok());
469
470 fs::current_path(*temp_path);
471 ASSERT_EQ(std::system("echo \"Hello world!\" > main.cc"), 0);
472 ASSERT_TRUE(WriteFile(kLicense, *temp_path / "LICENSE").ok());
473 Repo repo;
474 repo.Add("main.cc");
475 repo.Add("LICENSE");
476 ASSERT_TRUE(repo.Commit().ok());
477
478 std::stringstream ss;
479 std::vector<absl::Status> errors =
480 LicenseChecker::Run(temp_path->string(), ss, *data);
481 EXPECT_EQ(errors.size(), 1u);
482
483 EXPECT_TRUE(FindError(errors, absl::StatusCode::kNotFound,
484 "Expected root copyright in.*main.cc"))
485 << (errors.size() > 0 ? absl::StrCat(errors[0]) : "");
486}
487
488TEST_F(LicenseCheckerTest, ThirdPartyDirectoryLicense) {
489 absl::StatusOr<fs::path> temp_path = MakeTempDir();
490 ASSERT_TRUE(temp_path.ok());
491
492 absl::StatusOr<Data> data = MakeTestData();
493 ASSERT_TRUE(data.ok());
494
495 fs::current_path(*temp_path);
496 ASSERT_EQ(std::system("mkdir -p third_party/foobar"), 0);
497 ASSERT_EQ(std::system("echo \"Hello world!\" > third_party/foobar/foo.cc"),
498 0);
499 ASSERT_TRUE(WriteFile(kLicense, *temp_path / "LICENSE").ok());
500 ASSERT_TRUE(
501 WriteFile(kLicense, *temp_path / "third_party" / "foobar" / "LICENSE")
502 .ok());
503 Repo repo;
504 repo.Add("LICENSE");
505 repo.Add("third_party/foobar/foo.cc");
506 repo.Add("third_party/foobar/LICENSE");
507 ASSERT_TRUE(repo.Commit().ok());
508
509 std::stringstream ss;
510 std::vector<absl::Status> errors =
511 LicenseChecker::Run(temp_path->string(), ss, *data);
512 EXPECT_EQ(errors.size(), 0u);
513
514 EXPECT_EQ(ss.str(), R"output(foobar
515
516Test License
517v2.0
518)output");
519}
520
521TEST_F(LicenseCheckerTest, OnlyPrintMatch) {
522 absl::StatusOr<fs::path> temp_path = MakeTempDir();
523 ASSERT_TRUE(temp_path.ok());
524
525 absl::StatusOr<Data> data = MakeTestData();
526 ASSERT_TRUE(data.ok());
527
528 fs::current_path(*temp_path);
529 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
530 ASSERT_TRUE(WriteFile(absl::StrCat(kLicense, "\n----------------------\n"),
531 *temp_path / "LICENSE")
532 .ok());
533 Repo repo;
534 repo.Add(*temp_path / "main.cc");
535 repo.Add(*temp_path / "LICENSE");
536 ASSERT_TRUE(repo.Commit().ok());
537
538 std::stringstream ss;
539 std::vector<absl::Status> errors =
540 LicenseChecker::Run(temp_path->string(), ss, *data);
541 EXPECT_EQ(errors.size(), 0u) << errors[0];
542
543 EXPECT_EQ(ss.str(), R"output(engine
544
545Copyright Test
546--------------------------------------------------------------------------------
547engine
548
549Test License
550v2.0
551)output");
552}
553
554TEST_F(LicenseCheckerTest, OnlyPrintMatchHeader) {
555 absl::StatusOr<fs::path> temp_path = MakeTempDir();
556 ASSERT_TRUE(temp_path.ok());
557
558 absl::StatusOr<Data> data = MakeTestData();
559 ASSERT_TRUE(data.ok());
560
561 fs::current_path(*temp_path);
562 ASSERT_TRUE(WriteFile(R"header(
563// Extra text.
564// Copyright Test
565//
566// Extra text.
567
568void main() {
569}
570)header",
571 *temp_path / "main.cc")
572 .ok());
573 Repo repo;
574 repo.Add(*temp_path / "main.cc");
575 ASSERT_TRUE(repo.Commit().ok());
576
577 std::stringstream ss;
578 std::vector<absl::Status> errors =
579 LicenseChecker::Run(temp_path->string(), ss, *data);
580 EXPECT_EQ(errors.size(), 0u) << errors[0];
581
582 EXPECT_EQ(ss.str(), R"output(engine
583
584Copyright Test
585)output");
586}
587
588TEST_F(LicenseCheckerTest, UnmatchedCommentsAsErrors) {
589 absl::StatusOr<fs::path> temp_path = MakeTempDir();
590 ASSERT_TRUE(temp_path.ok());
591
592 absl::StatusOr<Data> data = MakeTestData();
593 ASSERT_TRUE(data.ok());
594
595 fs::current_path(*temp_path);
596 ASSERT_EQ(std::system("mkdir -p third_party/foobar"), 0);
597 ASSERT_TRUE(
598 WriteFile(kUnknownHeader, *temp_path / "third_party/foobar/foo.cc").ok());
599 ASSERT_TRUE(
600 WriteFile(kLicense, *temp_path / "third_party" / "foobar" / "LICENSE")
601 .ok());
602 Repo repo;
603 repo.Add("third_party/foobar/foo.cc");
604 repo.Add("third_party/foobar/LICENSE");
605 ASSERT_TRUE(repo.Commit().ok());
606
608 std::stringstream ss;
609 std::vector<absl::Status> errors =
610 LicenseChecker::Run(temp_path->string(), ss, *data, flags);
611
612 EXPECT_EQ(errors.size(), 1u);
613 EXPECT_TRUE(
614 FindError(errors, absl::StatusCode::kNotFound,
615 "(?s).*foo.cc.*Selector didn't match.*Unknown Copyright"))
616 << (errors.size() > 0 ? absl::StrCat(errors[0]) : "");
617}
618
620 absl::StatusOr<fs::path> temp_path = MakeTempDir();
621 ASSERT_TRUE(temp_path.ok());
622
623 absl::StatusOr<Data> data = MakeTestData(/*include_filter_text=*/"NOTICES");
624 ASSERT_TRUE(data.ok());
625
626 std::string notices = R"notices(engine
627foobar
628
629Copyright Test
630--------------------------------------------------------------------------------
631engine
632
633Test License
634v2.0
635)notices";
636
637 fs::current_path(*temp_path);
638 ASSERT_TRUE(WriteFile(notices, "NOTICES").ok());
639 Repo repo;
640 repo.Add("NOTICES");
641 ASSERT_TRUE(repo.Commit().ok());
642
643 std::stringstream ss;
644 std::vector<absl::Status> errors =
645 LicenseChecker::Run(temp_path->string(), ss, *data);
646 EXPECT_EQ(errors.size(), 0u) << errors[0];
647
648 EXPECT_EQ(ss.str(), notices);
649}
650
651TEST_F(LicenseCheckerTest, NoticesFileUnknownLicense) {
652 absl::StatusOr<fs::path> temp_path = MakeTempDir();
653 ASSERT_TRUE(temp_path.ok());
654
655 absl::StatusOr<Data> data = MakeTestData(/*include_filter_text=*/"NOTICES");
656 ASSERT_TRUE(data.ok());
657
658 std::string notices = R"notices(engine
659foobar
660
661Copyright Test
662--------------------------------------------------------------------------------
663engine
664
665Unknown license
666)notices";
667
668 fs::current_path(*temp_path);
669 ASSERT_TRUE(WriteFile(notices, "NOTICES").ok());
670 Repo repo;
671 repo.Add("NOTICES");
672 ASSERT_TRUE(repo.Commit().ok());
673
674 std::stringstream ss;
676 std::vector<absl::Status> errors =
677 LicenseChecker::Run(temp_path->string(), ss, *data, flags);
678 EXPECT_EQ(errors.size(), 1u);
679 ASSERT_TRUE(!errors.empty());
680 EXPECT_TRUE(FindError(errors, absl::StatusCode::kNotFound, "NOTICES"))
681 << errors[0];
682}
683
684TEST_F(LicenseCheckerTest, CipdDependencyParentDir) {
685 absl::StatusOr<fs::path> temp_path = MakeTempDir();
686 ASSERT_TRUE(temp_path.ok());
687
688 absl::StatusOr<Data> data = MakeTestData();
689 ASSERT_TRUE(data.ok());
690
691 fs::current_path(*temp_path);
692
693 const char* deps_file = R"deps(
694deps = {
695 'child/third_party/foobar': {
696 'dep_type': 'cipd',
697 'packages': [{'package': 'flutter/testing/foobar', 'version': '1.0.0'}],
698 },
699}
700)deps";
701 ASSERT_TRUE(WriteFile(deps_file, "DEPS").ok());
702
703 fs::create_directories("child/third_party/foobar");
704 ASSERT_TRUE(WriteFile(kHeader, "child/third_party/foobar/foobar.cc").ok());
705
706 Repo repo;
707 repo.Add("DEPS");
708 ASSERT_TRUE(repo.Commit().ok());
709
710 fs::current_path(*temp_path / "child");
711 std::stringstream ss;
712 std::vector<absl::Status> errors = LicenseChecker::Run(".", ss, *data);
713 EXPECT_EQ(errors.size(), 0u) << (errors.empty() ? "" : errors[0].message());
714
715 EXPECT_EQ(ss.str(), R"output(foobar
716
717Copyright Test
718)output");
719}
720
721TEST_F(LicenseCheckerTest, CipdDependency) {
722 absl::StatusOr<fs::path> temp_path = MakeTempDir();
723 ASSERT_TRUE(temp_path.ok());
724
725 absl::StatusOr<Data> data = MakeTestData();
726 ASSERT_TRUE(data.ok());
727
728 fs::current_path(*temp_path);
729
730 const char* deps_file = R"deps(
731deps = {
732 'third_party/foobar': {
733 'dep_type': 'cipd',
734 'packages': [{'package': 'flutter/testing/foobar', 'version': '1.0.0'}],
735 },
736}
737)deps";
738 ASSERT_TRUE(WriteFile(deps_file, "DEPS").ok());
739
740 fs::create_directories("third_party/foobar");
741 ASSERT_TRUE(WriteFile(kHeader, "third_party/foobar/foobar.cc").ok());
742
743 Repo repo;
744 repo.Add("DEPS");
745 ASSERT_TRUE(repo.Commit().ok());
746
747 std::stringstream ss;
748 std::vector<absl::Status> errors =
749 LicenseChecker::Run(temp_path->string(), ss, *data);
750 EXPECT_EQ(errors.size(), 0u) << (errors.empty() ? "" : errors[0].message());
751
752 EXPECT_EQ(ss.str(), R"output(foobar
753
754Copyright Test
755)output");
756}
757
759 absl::StatusOr<fs::path> temp_path = MakeTempDir();
760 ASSERT_TRUE(temp_path.ok());
761
762 absl::StatusOr<Data> data = MakeTestData();
763 ASSERT_TRUE(data.ok());
764
765 fs::current_path(*temp_path);
766 fs::create_directories("engine/third_party/foobar");
767 fs::create_directories("secondary/third_party/foobar");
768 ASSERT_TRUE(WriteFile(kHeader, "engine/third_party/foobar/foobar.cc").ok());
769 ASSERT_TRUE(
770 WriteFile(kLicense, "secondary/third_party/foobar/license.txt").ok());
771
772 data->secondary_dir = *temp_path / "secondary";
773
774 fs::current_path(*temp_path / "engine");
775 Repo repo;
776 repo.Add("third_party/foobar/foobar.cc");
777 ASSERT_TRUE(repo.Commit().ok());
778
779 std::stringstream ss;
780 std::vector<absl::Status> errors =
781 LicenseChecker::Run((*temp_path / "engine").string(), ss, *data);
782 EXPECT_EQ(errors.size(), 0u) << errors[0];
783
784 EXPECT_EQ(ss.str(), R"notices(foobar
785
786Copyright Test
787--------------------------------------------------------------------------------
788foobar
789
790Test License
791v2.0
792
793)notices");
794}
795
796TEST_F(LicenseCheckerTest, WorkingDirectoryTrailingSlash) {
797 absl::StatusOr<fs::path> temp_path = MakeTempDir();
798 ASSERT_TRUE(temp_path.ok());
799
800 absl::StatusOr<Data> data = MakeTestData();
801 ASSERT_TRUE(data.ok());
802
803 fs::current_path(*temp_path);
804 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
805 ASSERT_TRUE(WriteFile(kLicense, *temp_path / "LICENSE").ok());
806 Repo repo;
807 repo.Add("main.cc");
808 repo.Add("LICENSE");
809 ASSERT_TRUE(repo.Commit().ok());
810
811 std::stringstream ss;
812 std::string working_dir = temp_path->string() + "/";
813 std::vector<absl::Status> errors =
814 LicenseChecker::Run(working_dir, ss, *data);
815 EXPECT_EQ(errors.size(), 0u) << (errors.empty() ? "" : errors[0].message());
816
817 EXPECT_EQ(ss.str(), R"output(engine
818
819Copyright Test
820--------------------------------------------------------------------------------
821engine
822
823Test License
824v2.0
825)output");
826}
827
828TEST_F(LicenseCheckerTest, HandlesTxtFiles) {
829 absl::StatusOr<fs::path> temp_path = MakeTempDir();
830 ASSERT_TRUE(temp_path.ok());
831
832 absl::StatusOr<Data> data = MakeTestData(/*include_filter_text=*/".*txt");
833 ASSERT_TRUE(data.ok());
834
835 fs::current_path(*temp_path);
836
837 ASSERT_TRUE(WriteFile(R"lic(Test License
838v2.0
839)lic",
840 *temp_path / "foobar.txt")
841 .ok());
842 Repo repo;
843 repo.Add("foobar.txt");
844 ASSERT_TRUE(repo.Commit().ok());
845
846 std::stringstream ss;
847 std::vector<absl::Status> errors =
848 LicenseChecker::Run(temp_path->string(), ss, *data);
849 EXPECT_EQ(errors.size(), 0u) << errors[0];
850
851 EXPECT_EQ(ss.str(), R"output(engine
852
853Test License
854v2.0
855)output");
856}
857
859 absl::StatusOr<fs::path> temp_path = MakeTempDir();
860 ASSERT_TRUE(temp_path.ok());
861
862 absl::StatusOr<Data> data = MakeTestData();
863 ASSERT_TRUE(data.ok());
864
865 fs::current_path(*temp_path);
866 fs::create_directories("third_party/vulkan-deps");
867 fs::create_directories("third_party/vulkan-deps/foobar");
868
869 ASSERT_TRUE(
870 WriteFile(kLicense, *temp_path / "third_party/vulkan-deps/foobar/LICENSE")
871 .ok());
872 ASSERT_TRUE(WriteFile(kHeader,
873 *temp_path / "third_party/vulkan-deps/foobar/foobar.cc")
874 .ok());
875
876 Repo repo;
877 repo.Add(*temp_path / "third_party/vulkan-deps/foobar/LICENSE");
878 repo.Add(*temp_path / "third_party/vulkan-deps/foobar/foobar.cc");
879 ASSERT_TRUE(repo.Commit().ok());
880
881 std::stringstream ss;
882 std::vector<absl::Status> errors =
883 LicenseChecker::Run(temp_path->string(), ss, *data);
884 EXPECT_EQ(errors.size(), 0u) << errors[0];
885
886 EXPECT_EQ(ss.str(), R"output(foobar
887
888Copyright Test
889--------------------------------------------------------------------------------
890foobar
891
892Test License
893v2.0
894)output");
895}
896
897TEST_F(LicenseCheckerTest, IgnoredDirHasContent) {
898 absl::StatusOr<fs::path> temp_path = MakeTempDir();
899 ASSERT_TRUE(temp_path.ok());
900
901 absl::StatusOr<Data> data = MakeTestData();
902 ASSERT_TRUE(data.ok());
903
904 fs::current_path(*temp_path);
905 fs::create_directories("third_party/vulkan-deps");
906 fs::create_directories("third_party/vulkan-deps/foobar");
907
908 ASSERT_TRUE(
909 WriteFile(kLicense, *temp_path / "third_party/vulkan-deps/LICENSE").ok());
910 ASSERT_TRUE(
911 WriteFile(kHeader, *temp_path / "third_party/vulkan-deps/foobar.cc")
912 .ok());
913
914 Repo repo;
915 repo.Add(*temp_path / "third_party/vulkan-deps/LICENSE");
916 repo.Add(*temp_path / "third_party/vulkan-deps/foobar.cc");
917 ASSERT_TRUE(repo.Commit().ok());
918
919 std::stringstream ss;
920 std::vector<absl::Status> errors =
921 LicenseChecker::Run(temp_path->string(), ss, *data);
922 EXPECT_EQ(errors.size(), 0u) << errors[0];
923
924 EXPECT_EQ(ss.str(), R"output(vulkan-deps
925
926Copyright Test
927--------------------------------------------------------------------------------
928vulkan-deps
929
930Test License
931v2.0
932)output");
933}
934
935TEST_F(LicenseCheckerTest, DoubleLicenseFiles) {
936 absl::StatusOr<fs::path> temp_path = MakeTempDir();
937 ASSERT_TRUE(temp_path.ok());
938
939 absl::StatusOr<Data> data =
940 MakeTestData(/*include_filter_text=*/".*/COPYING|.*cc");
941 ASSERT_TRUE(data.ok());
942
943 fs::current_path(*temp_path);
944 fs::create_directories("third_party/foobar");
945
946 ASSERT_TRUE(WriteFile(R"lic(Test License
947v2.0
948)lic",
949 *temp_path / "third_party/foobar/LICENSE")
950 .ok());
951 ASSERT_TRUE(WriteFile(R"lic(Test License
952v3.0
953)lic",
954 *temp_path / "third_party/foobar/COPYING")
955 .ok());
956 ASSERT_TRUE(WriteFile(kHeader, "third_party/foobar/foobar.cc").ok());
957 Repo repo;
958 repo.Add("third_party/foobar/COPYING");
959 repo.Add("third_party/foobar/LICENSE");
960 repo.Add("third_party/foobar/foobar.cc");
961 ASSERT_TRUE(repo.Commit().ok());
962
963 std::stringstream ss;
964 std::vector<absl::Status> errors =
965 LicenseChecker::Run(temp_path->string(), ss, *data);
966 EXPECT_EQ(errors.size(), 0u) << errors[0];
967
968 EXPECT_EQ(ss.str(), R"output(foobar
969
970Copyright Test
971--------------------------------------------------------------------------------
972foobar
973
974Test License
975v2.0
976--------------------------------------------------------------------------------
977foobar
978
979Test License
980v3.0
981)output");
982}
983
984TEST_F(LicenseCheckerTest, OverrideRootPackageName) {
985 absl::StatusOr<fs::path> temp_path = MakeTempDir();
986 ASSERT_TRUE(temp_path.ok());
987
988 absl::StatusOr<Data> data = MakeTestData();
989 ASSERT_TRUE(data.ok());
990
991 fs::current_path(*temp_path);
992 ASSERT_TRUE(WriteFile(kHeader, *temp_path / "main.cc").ok());
993 Repo repo;
994 repo.Add(*temp_path / "main.cc");
995 ASSERT_TRUE(repo.Commit().ok());
996
997 LicenseChecker::Flags flags = {.root_package_name = "testroot"};
998 std::stringstream ss;
999 std::vector<absl::Status> errors =
1000 LicenseChecker::Run(temp_path->string(), ss, *data, flags);
1001 EXPECT_EQ(errors.size(), 0u) << errors[0];
1002
1003 EXPECT_EQ(ss.str(), R"output(testroot
1004
1005Copyright Test
1006)output");
1007}
static absl::StatusOr< Catalog > Make(const std::vector< Entry > &entries)
Make a Catalog for testing.
Definition catalog.cc:151
static absl::StatusOr< Filter > Open(std::string_view path)
Definition filter.cc:9
static std::vector< absl::Status > Run(std::string_view working_dir, std::ostream &licenses, const Data &data)
absl::StatusOr< fs::path > MakeTempDir()
TEST_F(LicenseCheckerTest, SimplePass)
bool WriteFile(const std::string &path, const char *data, ssize_t size)
Definition files.cc:69
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switch_defs.h:52
Definition data.h:17
Filter include_filter
Definition data.h:19
std::optional< std::string > root_package_name
std::shared_ptr< const fml::Mapping > data