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