16d528ed9Sopenharmony_ci// Copyright 2016 The Chromium Authors. All rights reserved. 26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 36d528ed9Sopenharmony_ci// found in the LICENSE file. 46d528ed9Sopenharmony_ci 56d528ed9Sopenharmony_ci#include "gn/functions.h" 66d528ed9Sopenharmony_ci#include "gn/rust_tool.h" 76d528ed9Sopenharmony_ci#include "gn/scheduler.h" 86d528ed9Sopenharmony_ci#include "gn/test_with_scheduler.h" 96d528ed9Sopenharmony_ci#include "gn/test_with_scope.h" 106d528ed9Sopenharmony_ci#include "util/test/test.h" 116d528ed9Sopenharmony_ci 126d528ed9Sopenharmony_ciusing FunctionToolchain = TestWithScheduler; 136d528ed9Sopenharmony_ci 146d528ed9Sopenharmony_ciTEST_F(FunctionToolchain, NoArguments) { 156d528ed9Sopenharmony_ci TestWithScope setup; 166d528ed9Sopenharmony_ci 176d528ed9Sopenharmony_ci // Check that creating a toolchain with no name reports an error. 186d528ed9Sopenharmony_ci { 196d528ed9Sopenharmony_ci TestParseInput input(R"(toolchain() {})"); 206d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 216d528ed9Sopenharmony_ci 226d528ed9Sopenharmony_ci Err err; 236d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 246d528ed9Sopenharmony_ci ASSERT_TRUE(err.has_error()) << err.message(); 256d528ed9Sopenharmony_ci } 266d528ed9Sopenharmony_ci 276d528ed9Sopenharmony_ci // Check that creating a toolchain with too many arguments is an error. 286d528ed9Sopenharmony_ci { 296d528ed9Sopenharmony_ci TestParseInput input(R"(toolchain("too", "many", "arguments") {})"); 306d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 316d528ed9Sopenharmony_ci 326d528ed9Sopenharmony_ci Err err; 336d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 346d528ed9Sopenharmony_ci ASSERT_TRUE(err.has_error()) << err.message(); 356d528ed9Sopenharmony_ci } 366d528ed9Sopenharmony_ci} 376d528ed9Sopenharmony_ci 386d528ed9Sopenharmony_ciTEST_F(FunctionToolchain, RuntimeOutputs) { 396d528ed9Sopenharmony_ci TestWithScope setup; 406d528ed9Sopenharmony_ci 416d528ed9Sopenharmony_ci // These runtime outputs are a subset of the outputs so are OK. 426d528ed9Sopenharmony_ci { 436d528ed9Sopenharmony_ci TestParseInput input( 446d528ed9Sopenharmony_ci R"(toolchain("good") { 456d528ed9Sopenharmony_ci tool("link") { 466d528ed9Sopenharmony_ci command = "link" 476d528ed9Sopenharmony_ci outputs = [ "foo" ] 486d528ed9Sopenharmony_ci runtime_outputs = [ "foo" ] 496d528ed9Sopenharmony_ci } 506d528ed9Sopenharmony_ci })"); 516d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 526d528ed9Sopenharmony_ci 536d528ed9Sopenharmony_ci Err err; 546d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 556d528ed9Sopenharmony_ci ASSERT_FALSE(err.has_error()) << err.message(); 566d528ed9Sopenharmony_ci 576d528ed9Sopenharmony_ci // It should have generated a toolchain. 586d528ed9Sopenharmony_ci ASSERT_EQ(1u, setup.items().size()); 596d528ed9Sopenharmony_ci const Toolchain* toolchain = setup.items()[0]->AsToolchain(); 606d528ed9Sopenharmony_ci ASSERT_TRUE(toolchain); 616d528ed9Sopenharmony_ci 626d528ed9Sopenharmony_ci // The toolchain should have a link tool with the two outputs. 636d528ed9Sopenharmony_ci const Tool* link = toolchain->GetTool(CTool::kCToolLink); 646d528ed9Sopenharmony_ci ASSERT_TRUE(link); 656d528ed9Sopenharmony_ci ASSERT_EQ(1u, link->outputs().list().size()); 666d528ed9Sopenharmony_ci EXPECT_EQ("foo", link->outputs().list()[0].AsString()); 676d528ed9Sopenharmony_ci ASSERT_EQ(1u, link->runtime_outputs().list().size()); 686d528ed9Sopenharmony_ci EXPECT_EQ("foo", link->runtime_outputs().list()[0].AsString()); 696d528ed9Sopenharmony_ci } 706d528ed9Sopenharmony_ci 716d528ed9Sopenharmony_ci // This one is not a subset so should throw an error. 726d528ed9Sopenharmony_ci { 736d528ed9Sopenharmony_ci TestParseInput input( 746d528ed9Sopenharmony_ci R"(toolchain("bad") { 756d528ed9Sopenharmony_ci tool("link") { 766d528ed9Sopenharmony_ci outputs = [ "foo" ] 776d528ed9Sopenharmony_ci runtime_outputs = [ "bar" ] 786d528ed9Sopenharmony_ci } 796d528ed9Sopenharmony_ci })"); 806d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 816d528ed9Sopenharmony_ci 826d528ed9Sopenharmony_ci Err err; 836d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 846d528ed9Sopenharmony_ci ASSERT_TRUE(err.has_error()) << err.message(); 856d528ed9Sopenharmony_ci } 866d528ed9Sopenharmony_ci} 876d528ed9Sopenharmony_ci 886d528ed9Sopenharmony_ciTEST_F(FunctionToolchain, Rust) { 896d528ed9Sopenharmony_ci TestWithScope setup; 906d528ed9Sopenharmony_ci 916d528ed9Sopenharmony_ci // These runtime outputs are a subset of the outputs so are OK. 926d528ed9Sopenharmony_ci { 936d528ed9Sopenharmony_ci TestParseInput input( 946d528ed9Sopenharmony_ci R"(toolchain("rust") { 956d528ed9Sopenharmony_ci tool("rust_bin") { 966d528ed9Sopenharmony_ci command = "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin {{rustflags}} -o {{output}} {{externs}} {{source}}" 976d528ed9Sopenharmony_ci description = "RUST {{output}}" 986d528ed9Sopenharmony_ci } 996d528ed9Sopenharmony_ci })"); 1006d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 1016d528ed9Sopenharmony_ci 1026d528ed9Sopenharmony_ci Err err; 1036d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 1046d528ed9Sopenharmony_ci ASSERT_FALSE(err.has_error()) << err.message(); 1056d528ed9Sopenharmony_ci 1066d528ed9Sopenharmony_ci // It should have generated a toolchain. 1076d528ed9Sopenharmony_ci ASSERT_EQ(1u, setup.items().size()); 1086d528ed9Sopenharmony_ci const Toolchain* toolchain = setup.items()[0]->AsToolchain(); 1096d528ed9Sopenharmony_ci ASSERT_TRUE(toolchain); 1106d528ed9Sopenharmony_ci 1116d528ed9Sopenharmony_ci const Tool* rust = toolchain->GetTool(RustTool::kRsToolBin); 1126d528ed9Sopenharmony_ci ASSERT_TRUE(rust); 1136d528ed9Sopenharmony_ci ASSERT_EQ(rust->command().AsString(), 1146d528ed9Sopenharmony_ci "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin " 1156d528ed9Sopenharmony_ci "{{rustflags}} -o {{output}} {{externs}} {{source}}"); 1166d528ed9Sopenharmony_ci ASSERT_EQ(rust->description().AsString(), "RUST {{output}}"); 1176d528ed9Sopenharmony_ci } 1186d528ed9Sopenharmony_ci} 1196d528ed9Sopenharmony_ci 1206d528ed9Sopenharmony_ciTEST_F(FunctionToolchain, Command) { 1216d528ed9Sopenharmony_ci TestWithScope setup; 1226d528ed9Sopenharmony_ci 1236d528ed9Sopenharmony_ci TestParseInput input( 1246d528ed9Sopenharmony_ci R"(toolchain("missing_command") { 1256d528ed9Sopenharmony_ci tool("cxx") {} 1266d528ed9Sopenharmony_ci })"); 1276d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 1286d528ed9Sopenharmony_ci 1296d528ed9Sopenharmony_ci Err err; 1306d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 1316d528ed9Sopenharmony_ci ASSERT_TRUE(err.has_error()) << err.message(); 1326d528ed9Sopenharmony_ci} 1336d528ed9Sopenharmony_ci 1346d528ed9Sopenharmony_ciTEST_F(FunctionToolchain, CommandLauncher) { 1356d528ed9Sopenharmony_ci TestWithScope setup; 1366d528ed9Sopenharmony_ci 1376d528ed9Sopenharmony_ci TestParseInput input( 1386d528ed9Sopenharmony_ci R"(toolchain("good") { 1396d528ed9Sopenharmony_ci tool("cxx") { 1406d528ed9Sopenharmony_ci command = "cxx" 1416d528ed9Sopenharmony_ci command_launcher = "/usr/goma/gomacc" 1426d528ed9Sopenharmony_ci } 1436d528ed9Sopenharmony_ci })"); 1446d528ed9Sopenharmony_ci ASSERT_FALSE(input.has_error()); 1456d528ed9Sopenharmony_ci 1466d528ed9Sopenharmony_ci Err err; 1476d528ed9Sopenharmony_ci input.parsed()->Execute(setup.scope(), &err); 1486d528ed9Sopenharmony_ci ASSERT_FALSE(err.has_error()) << err.message(); 1496d528ed9Sopenharmony_ci 1506d528ed9Sopenharmony_ci // It should have generated a toolchain. 1516d528ed9Sopenharmony_ci ASSERT_EQ(1u, setup.items().size()); 1526d528ed9Sopenharmony_ci const Toolchain* toolchain = setup.items()[0]->AsToolchain(); 1536d528ed9Sopenharmony_ci ASSERT_TRUE(toolchain); 1546d528ed9Sopenharmony_ci 1556d528ed9Sopenharmony_ci // The toolchain should have a link tool with the two outputs. 1566d528ed9Sopenharmony_ci const Tool* link = toolchain->GetTool(CTool::kCToolCxx); 1576d528ed9Sopenharmony_ci ASSERT_TRUE(link); 1586d528ed9Sopenharmony_ci EXPECT_EQ("/usr/goma/gomacc", link->command_launcher()); 1596d528ed9Sopenharmony_ci} 160