diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2024-04-25 09:13:23 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2024-04-25 09:13:23 -0400 |
commit | f162693a23fe5cfda8dab3857718624033812d30 (patch) | |
tree | 0768f9ea570b248b48e4caa33103e3d55c625466 /indra/test | |
parent | d8931c9269a90cd01f6f6ff4de83b8fb41df11d3 (diff) | |
parent | d98fc504a1d4bc292ba86acdda053c8b4598a193 (diff) |
Merge Maint YZ branch 'main' into DRTVWR-588-cleanup-timers
Diffstat (limited to 'indra/test')
-rw-r--r-- | indra/test/CMakeLists.txt | 7 | ||||
-rw-r--r-- | indra/test/hexdump.h | 97 | ||||
-rw-r--r-- | indra/test/io.cpp | 10 | ||||
-rw-r--r-- | indra/test/llevents_tut.cpp | 4 | ||||
-rw-r--r-- | indra/test/namedtempfile.h | 29 | ||||
-rw-r--r-- | indra/test/test.cpp | 38 |
6 files changed, 156 insertions, 29 deletions
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index b7a39a7450..4a0a8716c4 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -74,6 +74,13 @@ if (WINDOWS) LINK_FLAGS "/NODEFAULTLIB:LIBCMT" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" ) +elseif (DARWIN) + # Support our "@executable_path/../Resources" load path for our test + # executable. This SHOULD properly be "$<TARGET_FILE_DIR:lltest>/Resources", + # but the CMake $<TARGET_FILE_DIR> generator expression isn't evaluated by + # CREATE_LINK, so fudge it. + file(CREATE_LINK "../sharedlibs/Release/Resources" "${CMAKE_BINARY_DIR}/test/Resources" + SYMBOLIC) endif (WINDOWS) set(TEST_EXE $<TARGET_FILE:lltest>) diff --git a/indra/test/hexdump.h b/indra/test/hexdump.h new file mode 100644 index 0000000000..dd7cbaaa3c --- /dev/null +++ b/indra/test/hexdump.h @@ -0,0 +1,97 @@ +/** + * @file hexdump.h + * @author Nat Goodspeed + * @date 2023-09-08 + * @brief Provide hexdump() and hexmix() ostream formatters + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Copyright (c) 2023, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_HEXDUMP_H) +#define LL_HEXDUMP_H + +#include <cctype> +#include <iomanip> +#include <iostream> +#include <string_view> + +// Format a given byte string as 2-digit hex values, no separators +// Usage: std::cout << hexdump(somestring) << ... +class hexdump +{ +public: + hexdump(const std::string_view& data): + hexdump(data.data(), data.length()) + {} + + hexdump(const char* data, size_t len): + hexdump(reinterpret_cast<const unsigned char*>(data), len) + {} + + hexdump(const unsigned char* data, size_t len): + mData(data, data + len) + {} + + friend std::ostream& operator<<(std::ostream& out, const hexdump& self) + { + auto oldfmt{ out.flags() }; + auto oldfill{ out.fill() }; + out.setf(std::ios_base::hex, std::ios_base::basefield); + out.fill('0'); + for (auto c : self.mData) + { + out << std::setw(2) << unsigned(c); + } + out.setf(oldfmt, std::ios_base::basefield); + out.fill(oldfill); + return out; + } + +private: + std::vector<unsigned char> mData; +}; + +// Format a given byte string as a mix of printable characters and, for each +// non-printable character, "\xnn" +// Usage: std::cout << hexmix(somestring) << ... +class hexmix +{ +public: + hexmix(const std::string_view& data): + mData(data) + {} + + hexmix(const char* data, size_t len): + mData(data, len) + {} + + friend std::ostream& operator<<(std::ostream& out, const hexmix& self) + { + auto oldfmt{ out.flags() }; + auto oldfill{ out.fill() }; + out.setf(std::ios_base::hex, std::ios_base::basefield); + out.fill('0'); + for (auto c : self.mData) + { + // std::isprint() must be passed an unsigned char! + if (std::isprint(static_cast<unsigned char>(c))) + { + out << c; + } + else + { + out << "\\x" << std::setw(2) << unsigned(c); + } + } + out.setf(oldfmt, std::ios_base::basefield); + out.fill(oldfill); + return out; + } + +private: + std::string mData; +}; + +#endif /* ! defined(LL_HEXDUMP_H) */ diff --git a/indra/test/io.cpp b/indra/test/io.cpp index 40243a8ad6..99b49c8b29 100644 --- a/indra/test/io.cpp +++ b/indra/test/io.cpp @@ -946,7 +946,7 @@ namespace tut typedef LLCloneIOFactory<LLPipeStringInjector> emitter_t; emitter_t* emitter = new emitter_t( new LLPipeStringInjector("suckers never play me")); - boost::shared_ptr<LLChainIOFactory> factory(emitter); + std::shared_ptr<LLChainIOFactory> factory(emitter); LLIOServerSocket* server = new LLIOServerSocket( mPool, mSocket, @@ -993,7 +993,7 @@ namespace tut LLPumpIO::chain_t chain; typedef LLCloneIOFactory<LLIOFuzz> emitter_t; emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); - boost::shared_ptr<LLChainIOFactory> factory(emitter); + std::shared_ptr<LLChainIOFactory> factory(emitter); LLIOServerSocket* server = new LLIOServerSocket( mPool, mSocket, @@ -1036,7 +1036,7 @@ namespace tut LLPumpIO::chain_t chain; typedef LLCloneIOFactory<LLIOFuzz> emitter_t; emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); - boost::shared_ptr<LLChainIOFactory> factory(emitter); + std::shared_ptr<LLChainIOFactory> factory(emitter); LLIOServerSocket* server = new LLIOServerSocket( mPool, mSocket, @@ -1079,7 +1079,7 @@ namespace tut LLPumpIO::chain_t chain; typedef LLCloneIOFactory<LLIOFuzz> emitter_t; emitter_t* emitter = new emitter_t(new LLIOFuzz(1000000)); - boost::shared_ptr<LLChainIOFactory> factory(emitter); + std::shared_ptr<LLChainIOFactory> factory(emitter); LLIOServerSocket* server = new LLIOServerSocket( mPool, mSocket, @@ -1120,7 +1120,7 @@ namespace tut LLPumpIO::chain_t chain; typedef LLCloneIOFactory<LLIOSleeper> sleeper_t; sleeper_t* sleeper = new sleeper_t(new LLIOSleeper); - boost::shared_ptr<LLChainIOFactory> factory(sleeper); + std::shared_ptr<LLChainIOFactory> factory(sleeper); LLIOServerSocket* server = new LLIOServerSocket( mPool, mSocket, diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp index 17f64a4953..a38de71e48 100644 --- a/indra/test/llevents_tut.cpp +++ b/indra/test/llevents_tut.cpp @@ -368,10 +368,10 @@ void events_object::test<7>() LLEventStream bob("bob"); // should work, previous one unregistered LLEventStream bob1("bob", true);// allowed to tweak name ensure_equals("tweaked LLEventStream name", bob1.getName(), "bob1"); - std::vector<boost::shared_ptr<LLEventStream> > streams; + std::vector<std::shared_ptr<LLEventStream> > streams; for (int i = 2; i <= 10; ++i) { - streams.push_back(boost::shared_ptr<LLEventStream>(new LLEventStream("bob", true))); + streams.push_back(std::shared_ptr<LLEventStream>(new LLEventStream("bob", true))); } ensure_equals("last tweaked LLEventStream name", streams.back()->getName(), "bob10"); } diff --git a/indra/test/namedtempfile.h b/indra/test/namedtempfile.h index 525a35000d..ad14cebbd1 100644 --- a/indra/test/namedtempfile.h +++ b/indra/test/namedtempfile.h @@ -67,14 +67,31 @@ public: std::string getName() const { return mPath.string(); } - void peep() + template <typename CALLABLE> + void peep_via(CALLABLE&& callable) const { - std::cout << "File '" << mPath << "' contains:\n"; - boost::filesystem::ifstream reader(mPath); + std::forward<CALLABLE>(callable)(stringize("File '", mPath, "' contains:")); + boost::filesystem::ifstream reader(mPath, std::ios::binary); std::string line; while (std::getline(reader, line)) - std::cout << line << '\n'; - std::cout << "---\n"; + std::forward<CALLABLE>(callable)(line); + std::forward<CALLABLE>(callable)("---"); + } + + void peep_log() const + { + peep_via([](const std::string& line){ LL_DEBUGS() << line << LL_ENDL; }); + } + + void peep(std::ostream& out=std::cout) const + { + peep_via([&out](const std::string& line){ out << line << '\n'; }); + } + + friend std::ostream& operator<<(std::ostream& out, const NamedTempFile& self) + { + self.peep(out); + return out; } static boost::filesystem::path temp_path(const std::string_view& pfx="", @@ -103,7 +120,7 @@ protected: { // Create file in a temporary place. mPath = temp_path(pfx, sfx); - boost::filesystem::ofstream out{ mPath }; + boost::filesystem::ofstream out{ mPath, std::ios::binary }; // Write desired content. func(out); } diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 9dd33c574d..f1c5991330 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -54,6 +54,12 @@ #endif #ifndef LL_WINDOWS + +typedef struct { + void *re_pcre; + size_t re_nsub; + size_t re_erroffset; +} regex_t; #include <gmock/gmock.h> #include <gtest/gtest.h> #endif @@ -97,7 +103,7 @@ public: class RecordToTempFile : public LLError::Recorder, public boost::noncopyable { public: - RecordToTempFile(apr_pool_t* pPool) + RecordToTempFile() : LLError::Recorder(), boost::noncopyable(), mTempFile("log", ""), @@ -141,11 +147,11 @@ private: class LLReplayLogReal: public LLReplayLog, public boost::noncopyable { public: - LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool) + LLReplayLogReal(LLError::ELevel level) : LLReplayLog(), boost::noncopyable(), mOldSettings(LLError::saveAndResetSettings()), - mRecorder(new RecordToTempFile(pool)) + mRecorder(new RecordToTempFile()) { LLError::setFatalFunction(wouldHaveCrashed); LLError::setDefaultLevel(level); @@ -160,12 +166,12 @@ public: virtual void reset() { - boost::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->reset(); + std::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->reset(); } virtual void replay(std::ostream& out) { - boost::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->replay(out); + std::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->replay(out); } private: @@ -179,7 +185,7 @@ class LLTestCallback : public chained_callback public: LLTestCallback(bool verbose_mode, std::ostream *stream, - boost::shared_ptr<LLReplayLog> replayer) : + std::shared_ptr<LLReplayLog> replayer) : mVerboseMode(verbose_mode), mTotalTests(0), mPassedTests(0), @@ -187,7 +193,7 @@ public: mSkippedTests(0), // By default, capture a shared_ptr to std::cout, with a no-op "deleter" // so that destroying the shared_ptr makes no attempt to delete std::cout. - mStream(boost::shared_ptr<std::ostream>(&std::cout, [](std::ostream*){})), + mStream(std::shared_ptr<std::ostream>(&std::cout, [](std::ostream*){})), mReplayer(replayer) { if (stream) @@ -201,7 +207,7 @@ public: // Allocate and assign in two separate steps, per Herb Sutter. // (Until we turn on C++11 support, have to wrap *stream with // boost::ref() due to lack of perfect forwarding.) - boost::shared_ptr<std::ostream> pstream(new TeeStream(std::cout, boost::ref(*stream))); + std::shared_ptr<std::ostream> pstream(new TeeStream(std::cout, boost::ref(*stream))); mStream = pstream; } } @@ -259,7 +265,7 @@ public: break; case tut::test_result::ex: ++mFailedTests; - out << "exception: " << tr.exception_typeid; + out << "exception: " << LLError::Log::demangle(tr.exception_typeid.c_str()); break; case tut::test_result::warn: ++mFailedTests; @@ -325,8 +331,8 @@ protected: int mPassedTests; int mFailedTests; int mSkippedTests; - boost::shared_ptr<std::ostream> mStream; - boost::shared_ptr<LLReplayLog> mReplayer; + std::shared_ptr<std::ostream> mStream; + std::shared_ptr<LLReplayLog> mReplayer; }; // TeamCity specific class which emits service messages @@ -336,7 +342,7 @@ class LLTCTestCallback : public LLTestCallback { public: LLTCTestCallback(bool verbose_mode, std::ostream *stream, - boost::shared_ptr<LLReplayLog> replayer) : + std::shared_ptr<LLReplayLog> replayer) : LLTestCallback(verbose_mode, stream, replayer) { } @@ -401,7 +407,7 @@ public: { // Per http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages std::string result; - BOOST_FOREACH(char c, str) + for (char c : str) { switch (c) { @@ -549,7 +555,7 @@ int main(int argc, char **argv) apr_status_t apr_err; const char* opt_arg = NULL; int opt_id = 0; - boost::scoped_ptr<llofstream> output; + std::unique_ptr<llofstream> output; const char *touch = NULL; while(true) @@ -608,7 +614,7 @@ int main(int argc, char **argv) // set up logging const char* LOGFAIL = getenv("LOGFAIL"); - boost::shared_ptr<LLReplayLog> replayer{boost::make_shared<LLReplayLog>()}; + std::shared_ptr<LLReplayLog> replayer{std::make_shared<LLReplayLog>()}; // Testing environment variables for both 'set' and 'not empty' allows a // user to suppress a pre-existing environment variable by forcing empty. @@ -624,7 +630,7 @@ int main(int argc, char **argv) if (LOGFAIL && *LOGFAIL) { LLError::ELevel level = LLError::decodeLevel(LOGFAIL); - replayer.reset(new LLReplayLogReal(level, gAPRPoolp)); + replayer.reset(new LLReplayLogReal(level)); } } LLError::setFatalFunction(wouldHaveCrashed); |