• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "gn/functions.h"
6 #include "gn/rust_tool.h"
7 #include "gn/scheduler.h"
8 #include "gn/test_with_scheduler.h"
9 #include "gn/test_with_scope.h"
10 #include "util/test/test.h"
11 
12 using FunctionToolchain = TestWithScheduler;
13 
TEST_F(FunctionToolchain,NoArguments)14 TEST_F(FunctionToolchain, NoArguments) {
15   TestWithScope setup;
16 
17   // Check that creating a toolchain with no name reports an error.
18   {
19     TestParseInput input(R"(toolchain() {})");
20     ASSERT_FALSE(input.has_error());
21 
22     Err err;
23     input.parsed()->Execute(setup.scope(), &err);
24     ASSERT_TRUE(err.has_error()) << err.message();
25   }
26 
27   // Check that creating a toolchain with too many arguments is an error.
28   {
29     TestParseInput input(R"(toolchain("too", "many", "arguments") {})");
30     ASSERT_FALSE(input.has_error());
31 
32     Err err;
33     input.parsed()->Execute(setup.scope(), &err);
34     ASSERT_TRUE(err.has_error()) << err.message();
35   }
36 }
37 
TEST_F(FunctionToolchain,RuntimeOutputs)38 TEST_F(FunctionToolchain, RuntimeOutputs) {
39   TestWithScope setup;
40 
41   // These runtime outputs are a subset of the outputs so are OK.
42   {
43     TestParseInput input(
44         R"(toolchain("good") {
45           tool("link") {
46             command = "link"
47             outputs = [ "foo" ]
48             runtime_outputs = [ "foo" ]
49           }
50         })");
51     ASSERT_FALSE(input.has_error());
52 
53     Err err;
54     input.parsed()->Execute(setup.scope(), &err);
55     ASSERT_FALSE(err.has_error()) << err.message();
56 
57     // It should have generated a toolchain.
58     ASSERT_EQ(1u, setup.items().size());
59     const Toolchain* toolchain = setup.items()[0]->AsToolchain();
60     ASSERT_TRUE(toolchain);
61 
62     // The toolchain should have a link tool with the two outputs.
63     const Tool* link = toolchain->GetTool(CTool::kCToolLink);
64     ASSERT_TRUE(link);
65     ASSERT_EQ(1u, link->outputs().list().size());
66     EXPECT_EQ("foo", link->outputs().list()[0].AsString());
67     ASSERT_EQ(1u, link->runtime_outputs().list().size());
68     EXPECT_EQ("foo", link->runtime_outputs().list()[0].AsString());
69   }
70 
71   // This one is not a subset so should throw an error.
72   {
73     TestParseInput input(
74         R"(toolchain("bad") {
75           tool("link") {
76             outputs = [ "foo" ]
77             runtime_outputs = [ "bar" ]
78           }
79         })");
80     ASSERT_FALSE(input.has_error());
81 
82     Err err;
83     input.parsed()->Execute(setup.scope(), &err);
84     ASSERT_TRUE(err.has_error()) << err.message();
85   }
86 }
87 
TEST_F(FunctionToolchain,Rust)88 TEST_F(FunctionToolchain, Rust) {
89   TestWithScope setup;
90 
91   // These runtime outputs are a subset of the outputs so are OK.
92   {
93     TestParseInput input(
94         R"(toolchain("rust") {
95           tool("rust_bin") {
96             command = "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin {{rustflags}} -o {{output}} {{externs}} {{source}}"
97             description = "RUST {{output}}"
98           }
99         })");
100     ASSERT_FALSE(input.has_error());
101 
102     Err err;
103     input.parsed()->Execute(setup.scope(), &err);
104     ASSERT_FALSE(err.has_error()) << err.message();
105 
106     // It should have generated a toolchain.
107     ASSERT_EQ(1u, setup.items().size());
108     const Toolchain* toolchain = setup.items()[0]->AsToolchain();
109     ASSERT_TRUE(toolchain);
110 
111     const Tool* rust = toolchain->GetTool(RustTool::kRsToolBin);
112     ASSERT_TRUE(rust);
113     ASSERT_EQ(rust->command().AsString(),
114               "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin "
115               "{{rustflags}} -o {{output}} {{externs}} {{source}}");
116     ASSERT_EQ(rust->description().AsString(), "RUST {{output}}");
117   }
118 }
119 
TEST_F(FunctionToolchain,Command)120 TEST_F(FunctionToolchain, Command) {
121   TestWithScope setup;
122 
123   TestParseInput input(
124       R"(toolchain("missing_command") {
125         tool("cxx") {}
126       })");
127   ASSERT_FALSE(input.has_error());
128 
129   Err err;
130   input.parsed()->Execute(setup.scope(), &err);
131   ASSERT_TRUE(err.has_error()) << err.message();
132 }
133 
TEST_F(FunctionToolchain,CommandLauncher)134 TEST_F(FunctionToolchain, CommandLauncher) {
135   TestWithScope setup;
136 
137   TestParseInput input(
138       R"(toolchain("good") {
139         tool("cxx") {
140           command = "cxx"
141           command_launcher = "/usr/goma/gomacc"
142         }
143       })");
144   ASSERT_FALSE(input.has_error());
145 
146   Err err;
147   input.parsed()->Execute(setup.scope(), &err);
148   ASSERT_FALSE(err.has_error()) << err.message();
149 
150   // It should have generated a toolchain.
151   ASSERT_EQ(1u, setup.items().size());
152   const Toolchain* toolchain = setup.items()[0]->AsToolchain();
153   ASSERT_TRUE(toolchain);
154 
155   // The toolchain should have a link tool with the two outputs.
156   const Tool* link = toolchain->GetTool(CTool::kCToolCxx);
157   ASSERT_TRUE(link);
158   EXPECT_EQ("/usr/goma/gomacc", link->command_launcher());
159 }
160