aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zen/zen.cpp1
-rw-r--r--src/zencompute-test/zencompute-test.cpp22
-rw-r--r--src/zencore-test/zencore-test.cpp36
-rw-r--r--src/zencore/include/zencore/testing.h2
-rw-r--r--src/zencore/include/zencore/testutils.h27
-rw-r--r--src/zencore/string.cpp131
-rw-r--r--src/zencore/testing.cpp37
-rw-r--r--src/zenhttp-test/zenhttp-test.cpp35
-rw-r--r--src/zennet-test/zennet-test.cpp34
-rw-r--r--src/zenremotestore-test/zenremotestore-test.cpp35
-rw-r--r--src/zenserver-test/zenserver-test.cpp11
-rw-r--r--src/zenserver/main.cpp1
-rw-r--r--src/zenstore-test/zenstore-test.cpp34
-rw-r--r--src/zentelemetry-test/zentelemetry-test.cpp34
-rw-r--r--src/zentest-appstub/zentest-appstub.cpp1
-rw-r--r--src/zenutil-test/zenutil-test.cpp34
-rw-r--r--src/zenutil/include/zenutil/zenserverprocess.h10
-rw-r--r--src/zenutil/zenserverprocess.cpp13
18 files changed, 228 insertions, 270 deletions
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