From b0846aaf37a271d56019b42121ebcea0ac42e8c1 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 12 Dec 2022 09:33:33 -0800 Subject: Introduces a new porting flag (GTEST_HAS_FILE_SYSTEM) to indicate whether a platform supports filesystem operations. PiperOrigin-RevId: 494751986 Change-Id: I07f73bdf478a73934b8f1a69c1ab4abda1b231ae --- googletest/include/gtest/internal/gtest-filepath.h | 5 + googletest/include/gtest/internal/gtest-port.h | 101 +++++++++++++-------- googletest/src/gtest-filepath.cc | 4 + googletest/src/gtest-internal-inl.h | 4 + googletest/src/gtest.cc | 41 ++++++++- 5 files changed, 115 insertions(+), 40 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-filepath.h b/googletest/include/gtest/internal/gtest-filepath.h index dd7a3a4..ceba8f2 100644 --- a/googletest/include/gtest/internal/gtest-filepath.h +++ b/googletest/include/gtest/internal/gtest-filepath.h @@ -42,11 +42,14 @@ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-string.h" GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ /* class A needs to have dll-interface to be used by clients of class B */) +#if GTEST_HAS_FILE_SYSTEM + namespace testing { namespace internal { @@ -217,4 +220,6 @@ class GTEST_API_ FilePath { GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 +#endif // GTEST_HAS_FILE_SYSTEM + #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index c3b131f..01bfd1f 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -83,6 +83,8 @@ // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). +// GTEST_HAS_FILE_SYSTEM - Define it to 1/0 to indicate whether or not a +// file system is/isn't available. // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". @@ -463,6 +465,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif // GTEST_HAS_STD_WSTRING +#ifndef GTEST_HAS_FILE_SYSTEM +// Most platforms support a file system. +#define GTEST_HAS_FILE_SYSTEM 1 +#endif // GTEST_HAS_FILE_SYSTEM + // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to @@ -580,10 +587,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // output correctness and to implement death tests. #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all -// platforms except known mobile / embedded ones. +// platforms except known mobile / embedded ones. Also, if the port doesn't have +// a file system, stream redirection is not supported. #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \ - GTEST_OS_QURT + GTEST_OS_QURT || !GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_STREAM_REDIRECTION 0 #else #define GTEST_HAS_STREAM_REDIRECTION 1 @@ -599,7 +607,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \ GTEST_OS_GNU_HURD) +// Death tests require a file system to work properly. +#if GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_DEATH_TEST 1 +#endif // GTEST_HAS_FILE_SYSTEM #endif // Determines whether to support type-driven tests. @@ -1953,31 +1964,12 @@ inline std::string StripTrailingSpaces(std::string str) { namespace posix { -// Functions with a different name on Windows. - +// File system porting. +#if GTEST_HAS_FILE_SYSTEM #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; -#ifdef __BORLANDC__ -inline int DoIsATTY(int fd) { return isatty(fd); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return stricmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } -#else // !__BORLANDC__ -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ - GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) -inline int DoIsATTY(int /* fd */) { return 0; } -#else -inline int DoIsATTY(int fd) { return _isatty(fd); } -#endif // GTEST_OS_WINDOWS_MOBILE -inline int StrCaseCmp(const char* s1, const char* s2) { - return _stricmp(s1, s2); -} -inline char* StrDup(const char* src) { return _strdup(src); } -#endif // __BORLANDC__ - #if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this @@ -1993,15 +1985,10 @@ inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } -inline int DoIsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { // stat function not implemented on ESP8266 return 0; } -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } @@ -2010,12 +1997,7 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } -inline int DoIsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); -} -inline char* StrDup(const char* src) { return strdup(src); } #if GTEST_OS_QURT // QuRT doesn't support any directory functions, including rmdir inline int RmDir(const char*) { return 0; } @@ -2025,6 +2007,48 @@ inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_FILE_SYSTEM + +// Other functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +#ifdef __BORLANDC__ +inline int DoIsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ + GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) +inline int DoIsATTY(int /* fd */) { return 0; } +#else +inline int DoIsATTY(int fd) { return _isatty(fd); } +#endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +#endif // __BORLANDC__ + +#elif GTEST_OS_ESP8266 + +inline int DoIsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } + +#else + +inline int DoIsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } + +#endif // GTEST_OS_WINDOWS inline int IsATTY(int fd) { // DoIsATTY might change errno (for example ENOTTY in case you redirect stdout @@ -2044,7 +2068,7 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // StrError() aren't needed on Windows CE at this time and thus not // defined there. - +#if GTEST_HAS_FILE_SYSTEM #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ !GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA && \ !GTEST_OS_QURT @@ -2066,7 +2090,7 @@ inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } -#endif +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline int FClose(FILE* fp) { return fclose(fp); } #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline int Read(int fd, void* buf, unsigned int count) { @@ -2076,8 +2100,13 @@ inline int Write(int fd, const void* buf, unsigned int count) { return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT +#endif // GTEST_HAS_FILE_SYSTEM + +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline const char* StrError(int errnum) { return strerror(errnum); } -#endif +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT + inline const char* GetEnv(const char* name) { #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \ diff --git a/googletest/src/gtest-filepath.cc b/googletest/src/gtest-filepath.cc index bec5870..9d79ea4 100644 --- a/googletest/src/gtest-filepath.cc +++ b/googletest/src/gtest-filepath.cc @@ -57,6 +57,8 @@ #define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS +#if GTEST_HAS_FILE_SYSTEM + namespace testing { namespace internal { @@ -404,3 +406,5 @@ void FilePath::Normalize() { } // namespace internal } // namespace testing + +#endif // GTEST_HAS_FILE_SYSTEM diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index 517cc13..ddef4bb 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -396,9 +396,11 @@ class GTEST_API_ UnitTestOptions { static bool MatchesFilter(const std::string& name, const char* filter); }; +#if GTEST_HAS_FILE_SYSTEM // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. GTEST_API_ FilePath GetCurrentExecutableName(); +#endif // GTEST_HAS_FILE_SYSTEM // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { @@ -840,9 +842,11 @@ class GTEST_API_ UnitTestImpl { // The UnitTest object that owns this implementation object. UnitTest* const parent_; +#if GTEST_HAS_FILE_SYSTEM // The working directory when the first TEST() or TEST_F() was // executed. internal::FilePath original_working_dir_; +#endif // GTEST_HAS_FILE_SYSTEM // The default test part result reporters. DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 51de00e..0803cf3 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -58,6 +58,7 @@ #include "gtest/gtest-assertion-result.h" #include "gtest/gtest-spi.h" #include "gtest/internal/custom/gtest.h" +#include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX @@ -194,6 +195,7 @@ const char kStackTraceMarker[] = "\nStack trace:\n"; // is specified on the command line. bool g_help_flag = false; +#if GTEST_HAS_FILE_SYSTEM // Utility function to Open File for Writing static FILE* OpenFileForWriting(const std::string& output_file) { FILE* fileout = nullptr; @@ -208,6 +210,7 @@ static FILE* OpenFileForWriting(const std::string& output_file) { } return fileout; } +#endif // GTEST_HAS_FILE_SYSTEM } // namespace internal @@ -620,6 +623,7 @@ static ::std::vector g_argvs; #endif // defined(GTEST_CUSTOM_GET_ARGVS_) } +#if GTEST_HAS_FILE_SYSTEM // Returns the current application's name, removing directory path if that // is present. FilePath GetCurrentExecutableName() { @@ -633,6 +637,7 @@ FilePath GetCurrentExecutableName() { return result.RemoveDirectoryName(); } +#endif // GTEST_HAS_FILE_SYSTEM // Functions for processing the gtest_output flag. @@ -647,6 +652,7 @@ std::string UnitTestOptions::GetOutputFormat() { static_cast(colon - gtest_output_flag)); } +#if GTEST_HAS_FILE_SYSTEM // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { @@ -677,6 +683,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() { GetOutputFormat().c_str())); return result.string(); } +#endif // GTEST_HAS_FILE_SYSTEM // Returns true if and only if the wildcard pattern matches the string. Each // pattern consists of regular characters, single-character wildcards (?), and @@ -3262,7 +3269,12 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_start(args, fmt); static const bool in_color_mode = +#if GTEST_HAS_FILE_SYSTEM ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); +#else + false; +#endif // GTEST_HAS_FILE_SYSTEM + const bool use_color = in_color_mode && (color != GTestColor::kDefault); if (!use_color) { @@ -3867,6 +3879,7 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, // End TestEventRepeater +#if GTEST_HAS_FILE_SYSTEM // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: @@ -4414,7 +4427,9 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties( } // End XmlUnitTestResultPrinter +#endif // GTEST_HAS_FILE_SYSTEM +#if GTEST_HAS_FILE_SYSTEM // This class generates an JSON output file. class JsonUnitTestResultPrinter : public EmptyTestEventListener { public: @@ -4855,6 +4870,7 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( } // End JsonUnitTestResultPrinter +#endif // GTEST_HAS_FILE_SYSTEM #if GTEST_CAN_STREAM_RESULTS_ @@ -4993,6 +5009,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { #endif // GTEST_HAS_ABSL } +#if GTEST_HAS_DEATH_TEST // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. class ScopedPrematureExitFile { @@ -5030,6 +5047,7 @@ class ScopedPrematureExitFile { ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete; ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete; }; +#endif // GTEST_HAS_DEATH_TEST } // namespace internal @@ -5355,6 +5373,7 @@ void UnitTest::RecordProperty(const std::string& key, // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { +#if GTEST_HAS_DEATH_TEST const bool in_death_test_child_process = GTEST_FLAG_GET(internal_run_death_test).length() > 0; @@ -5383,6 +5402,7 @@ int UnitTest::Run() { in_death_test_child_process ? nullptr : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); +#endif // GTEST_HAS_DEATH_TEST // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. @@ -5438,11 +5458,13 @@ int UnitTest::Run() { : 1; } +#if GTEST_HAS_FILE_SYSTEM // Returns the working directory when the first TEST() or TEST_F() was // executed. const char* UnitTest::original_working_dir() const { return impl_->original_working_dir_.c_str(); } +#endif // GTEST_HAS_FILE_SYSTEM // Returns the TestSuite object for the test that's currently running, // or NULL if no test is running. @@ -5575,6 +5597,7 @@ void UnitTestImpl::SuppressTestEventsIfInSubprocess() { // UnitTestOptions. Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureXmlOutput() { const std::string& output_format = UnitTestOptions::GetOutputFormat(); +#if GTEST_HAS_FILE_SYSTEM if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); @@ -5585,6 +5608,10 @@ void UnitTestImpl::ConfigureXmlOutput() { GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" << output_format << "\" ignored."; } +#else + GTEST_LOG_(ERROR) << "ERROR: alternative output formats require " + << "GTEST_HAS_FILE_SYSTEM to be enabled"; +#endif // GTEST_HAS_FILE_SYSTEM } #if GTEST_CAN_STREAM_RESULTS_ @@ -5747,10 +5774,12 @@ bool UnitTestImpl::RunAllTests() { // user didn't call InitGoogleTest. PostFlagParsingInit(); +#if GTEST_HAS_FILE_SYSTEM // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding // protocol. internal::WriteToShardStatusFileIfNeeded(); +#endif // GTEST_HAS_FILE_SYSTEM // True if and only if we are in a subprocess for running a thread-safe-style // death test. @@ -5930,6 +5959,7 @@ bool UnitTestImpl::RunAllTests() { return !failed; } +#if GTEST_HAS_FILE_SYSTEM // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot @@ -5949,6 +5979,7 @@ void WriteToShardStatusFileIfNeeded() { fclose(file); } } +#endif // GTEST_HAS_FILE_SYSTEM // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, @@ -6140,6 +6171,7 @@ void UnitTestImpl::ListTestsMatchingFilter() { } } fflush(stdout); + #if GTEST_HAS_FILE_SYSTEM const std::string& output_format = UnitTestOptions::GetOutputFormat(); if (output_format == "xml" || output_format == "json") { FILE* fileout = OpenFileForWriting( @@ -6157,6 +6189,7 @@ void UnitTestImpl::ListTestsMatchingFilter() { fprintf(fileout, "%s", StringStreamToString(&stream).c_str()); fclose(fileout); } +#endif // GTEST_HAS_FILE_SYSTEM } // Sets the OS stack trace getter. @@ -6545,7 +6578,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { return false; } -#if GTEST_USE_OWN_FLAGFILE_FLAG_ +#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM static void LoadFlagsFromFile(const std::string& path) { FILE* flagfile = posix::FOpen(path.c_str(), "r"); if (!flagfile) { @@ -6561,7 +6594,7 @@ static void LoadFlagsFromFile(const std::string& path) { if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true; } } -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be @@ -6578,12 +6611,12 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { bool remove_flag = false; if (ParseGoogleTestFlag(arg)) { remove_flag = true; -#if GTEST_USE_OWN_FLAGFILE_FLAG_ +#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM } else if (ParseFlag(arg, "flagfile", &flagfile_value)) { GTEST_FLAG_SET(flagfile, flagfile_value); LoadFlagsFromFile(flagfile_value); remove_flag = true; -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM } else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. -- cgit v0.12