1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file.
4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <vector>
6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "tools/gn/config.h"
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "tools/gn/header_checker.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "tools/gn/scheduler.h"
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "tools/gn/target.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "tools/gn/test_with_scope.h"
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace {
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass HeaderCheckerTest : public testing::Test {
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  HeaderCheckerTest()
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : a_(setup_.settings(), Label(SourceDir("//a/"), "a")),
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        b_(setup_.settings(), Label(SourceDir("//b/"), "b")),
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        c_(setup_.settings(), Label(SourceDir("//c/"), "c")),
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        d_(setup_.settings(), Label(SourceDir("//d/"), "d")) {
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    a_.set_output_type(Target::SOURCE_SET);
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    b_.set_output_type(Target::SOURCE_SET);
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    c_.set_output_type(Target::SOURCE_SET);
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    d_.set_output_type(Target::SOURCE_SET);
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Err err;
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    a_.SetToolchain(setup_.toolchain(), &err);
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    b_.SetToolchain(setup_.toolchain(), &err);
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    c_.SetToolchain(setup_.toolchain(), &err);
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    d_.SetToolchain(setup_.toolchain(), &err);
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    a_.public_deps().push_back(LabelTargetPair(&b_));
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    b_.public_deps().push_back(LabelTargetPair(&c_));
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // Start with all public visibility.
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    a_.visibility().SetPublic();
39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    b_.visibility().SetPublic();
40a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    c_.visibility().SetPublic();
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    d_.visibility().SetPublic();
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    d_.OnResolved(&err);
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    c_.OnResolved(&err);
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    b_.OnResolved(&err);
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    a_.OnResolved(&err);
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    targets_.push_back(&a_);
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    targets_.push_back(&b_);
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    targets_.push_back(&c_);
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    targets_.push_back(&d_);
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch protected:
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Scheduler scheduler_;
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  TestWithScope setup_;
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Some headers that are automatically set up with a public dependency chain.
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // a -> b -> c. D is unconnected.
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Target a_;
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Target b_;
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Target c_;
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Target d_;
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<const Target*> targets_;
67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(HeaderCheckerTest, IsDependencyOf) {
72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<HeaderChecker> checker(
73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new HeaderChecker(setup_.build_settings(), targets_));
74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Add a target P ("private") that privately depends on C, and hook up the
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // chain so that A -> P -> C. A will depend on C via two different paths.
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Target p(setup_.settings(), Label(SourceDir("//p/"), "p"));
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  p.set_output_type(Target::SOURCE_SET);
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  p.SetToolchain(setup_.toolchain(), &err);
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(err.has_error());
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  p.private_deps().push_back(LabelTargetPair(&c_));
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  p.visibility().SetPublic();
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  p.OnResolved(&err);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  a_.public_deps().push_back(LabelTargetPair(&p));
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A does not depend on itself.
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_permitted = false;
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HeaderChecker::Chain chain;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, &chain, &is_permitted));
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A depends publicly on B.
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chain.clear();
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  is_permitted = false;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, &chain, &is_permitted));
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(2u, chain.size());
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&b_, true), chain[0]);
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[1]);
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(is_permitted);
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A indirectly depends on C. The "public" dependency path through B should
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // be identified.
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chain.clear();
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  is_permitted = false;
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_permitted));
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_EQ(3u, chain.size());
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&c_, true), chain[0]);
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&b_, true), chain[1]);
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[2]);
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(is_permitted);
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // C does not depend on A.
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chain.clear();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  is_permitted = false;
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, &chain, &is_permitted));
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(chain.empty());
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(is_permitted);
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Remove the B -> C public dependency, leaving P's private dep on C the only
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // path from A to C. This should now be found.
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  chain.clear();
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(&c_, b_.public_deps()[0].ptr);  // Validate it's the right one.
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  b_.public_deps().erase(b_.public_deps().begin());
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_permitted));
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(3u, chain.size());
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&c_, false), chain[0]);
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&p, true), chain[1]);
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[2]);
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(is_permitted);
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // P privately depends on C. That dependency should be OK since it's only
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // one hop.
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  chain.clear();
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  is_permitted = false;
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->IsDependencyOf(&c_, &p, &chain, &is_permitted));
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(2u, chain.size());
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&c_, false), chain[0]);
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&p, true), chain[1]);
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(is_permitted);
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(HeaderCheckerTest, CheckInclude) {
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  InputFile input_file(SourceFile("//some_file.cc"));
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  input_file.SetContents(std::string());
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  LocationRange range;  // Dummy value.
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Add a disconnected target d with a header to check that you have to have
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // to depend on a target listing a header.
150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SourceFile d_header("//d_header.h");
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  d_.sources().push_back(SourceFile(d_header));
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Add a header on B and say everything in B is public.
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SourceFile b_public("//b_public.h");
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  b_.sources().push_back(b_public);
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  c_.set_all_headers_public(true);
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Add a public and private header on C.
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SourceFile c_public("//c_public.h");
160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SourceFile c_private("//c_private.h");
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  c_.sources().push_back(c_private);
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  c_.public_headers().push_back(c_public);
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  c_.set_all_headers_public(false);
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<HeaderChecker> checker(
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      new HeaderChecker(setup_.build_settings(), targets_));
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // A file in target A can't include a header from D because A has no
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // dependency on D.
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Err err;
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_FALSE(checker->CheckInclude(&a_, input_file, d_header, range, &err));
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(err.has_error());
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // A can include the public header in B.
175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  err = Err();
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_TRUE(checker->CheckInclude(&a_, input_file, b_public, range, &err));
177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(err.has_error());
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Check A depending on the public and private headers in C.
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  err = Err();
181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_TRUE(checker->CheckInclude(&a_, input_file, c_public, range, &err));
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(err.has_error());
183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_FALSE(checker->CheckInclude(&a_, input_file, c_private, range, &err));
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(err.has_error());
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // A can depend on a random file unknown to the build.
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  err = Err();
188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_TRUE(checker->CheckInclude(&a_, input_file, SourceFile("//random.h"),
189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                    range, &err));
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(err.has_error());
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// A public chain of dependencies should always be identified first, even if
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// it is longer than a private one.
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(HeaderCheckerTest, PublicFirst) {
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now make a A -> Z -> D private dependency chain (one shorter than the
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // public one to get to D).
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Target z(setup_.settings(), Label(SourceDir("//a/"), "a"));
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  z.set_output_type(Target::SOURCE_SET);
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(z.SetToolchain(setup_.toolchain(), &err));
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  z.private_deps().push_back(LabelTargetPair(&d_));
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(z.OnResolved(&err));
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  targets_.push_back(&z);
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  a_.private_deps().push_back(LabelTargetPair(&z));
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Check that D can be found from A, but since it's private, it will be
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // marked as not permitted.
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_permitted = false;
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HeaderChecker::Chain chain;
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<HeaderChecker> checker(
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HeaderChecker(setup_.build_settings(), targets_));
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->IsDependencyOf(&d_, &a_, &chain, &is_permitted));
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(is_permitted);
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(3u, chain.size());
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&d_, false), chain[0]);
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&z, false), chain[1]);
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[2]);
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Hook up D to the existing public A -> B -> C chain to make a long one, and
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // search for D again.
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  c_.public_deps().push_back(LabelTargetPair(&d_));
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  checker = new HeaderChecker(setup_.build_settings(), targets_);
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  chain.clear();
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->IsDependencyOf(&d_, &a_, &chain, &is_permitted));
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This should have found the long public one.
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(is_permitted);
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(4u, chain.size());
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&d_, true), chain[0]);
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&c_, true), chain[1]);
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&b_, true), chain[2]);
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[3]);
236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Checks that the allow_circular_includes_from list works.
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(HeaderCheckerTest, CheckIncludeAllowCircular) {
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  InputFile input_file(SourceFile("//some_file.cc"));
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  input_file.SetContents(std::string());
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LocationRange range;  // Dummy value.
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Add an include file to A.
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SourceFile a_public("//a_public.h");
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  a_.sources().push_back(a_public);
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<HeaderChecker> checker(
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HeaderChecker(setup_.build_settings(), targets_));
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A depends on B. So B normally can't include headers from A.
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(checker->CheckInclude(&b_, input_file, a_public, range, &err));
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(err.has_error());
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Add an allow_circular_includes_from on A that lists B.
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  a_.allow_circular_includes_from().insert(b_.label());
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now the include from B to A should be allowed.
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  err = Err();
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(checker->CheckInclude(&b_, input_file, a_public, range, &err));
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(err.has_error());
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
264