Fix command_format_unittest.cc out-of-tree builds.

The format unittests were relying on the source root being exactly one
directory level up from the executable directory. This assumption fails
when building with a custom or nested output directory, such as
out/Default, or when building out-of-tree (like in /tmp/gn-release).

To resolve this robustly:
1. build/gen.py now writes the absolute path of the repository root
   (REPO_ROOT) to source_root.txt in the build directory.
2. GetFormatTestDataDir() in src/gn/command_format_unittest.cc reads
   source_root.txt to dynamically resolve the repository root and sets
   the CWD to that location. If the file cannot be read, it fails
   immediately via CHECK.

Bug: None
Change-Id: I93d9a1642720ce912fd767e76eb414016a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/23944
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Matt Stark <msta@google.com>
diff --git a/build/gen.py b/build/gen.py
index 6f13c8c..e3f2c46 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -1026,6 +1026,11 @@
   executables['gn']['libs'].extend(static_libraries.keys())
   executables['gn_unittests']['libs'].extend(static_libraries.keys())
 
+  # Write the absolute path of the source root to a file in the output directory
+  # so that tests can locate the source tree robustly.
+  with open(os.path.join(options.out_path, 'source_root.txt'), 'w') as f:
+    f.write(REPO_ROOT)
+
   WriteGenericNinja(path, static_libraries, executables, cxx, ar, ld,
                     platform, host, options, args_list,
                     cflags, ldflags, libflags, include_dirs, libs)
diff --git a/src/gn/command_format_unittest.cc b/src/gn/command_format_unittest.cc
index 4a8c597..8500525 100644
--- a/src/gn/command_format_unittest.cc
+++ b/src/gn/command_format_unittest.cc
@@ -5,13 +5,21 @@
 #include "gn/command_format.h"
 
 #include "base/files/file_util.h"
-#include "base/strings/string_util.h"
 #include "gn/commands.h"
+#include "gn/filesystem_utils.h"
 #include "gn/setup.h"
 #include "gn/test_with_scheduler.h"
 #include "util/exe_path.h"
 #include "util/test/test.h"
 
+base::FilePath GetFormatTestDataDir() {
+  base::FilePath source_root_path =
+      GetExePath().DirName().Append(FILE_PATH_LITERAL("source_root.txt"));
+  std::string source_root;
+  CHECK(base::ReadFileToString(source_root_path, &source_root));
+  return UTF8ToFilePath(source_root);
+}
+
 using FormatTest = TestWithScheduler;
 
 #define FORMAT_TEST(n) FORMAT_TEST_WITH_WIDTH(n, commands::kDefaultFormatWidth)
@@ -22,8 +30,7 @@
     std::string input;                                                         \
     std::string out;                                                           \
     std::string expected;                                                      \
-    base::FilePath src_dir =                                                   \
-        GetExePath().DirName().Append(FILE_PATH_LITERAL(".."));                \
+    base::FilePath src_dir = GetFormatTestDataDir();                           \
     base::SetCurrentDirectory(src_dir);                                        \
     ASSERT_TRUE(base::ReadFileToString(                                        \
         base::FilePath(FILE_PATH_LITERAL("src/gn/format_test_data/")           \