diff options
| author | Stefan Boberg <[email protected]> | 2026-03-01 12:40:20 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-01 12:40:20 +0100 |
| commit | 4d01aaee0a45f4c9f96e8a4925eff696be98de8d (patch) | |
| tree | a0cefd6ef899f77a98370f52079b86af3db0d070 | |
| parent | subprocess tracking using Jobs on Windows/hub (#796) (diff) | |
| download | zen-4d01aaee0a45f4c9f96e8a4925eff696be98de8d.tar.xz zen-4d01aaee0a45f4c9f96e8a4925eff696be98de8d.zip | |
added `--verbose` option to zenserver-test and `xmake test` (#798)
* when `--verbose` is specified to zenserver-test, all child process output (typically, zenserver instances) is piped through to stdout. you can also pass `--verbose` to `xmake test` to accomplish the same thing.
* this PR also consolidates all test runner `main` function logic (such as from zencore-test, zenhttp-test etc) into central implementation in zencore for consistency and ease of maintenance
* also added extended utf8-tests including a fix to `Utf8ToWide()`
| -rw-r--r-- | .github/workflows/create_release.yml | 6 | ||||
| -rw-r--r-- | .github/workflows/validate.yml | 6 | ||||
| -rw-r--r-- | src/zen/zen.cpp | 1 | ||||
| -rw-r--r-- | src/zencompute-test/zencompute-test.cpp | 22 | ||||
| -rw-r--r-- | src/zencore-test/zencore-test.cpp | 36 | ||||
| -rw-r--r-- | src/zencore/include/zencore/testing.h | 2 | ||||
| -rw-r--r-- | src/zencore/include/zencore/testutils.h | 27 | ||||
| -rw-r--r-- | src/zencore/string.cpp | 131 | ||||
| -rw-r--r-- | src/zencore/testing.cpp | 37 | ||||
| -rw-r--r-- | src/zenhttp-test/zenhttp-test.cpp | 35 | ||||
| -rw-r--r-- | src/zennet-test/zennet-test.cpp | 34 | ||||
| -rw-r--r-- | src/zenremotestore-test/zenremotestore-test.cpp | 35 | ||||
| -rw-r--r-- | src/zenserver-test/zenserver-test.cpp | 11 | ||||
| -rw-r--r-- | src/zenserver/main.cpp | 1 | ||||
| -rw-r--r-- | src/zenstore-test/zenstore-test.cpp | 34 | ||||
| -rw-r--r-- | src/zentelemetry-test/zentelemetry-test.cpp | 34 | ||||
| -rw-r--r-- | src/zentest-appstub/zentest-appstub.cpp | 1 | ||||
| -rw-r--r-- | src/zenutil-test/zenutil-test.cpp | 34 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/zenserverprocess.h | 10 | ||||
| -rw-r--r-- | src/zenutil/zenserverprocess.cpp | 13 | ||||
| -rw-r--r-- | xmake.lua | 7 |
21 files changed, 240 insertions, 277 deletions
diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 203588d24..163c0cf85 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup xmake - uses: ue-foundation/[email protected] + uses: ue-foundation/[email protected] with: xmake-version: ${{env.XMAKE_VERSION}} @@ -54,7 +54,7 @@ jobs: ./scripts/ue_build_linux/get_ue_toolchain.sh ./.tmp-ue-toolchain - name: Setup xmake - uses: ue-foundation/[email protected] + uses: ue-foundation/[email protected] with: xmake-version: ${{env.XMAKE_VERSION}} @@ -92,7 +92,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup xmake - uses: ue-foundation/[email protected] + uses: ue-foundation/[email protected] with: xmake-version: ${{env.XMAKE_VERSION}} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index bf7b1c853..32b75fe5e 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -72,7 +72,7 @@ jobs: run: git config --global --add safe.directory "${{ github.workspace }}" - name: Setup xmake - uses: ue-foundation/[email protected] + uses: ue-foundation/[email protected] with: xmake-version: ${{env.XMAKE_VERSION}} @@ -139,7 +139,7 @@ jobs: ./scripts/ue_build_linux/get_ue_toolchain.sh ./.tmp-ue-toolchain - name: Setup xmake - uses: ue-foundation/[email protected] + uses: ue-foundation/[email protected] with: xmake-version: ${{env.XMAKE_VERSION}} @@ -202,7 +202,7 @@ jobs: uses: actions/checkout@v4 - name: Setup xmake - uses: ue-foundation/[email protected] + uses: ue-foundation/[email protected] with: xmake-version: ${{env.XMAKE_VERSION}} diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp index dc37cb56b..ba8a76bc3 100644 --- a/src/zen/zen.cpp +++ b/src/zen/zen.cpp @@ -56,7 +56,6 @@ #include "progressbar.h" #if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> #endif diff --git a/src/zencompute-test/zencompute-test.cpp b/src/zencompute-test/zencompute-test.cpp index 237812e12..60aaeab1d 100644 --- a/src/zencompute-test/zencompute-test.cpp +++ b/src/zencompute-test/zencompute-test.cpp @@ -1,31 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. #include <zencompute/zencompute.h> -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/zencore.h> +#include <zencore/testing.h> -#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC -# include <sys/time.h> -# include <sys/resource.h> -# include <zencore/except.h> -#endif - -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -#endif +#include <zencore/memory/newdelete.h> int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { #if ZEN_WITH_TESTS - zen::zencompute_forcelinktests(); - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zencompute-test", zen::zencompute_forcelinktests); #else return 0; #endif diff --git a/src/zencore-test/zencore-test.cpp b/src/zencore-test/zencore-test.cpp index 68fc940ee..3d9a79283 100644 --- a/src/zencore-test/zencore-test.cpp +++ b/src/zencore-test/zencore-test.cpp @@ -1,47 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -// zencore-test.cpp : Defines the entry point for the console application. -// - -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/trace.h> +#include <zencore/testing.h> #include <zencore/zencore.h> #include <zencore/memory/newdelete.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif - int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zencore_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zencore-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zencore-test", zen::zencore_forcelinktests); #else return 0; #endif diff --git a/src/zencore/include/zencore/testing.h b/src/zencore/include/zencore/testing.h index a00ee3166..43bdbbffe 100644 --- a/src/zencore/include/zencore/testing.h +++ b/src/zencore/include/zencore/testing.h @@ -59,6 +59,8 @@ private: return Runner.Run(); \ }() +int RunTestMain(int argc, char* argv[], const char* traceName, void (*forceLink)()); + } // namespace zen::testing #endif diff --git a/src/zencore/include/zencore/testutils.h b/src/zencore/include/zencore/testutils.h index e2a4f8346..2a789d18f 100644 --- a/src/zencore/include/zencore/testutils.h +++ b/src/zencore/include/zencore/testutils.h @@ -59,6 +59,33 @@ struct TrueType static const bool Enabled = true; }; +namespace utf8test { + + // 2-byte UTF-8 (Latin extended) + static constexpr const char kLatin[] = u8"café_résumé"; + static constexpr const wchar_t kLatinW[] = L"café_résumé"; + + // 2-byte UTF-8 (Cyrillic) + static constexpr const char kCyrillic[] = u8"данные"; + static constexpr const wchar_t kCyrillicW[] = L"данные"; + + // 3-byte UTF-8 (CJK) + static constexpr const char kCJK[] = u8"日本語"; + static constexpr const wchar_t kCJKW[] = L"日本語"; + + // Mixed scripts + static constexpr const char kMixed[] = u8"zen_éд日"; + static constexpr const wchar_t kMixedW[] = L"zen_éд日"; + + // 4-byte UTF-8 (supplementary plane) — string tests only, NOT filesystem + static constexpr const char kEmoji[] = u8"📦"; + static constexpr const wchar_t kEmojiW[] = L"📦"; + + // BMP-only test strings suitable for filesystem use + static constexpr const char* kFilenameSafe[] = {kLatin, kCyrillic, kCJK, kMixed}; + +} // namespace utf8test + } // namespace zen #endif // ZEN_WITH_TESTS diff --git a/src/zencore/string.cpp b/src/zencore/string.cpp index a9aed6309..ab1c7de58 100644 --- a/src/zencore/string.cpp +++ b/src/zencore/string.cpp @@ -4,6 +4,7 @@ #include <zencore/memoryview.h> #include <zencore/string.h> #include <zencore/testing.h> +#include <zencore/testutils.h> #include <inttypes.h> #include <math.h> @@ -184,7 +185,21 @@ Utf8ToWide(const std::u8string_view& Str8, WideStringBuilderBase& OutString) if (!ByteCount) { +#if ZEN_SIZEOF_WCHAR_T == 2 + if (CurrentOutChar > 0xFFFF) + { + // Supplementary plane: emit a UTF-16 surrogate pair + uint32_t Adjusted = uint32_t(CurrentOutChar - 0x10000); + OutString.Append(wchar_t(0xD800 + (Adjusted >> 10))); + OutString.Append(wchar_t(0xDC00 + (Adjusted & 0x3FF))); + } + else + { + OutString.Append(wchar_t(CurrentOutChar)); + } +#else OutString.Append(wchar_t(CurrentOutChar)); +#endif CurrentOutChar = 0; } } @@ -967,33 +982,131 @@ TEST_CASE("ExtendableWideStringBuilder") TEST_CASE("utf8") { + using namespace utf8test; + SUBCASE("utf8towide") { - // TODO: add more extensive testing here - this covers a very small space - WideStringBuilder<32> wout; Utf8ToWide(u8"abcdefghi", wout); CHECK(StringEquals(L"abcdefghi", wout.c_str())); wout.Reset(); + Utf8ToWide(u8"abc\xC3\xA4\xC3\xB6\xC3\xBC", wout); + CHECK(StringEquals(L"abc\u00E4\u00F6\u00FC", wout.c_str())); + + wout.Reset(); + Utf8ToWide(std::string_view(kLatin), wout); + CHECK(StringEquals(kLatinW, wout.c_str())); + + wout.Reset(); + Utf8ToWide(std::string_view(kCyrillic), wout); + CHECK(StringEquals(kCyrillicW, wout.c_str())); + + wout.Reset(); + Utf8ToWide(std::string_view(kCJK), wout); + CHECK(StringEquals(kCJKW, wout.c_str())); + + wout.Reset(); + Utf8ToWide(std::string_view(kMixed), wout); + CHECK(StringEquals(kMixedW, wout.c_str())); - Utf8ToWide(u8"abc���", wout); - CHECK(StringEquals(L"abc���", wout.c_str())); + wout.Reset(); + Utf8ToWide(std::string_view(kEmoji), wout); + CHECK(StringEquals(kEmojiW, wout.c_str())); } SUBCASE("widetoutf8") { - // TODO: add more extensive testing here - this covers a very small space - - StringBuilder<32> out; + StringBuilder<64> out; WideToUtf8(L"abcdefghi", out); CHECK(StringEquals("abcdefghi", out.c_str())); out.Reset(); + WideToUtf8(kLatinW, out); + CHECK(StringEquals(kLatin, out.c_str())); - WideToUtf8(L"abc���", out); - CHECK(StringEquals(u8"abc���", out.c_str())); + out.Reset(); + WideToUtf8(kCyrillicW, out); + CHECK(StringEquals(kCyrillic, out.c_str())); + + out.Reset(); + WideToUtf8(kCJKW, out); + CHECK(StringEquals(kCJK, out.c_str())); + + out.Reset(); + WideToUtf8(kMixedW, out); + CHECK(StringEquals(kMixed, out.c_str())); + + out.Reset(); + WideToUtf8(kEmojiW, out); + CHECK(StringEquals(kEmoji, out.c_str())); + } + + SUBCASE("roundtrip") + { + // UTF-8 -> Wide -> UTF-8 identity + const char* Utf8Strings[] = {kLatin, kCyrillic, kCJK, kMixed, kEmoji}; + for (const char* Utf8Str : Utf8Strings) + { + ExtendableWideStringBuilder<64> Wide; + Utf8ToWide(std::string_view(Utf8Str), Wide); + + ExtendableStringBuilder<64> Back; + WideToUtf8(std::wstring_view(Wide.c_str()), Back); + CHECK(StringEquals(Utf8Str, Back.c_str())); + } + + // Wide -> UTF-8 -> Wide identity + const wchar_t* WideStrings[] = {kLatinW, kCyrillicW, kCJKW, kMixedW, kEmojiW}; + for (const wchar_t* WideStr : WideStrings) + { + ExtendableStringBuilder<64> Utf8; + WideToUtf8(std::wstring_view(WideStr), Utf8); + + ExtendableWideStringBuilder<64> Back; + Utf8ToWide(std::string_view(Utf8.c_str()), Back); + CHECK(StringEquals(WideStr, Back.c_str())); + } + + // Empty string round-trip + { + ExtendableWideStringBuilder<8> Wide; + Utf8ToWide(std::string_view(""), Wide); + CHECK(Wide.Size() == 0); + + ExtendableStringBuilder<8> Narrow; + WideToUtf8(std::wstring_view(L""), Narrow); + CHECK(Narrow.Size() == 0); + } + } + + SUBCASE("IsValidUtf8") + { + // Valid inputs + CHECK(IsValidUtf8("")); + CHECK(IsValidUtf8("hello world")); + CHECK(IsValidUtf8(kLatin)); + CHECK(IsValidUtf8(kCyrillic)); + CHECK(IsValidUtf8(kCJK)); + CHECK(IsValidUtf8(kMixed)); + CHECK(IsValidUtf8(kEmoji)); + + // Invalid: truncated 2-byte sequence + CHECK(!IsValidUtf8(std::string_view("\xC3", 1))); + + // Invalid: truncated 3-byte sequence + CHECK(!IsValidUtf8(std::string_view("\xE6\x97", 2))); + + // Invalid: truncated 4-byte sequence + CHECK(!IsValidUtf8(std::string_view("\xF0\x9F\x93", 3))); + + // Invalid: bad start byte + CHECK(!IsValidUtf8(std::string_view("\xFF", 1))); + CHECK(!IsValidUtf8(std::string_view("\xFE", 1))); + + // Invalid: overlong encoding of '/' (U+002F) + CHECK(!IsValidUtf8(std::string_view("\xC0\xAF", 2))); } } diff --git a/src/zencore/testing.cpp b/src/zencore/testing.cpp index ef8fb0480..6000bd95c 100644 --- a/src/zencore/testing.cpp +++ b/src/zencore/testing.cpp @@ -1,18 +1,23 @@ // Copyright Epic Games, Inc. All Rights Reserved. +#define ZEN_TEST_WITH_RUNNER 1 + #include "zencore/testing.h" + +#include "zencore/filesystem.h" #include "zencore/logging.h" +#include "zencore/process.h" +#include "zencore/trace.h" #if ZEN_WITH_TESTS # include <chrono> +# include <clocale> # include <cstdlib> # include <cstdio> # include <string> # include <vector> -# include <doctest/doctest.h> - namespace zen::testing { using namespace std::literals; @@ -149,6 +154,34 @@ TestRunner::Run() return m_Impl->Session.run(); } +int +RunTestMain(int argc, char* argv[], [[maybe_unused]] const char* traceName, void (*forceLink)()) +{ +# if ZEN_PLATFORM_WINDOWS + setlocale(LC_ALL, "en_us.UTF8"); +# endif + + forceLink(); + +# if ZEN_PLATFORM_LINUX + zen::IgnoreChildSignals(); +# endif + +# if ZEN_WITH_TRACE + zen::TraceInit(traceName); + zen::TraceOptions TraceCommandlineOptions; + if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) + { + TraceConfigure(TraceCommandlineOptions); + } +# endif + + zen::logging::InitializeLogging(); + zen::MaximizeOpenFileCount(); + + return ZEN_RUN_TESTS(argc, argv); +} + } // namespace zen::testing #endif // ZEN_WITH_TESTS diff --git a/src/zenhttp-test/zenhttp-test.cpp b/src/zenhttp-test/zenhttp-test.cpp index c18759beb..b4b406ac8 100644 --- a/src/zenhttp-test/zenhttp-test.cpp +++ b/src/zenhttp-test/zenhttp-test.cpp @@ -1,44 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/memory/newdelete.h> -#include <zencore/trace.h> +#include <zencore/testing.h> #include <zenhttp/zenhttp.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif +#include <zencore/memory/newdelete.h> int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zenhttp_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zenhttp-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zenhttp-test", zen::zenhttp_forcelinktests); #else return 0; #endif diff --git a/src/zennet-test/zennet-test.cpp b/src/zennet-test/zennet-test.cpp index bc3b8e8e9..1283eb820 100644 --- a/src/zennet-test/zennet-test.cpp +++ b/src/zennet-test/zennet-test.cpp @@ -1,45 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/trace.h> +#include <zencore/testing.h> #include <zennet/zennet.h> #include <zencore/memory/newdelete.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif - int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zennet_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zennet-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zennet-test", zen::zennet_forcelinktests); #else return 0; #endif diff --git a/src/zenremotestore-test/zenremotestore-test.cpp b/src/zenremotestore-test/zenremotestore-test.cpp index 5db185041..dc47c5aed 100644 --- a/src/zenremotestore-test/zenremotestore-test.cpp +++ b/src/zenremotestore-test/zenremotestore-test.cpp @@ -1,46 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/trace.h> -#include <zenremotestore/projectstore/remoteprojectstore.h> +#include <zencore/testing.h> #include <zenremotestore/zenremotestore.h> #include <zencore/memory/newdelete.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif - int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zenremotestore_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zenstore-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zenremotestore-test", zen::zenremotestore_forcelinktests); #else return 0; #endif diff --git a/src/zenserver-test/zenserver-test.cpp b/src/zenserver-test/zenserver-test.cpp index 4120dec1a..c7ce633d3 100644 --- a/src/zenserver-test/zenserver-test.cpp +++ b/src/zenserver-test/zenserver-test.cpp @@ -4,7 +4,6 @@ #if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 # include "zenserver-test.h" # include <zencore/except.h> @@ -97,6 +96,7 @@ main(int argc, char** argv) // somehow in the future std::string ServerClass; + bool Verbose = false; for (int i = 1; i < argc; ++i) { @@ -107,10 +107,19 @@ main(int argc, char** argv) ServerClass = argv[++i]; } } + else if (argv[i] == "--verbose"sv) + { + Verbose = true; + } } zen::tests::TestEnv.InitializeForTest(ProgramBaseDir, TestBaseDir, ServerClass); + if (Verbose) + { + zen::tests::TestEnv.SetPassthroughOutput(true); + } + ZEN_INFO("Running tests...(base dir: '{}')", TestBaseDir); zen::testing::TestRunner Runner; diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp index 571dd3b4f..c764cbde6 100644 --- a/src/zenserver/main.cpp +++ b/src/zenserver/main.cpp @@ -41,7 +41,6 @@ // in some shared code into the executable #if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> #endif diff --git a/src/zenstore-test/zenstore-test.cpp b/src/zenstore-test/zenstore-test.cpp index c055dbb64..875373a9d 100644 --- a/src/zenstore-test/zenstore-test.cpp +++ b/src/zenstore-test/zenstore-test.cpp @@ -1,45 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/trace.h> +#include <zencore/testing.h> #include <zenstore/zenstore.h> #include <zencore/memory/newdelete.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif - int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zenstore_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zenstore-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zenstore-test", zen::zenstore_forcelinktests); #else return 0; #endif diff --git a/src/zentelemetry-test/zentelemetry-test.cpp b/src/zentelemetry-test/zentelemetry-test.cpp index 83fd549db..5a2ac74de 100644 --- a/src/zentelemetry-test/zentelemetry-test.cpp +++ b/src/zentelemetry-test/zentelemetry-test.cpp @@ -1,45 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/trace.h> +#include <zencore/testing.h> #include <zentelemetry/zentelemetry.h> #include <zencore/memory/newdelete.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif - int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zentelemetry_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zenstore-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zentelemetry-test", zen::zentelemetry_forcelinktests); #else return 0; #endif diff --git a/src/zentest-appstub/zentest-appstub.cpp b/src/zentest-appstub/zentest-appstub.cpp index 926580d96..67fbef532 100644 --- a/src/zentest-appstub/zentest-appstub.cpp +++ b/src/zentest-appstub/zentest-appstub.cpp @@ -9,7 +9,6 @@ #include <zencore/stream.h> #if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> #endif diff --git a/src/zenutil-test/zenutil-test.cpp b/src/zenutil-test/zenutil-test.cpp index f5cfd5a72..e2b6ac9bd 100644 --- a/src/zenutil-test/zenutil-test.cpp +++ b/src/zenutil-test/zenutil-test.cpp @@ -1,45 +1,15 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include <zencore/filesystem.h> -#include <zencore/logging.h> -#include <zencore/trace.h> +#include <zencore/testing.h> #include <zenutil/zenutil.h> #include <zencore/memory/newdelete.h> -#if ZEN_WITH_TESTS -# define ZEN_TEST_WITH_RUNNER 1 -# include <zencore/testing.h> -# include <zencore/process.h> -#endif - int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { -#if ZEN_PLATFORM_WINDOWS - setlocale(LC_ALL, "en_us.UTF8"); -#endif // ZEN_PLATFORM_WINDOWS - #if ZEN_WITH_TESTS - zen::zenutil_forcelinktests(); - -# if ZEN_PLATFORM_LINUX - zen::IgnoreChildSignals(); -# endif - -# if ZEN_WITH_TRACE - zen::TraceInit("zenutil-test"); - zen::TraceOptions TraceCommandlineOptions; - if (GetTraceOptionsFromCommandline(TraceCommandlineOptions)) - { - TraceConfigure(TraceCommandlineOptions); - } -# endif // ZEN_WITH_TRACE - - zen::logging::InitializeLogging(); - zen::MaximizeOpenFileCount(); - - return ZEN_RUN_TESTS(argc, argv); + return zen::testing::RunTestMain(argc, argv, "zenutil-test", zen::zenutil_forcelinktests); #else return 0; #endif diff --git a/src/zenutil/include/zenutil/zenserverprocess.h b/src/zenutil/include/zenutil/zenserverprocess.h index 954916fe2..e81b154e8 100644 --- a/src/zenutil/include/zenutil/zenserverprocess.h +++ b/src/zenutil/include/zenutil/zenserverprocess.h @@ -46,6 +46,9 @@ public: inline std::string_view GetServerClass() const { return m_ServerClass; } inline uint16_t GetNewPortNumber() { return m_NextPortNumber.fetch_add(1); } + void SetPassthroughOutput(bool Enable) { m_PassthroughOutput = Enable; } + bool IsPassthroughOutput() const { return m_PassthroughOutput; } + // The defaults will work for a single root process only. For hierarchical // setups (e.g., hub managing storage servers), we need to be able to // allocate distinct child IDs and ports to avoid overlap/conflicts. @@ -55,9 +58,10 @@ public: private: std::filesystem::path m_ProgramBaseDir; std::filesystem::path m_ChildProcessBaseDir; - bool m_IsInitialized = false; - bool m_IsTestInstance = false; - bool m_IsHubInstance = false; + bool m_IsInitialized = false; + bool m_IsTestInstance = false; + bool m_IsHubInstance = false; + bool m_PassthroughOutput = false; std::string m_ServerClass; std::atomic_uint16_t m_NextPortNumber{20000}; }; diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index 0f8ab223d..e127a92d7 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -829,12 +829,13 @@ ZenServerInstance::SpawnServerInternal(int ChildId, std::string_view ServerArgs, const std::filesystem::path BaseDir = m_Env.ProgramBaseDir(); const std::filesystem::path Executable = m_ServerExecutablePath.empty() ? (BaseDir / "zenserver" ZEN_EXE_SUFFIX_LITERAL) : m_ServerExecutablePath; - const std::filesystem::path OutputPath = - OpenConsole ? std::filesystem::path{} : std::filesystem::temp_directory_path() / ("zenserver_" + m_Name + ".log"); - CreateProcOptions CreateOptions = { - .WorkingDirectory = &CurrentDirectory, - .Flags = CreationFlags, - .StdoutFile = OutputPath, + const std::filesystem::path OutputPath = (OpenConsole || m_Env.IsPassthroughOutput()) + ? std::filesystem::path{} + : std::filesystem::temp_directory_path() / ("zenserver_" + m_Name + ".log"); + CreateProcOptions CreateOptions = { + .WorkingDirectory = &CurrentDirectory, + .Flags = CreationFlags, + .StdoutFile = OutputPath, #if ZEN_PLATFORM_WINDOWS .AssignToJob = m_JobObject, #endif @@ -350,7 +350,8 @@ task("test") {'r', "run", "kv", "all", "Run test(s) - comma-separated", " - all", " - core", " - http", " - util", " - store", " - remotestore", " - server", " - integration"}, {'j', "junit", "k", nil, "Enable junit report output"}, {'n', "noskip", "k", nil, "Run skipped tests (passes --no-skip to doctest)"}, - {nil, "repeat", "kv", nil, "Repeat tests N times (stops on first failure)"} + {nil, "repeat", "kv", nil, "Repeat tests N times (stops on first failure)"}, + {'v', "verbose", "k", nil, "Route child process output to stdout (zenserver-test)"} } } on_run(function() @@ -421,6 +422,7 @@ task("test") local use_junit_reporting = option.get("junit") local use_noskip = option.get("noskip") + local use_verbose = option.get("verbose") local repeat_count = tonumber(option.get("repeat")) or 1 local junit_report_files = {} @@ -535,6 +537,9 @@ task("test") if use_noskip then cmd = string.format("%s --no-skip", cmd) end + if use_verbose and name == "integration" then + cmd = string.format("%s --verbose", cmd) + end -- Tell TestListener where to write the summary local summary_file = path.join(summary_dir, target .. ".txt") |