1 // Copyright 2018 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/setup.h" 6 7 #include "base/command_line.h" 8 #include "base/files/file_path.h" 9 #include "base/files/file_util.h" 10 #include "base/files/scoped_temp_dir.h" 11 #include "gn/filesystem_utils.h" 12 #include "gn/switches.h" 13 #include "gn/test_with_scheduler.h" 14 #include "util/build_config.h" 15 16 using SetupTest = TestWithScheduler; 17 WriteFile(const base::FilePath & file,const std::string & data)18 static void WriteFile(const base::FilePath& file, const std::string& data) { 19 CHECK_EQ(static_cast<int>(data.size()), // Way smaller than INT_MAX. 20 base::WriteFile(file, data.data(), data.size())); 21 } 22 TEST_F(SetupTest,DotGNFileIsGenDep)23 TEST_F(SetupTest, DotGNFileIsGenDep) { 24 base::CommandLine cmdline(base::CommandLine::NO_PROGRAM); 25 26 // Create a temp directory containing a .gn file and a BUILDCONFIG.gn file, 27 // pass it as --root. 28 base::ScopedTempDir in_temp_dir; 29 ASSERT_TRUE(in_temp_dir.CreateUniqueTempDir()); 30 base::FilePath in_path = in_temp_dir.GetPath(); 31 base::FilePath dot_gn_name = in_path.Append(FILE_PATH_LITERAL(".gn")); 32 WriteFile(dot_gn_name, "buildconfig = \"//BUILDCONFIG.gn\"\n"); 33 WriteFile(in_path.Append(FILE_PATH_LITERAL("BUILDCONFIG.gn")), ""); 34 cmdline.AppendSwitchASCII(switches::kRoot, FilePathToUTF8(in_path)); 35 36 // Create another temp dir for writing the generated files to. 37 base::ScopedTempDir build_temp_dir; 38 ASSERT_TRUE(build_temp_dir.CreateUniqueTempDir()); 39 40 // Run setup and check that the .gn file is in the scheduler's gen deps. 41 Setup setup; 42 EXPECT_TRUE( 43 setup.DoSetup(FilePathToUTF8(build_temp_dir.GetPath()), true, cmdline)); 44 std::vector<base::FilePath> gen_deps = g_scheduler->GetGenDependencies(); 45 ASSERT_EQ(1u, gen_deps.size()); 46 EXPECT_EQ(gen_deps[0], base::MakeAbsoluteFilePath(dot_gn_name)); 47 } 48 TEST_F(SetupTest,EmptyScriptExecutableDoesNotGenerateError)49 TEST_F(SetupTest, EmptyScriptExecutableDoesNotGenerateError) { 50 base::CommandLine cmdline(base::CommandLine::NO_PROGRAM); 51 52 // Create a temp directory containing a .gn file and a BUILDCONFIG.gn file, 53 // pass it as --root. 54 base::ScopedTempDir in_temp_dir; 55 ASSERT_TRUE(in_temp_dir.CreateUniqueTempDir()); 56 base::FilePath in_path = in_temp_dir.GetPath(); 57 base::FilePath dot_gn_name = in_path.Append(FILE_PATH_LITERAL(".gn")); 58 WriteFile(dot_gn_name, 59 "buildconfig = \"//BUILDCONFIG.gn\"\n" 60 "script_executable = \"\"\n"); 61 62 WriteFile(in_path.Append(FILE_PATH_LITERAL("BUILDCONFIG.gn")), ""); 63 cmdline.AppendSwitchASCII(switches::kRoot, FilePathToUTF8(in_path)); 64 65 // Create another temp dir for writing the generated files to. 66 base::ScopedTempDir build_temp_dir; 67 ASSERT_TRUE(build_temp_dir.CreateUniqueTempDir()); 68 69 // Run setup and check that the .gn file is in the scheduler's gen deps. 70 Setup setup; 71 Err err; 72 EXPECT_TRUE(setup.DoSetupWithErr(FilePathToUTF8(build_temp_dir.GetPath()), 73 true, cmdline, &err)); 74 } 75 76 #if defined(OS_WIN) TEST_F(SetupTest,MissingScriptExeGeneratesSetupErrorOnWindows)77 TEST_F(SetupTest, MissingScriptExeGeneratesSetupErrorOnWindows) { 78 base::CommandLine cmdline(base::CommandLine::NO_PROGRAM); 79 80 // Create a temp directory containing a .gn file and a BUILDCONFIG.gn file, 81 // pass it as --root. 82 base::ScopedTempDir in_temp_dir; 83 ASSERT_TRUE(in_temp_dir.CreateUniqueTempDir()); 84 base::FilePath in_path = in_temp_dir.GetPath(); 85 base::FilePath dot_gn_name = in_path.Append(FILE_PATH_LITERAL(".gn")); 86 WriteFile(dot_gn_name, 87 "buildconfig = \"//BUILDCONFIG.gn\"\n" 88 "script_executable = \"this_does_not_exist\"\n"); 89 90 WriteFile(in_path.Append(FILE_PATH_LITERAL("BUILDCONFIG.gn")), ""); 91 cmdline.AppendSwitchASCII(switches::kRoot, FilePathToUTF8(in_path)); 92 93 // Create another temp dir for writing the generated files to. 94 base::ScopedTempDir build_temp_dir; 95 ASSERT_TRUE(build_temp_dir.CreateUniqueTempDir()); 96 97 // Run setup and check that the .gn file is in the scheduler's gen deps. 98 Setup setup; 99 Err err; 100 EXPECT_FALSE(setup.DoSetupWithErr(FilePathToUTF8(build_temp_dir.GetPath()), 101 true, cmdline, &err)); 102 EXPECT_TRUE(err.has_error()); 103 } 104 #endif // defined(OS_WIN) 105 RunExtensionCheckTest(std::string extension,bool success,const std::string & expected_error_message)106 static void RunExtensionCheckTest(std::string extension, 107 bool success, 108 const std::string& expected_error_message) { 109 base::CommandLine cmdline(base::CommandLine::NO_PROGRAM); 110 111 // Create a temp directory containing a .gn file and a BUILDCONFIG.gn file, 112 // pass it as --root. 113 base::ScopedTempDir in_temp_dir; 114 ASSERT_TRUE(in_temp_dir.CreateUniqueTempDir()); 115 base::FilePath in_path = in_temp_dir.GetPath(); 116 base::FilePath dot_gn_name = in_path.Append(FILE_PATH_LITERAL(".gn")); 117 WriteFile(dot_gn_name, 118 "buildconfig = \"//BUILDCONFIG.gn\"\n\ 119 build_file_extension = \"" + 120 extension + "\""); 121 WriteFile(in_path.Append(FILE_PATH_LITERAL("BUILDCONFIG.gn")), ""); 122 cmdline.AppendSwitchASCII(switches::kRoot, FilePathToUTF8(in_path)); 123 124 // Create another temp dir for writing the generated files to. 125 base::ScopedTempDir build_temp_dir; 126 ASSERT_TRUE(build_temp_dir.CreateUniqueTempDir()); 127 128 // Run setup and check that its status. 129 Setup setup; 130 Err err; 131 EXPECT_EQ(success, 132 setup.DoSetupWithErr(FilePathToUTF8(build_temp_dir.GetPath()), true, 133 cmdline, &err)); 134 EXPECT_EQ(success, !err.has_error()); 135 } 136 TEST_F(SetupTest,NoSeparatorInExtension)137 TEST_F(SetupTest, NoSeparatorInExtension) { 138 RunExtensionCheckTest( 139 "hello" + std::string(1, base::FilePath::kSeparators[0]) + "world", false, 140 #if defined(OS_WIN) 141 "Build file extension 'hello\\world' cannot contain a path separator" 142 #else 143 "Build file extension 'hello/world' cannot contain a path separator" 144 #endif 145 ); 146 } 147 TEST_F(SetupTest,Extension)148 TEST_F(SetupTest, Extension) { 149 RunExtensionCheckTest("yay", true, ""); 150 } 151