diff options
author | pechatnov <[email protected]> | 2025-08-06 18:42:10 +0300 |
---|---|---|
committer | pechatnov <[email protected]> | 2025-08-06 19:03:46 +0300 |
commit | 7bed48dd832fd169b9f9e4b820146228c934734b (patch) | |
tree | f51a6b2ec3d5a7be749b637c75c2346a56c04bf2 /library/cpp | |
parent | a7b92fa6aa8979ff6da2ae0b16c1e3d79c04b95e (diff) |
Optional description argument for YT_VERIFY, YT_ASSERT and others
commit_hash:80b47f95a2ee356b086f5955f2529f1b0e636db1
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/yt/assert/assert.cpp | 7 | ||||
-rw-r--r-- | library/cpp/yt/assert/assert.h | 45 | ||||
-rw-r--r-- | library/cpp/yt/assert/unittests/assert_ut.cpp | 98 | ||||
-rw-r--r-- | library/cpp/yt/assert/unittests/ya.make | 13 | ||||
-rw-r--r-- | library/cpp/yt/assert/ya.make | 4 |
5 files changed, 152 insertions, 15 deletions
diff --git a/library/cpp/yt/assert/assert.cpp b/library/cpp/yt/assert/assert.cpp index 095357cdfa8..2329a5118db 100644 --- a/library/cpp/yt/assert/assert.cpp +++ b/library/cpp/yt/assert/assert.cpp @@ -10,6 +10,7 @@ namespace NYT::NDetail { Y_WEAK void AssertTrapImpl( TStringBuf trapType, TStringBuf expr, + TStringBuf description, TStringBuf file, int line, TStringBuf function) @@ -20,8 +21,10 @@ Y_WEAK void AssertTrapImpl( line, function.data(), expr.data(), - "%s", - trapType.data()); + "%s: %.*s", + trapType.data(), + static_cast<int>(std::min<ui64>(description.length(), std::numeric_limits<int>::max())), + description.data()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/assert/assert.h b/library/cpp/yt/assert/assert.h index f2131d5bbcd..6430f136ffc 100644 --- a/library/cpp/yt/assert/assert.h +++ b/library/cpp/yt/assert/assert.h @@ -15,6 +15,7 @@ namespace NDetail { void AssertTrapImpl( TStringBuf trapType, TStringBuf expr, + TStringBuf description, TStringBuf file, int line, TStringBuf function); @@ -27,31 +28,47 @@ void AssertTrapImpl( #define YT_BUILTIN_TRAP() std::terminate() #endif -#define YT_ASSERT_TRAP(trapType, expr) \ - ::NYT::NDetail::AssertTrapImpl(TStringBuf(trapType), TStringBuf(expr), __SOURCE_FILE_IMPL__.As<TStringBuf>(), __LINE__, TStringBuf(__FUNCTION__)); \ - Y_UNREACHABLE() \ +#define YT_ASSERT_TRAP_IMPL(trapType, expr, description) \ + ::NYT::NDetail::AssertTrapImpl( \ + TStringBuf(trapType), \ + TStringBuf(expr), \ + TStringBuf(description), \ + __SOURCE_FILE_IMPL__.As<TStringBuf>(), \ + __LINE__, \ + TStringBuf(__FUNCTION__)); \ + Y_UNREACHABLE() +#define YT_ASSERT_TRAP_IMPL_EXTRA_ARG(trapType, expr, description, _) YT_ASSERT_TRAP_IMPL(trapType, expr, description) + +#define YT_ASSERT_TRAP(trapType, expr, ...) \ + YT_ASSERT_TRAP_IMPL##__VA_OPT__(_EXTRA_ARG)(trapType, expr, __VA_OPT__(__VA_ARGS__,) "") + +//! If |expr| is evaluated to false, abnormally terminates the current process in debug mode. +//! Does nothing in release mode. +//! Accepts an optional string argument that will be printed in error with #expr. #ifdef NDEBUG - #define YT_ASSERT(expr) \ + #define YT_ASSERT(expr, ...) \ do { \ if (false) { \ (void) (expr); \ + __VA_OPT__((void)(__VA_ARGS__)); \ } \ } while (false) #else - #define YT_ASSERT(expr) \ + #define YT_ASSERT(expr, ...) \ do { \ if (Y_UNLIKELY(!(expr))) { \ - YT_ASSERT_TRAP("YT_ASSERT", #expr); \ + YT_ASSERT_TRAP("YT_ASSERT", #expr __VA_OPT__(, __VA_ARGS__)); \ } \ } while (false) #endif //! Same as |YT_ASSERT| but evaluates and checks the expression in both release and debug mode. -#define YT_VERIFY(expr) \ +//! Accepts an optional string argument that will be printed in error message with #expr. +#define YT_VERIFY(expr, ...) \ do { \ if (Y_UNLIKELY(!(expr))) { \ - YT_ASSERT_TRAP("YT_VERIFY", #expr); \ + YT_ASSERT_TRAP("YT_VERIFY", #expr __VA_OPT__(, __VA_ARGS__)); \ } \ } while (false) @@ -70,19 +87,21 @@ void AssertTrapImpl( #endif //! Fatal error code marker. Abnormally terminates the current process. +//! Accepts an optional string argument that will be printed in error message. #ifdef YT_COMPILING_UDF - #define YT_ABORT() __YT_BUILTIN_ABORT() + #define YT_ABORT(...) __YT_BUILTIN_ABORT() #else - #define YT_ABORT() \ + #define YT_ABORT(...) \ do { \ - YT_ASSERT_TRAP("YT_ABORT", ""); \ + YT_ASSERT_TRAP("YT_ABORT", "" __VA_OPT__(, __VA_ARGS__)); \ } while (false) #endif //! Unimplemented code marker. Abnormally terminates the current process. -#define YT_UNIMPLEMENTED() \ +//! Accepts an optional string argument that will be printed in error message. +#define YT_UNIMPLEMENTED(...) \ do { \ - YT_ASSERT_TRAP("YT_UNIMPLEMENTED", ""); \ + YT_ASSERT_TRAP("YT_UNIMPLEMENTED", "" __VA_OPT__(, __VA_ARGS__)); \ } while (false) //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/assert/unittests/assert_ut.cpp b/library/cpp/yt/assert/unittests/assert_ut.cpp new file mode 100644 index 00000000000..102f82618b1 --- /dev/null +++ b/library/cpp/yt/assert/unittests/assert_ut.cpp @@ -0,0 +1,98 @@ +#include <yt/yt/core/test_framework/framework.h> + +#include <library/cpp/yt/assert/assert.h> + +namespace NYT { +namespace { + +//////////////////////////////////////////////////////////////////////////////// + +TEST(TAssertTest, Abort) +{ + EXPECT_DEATH( + { + YT_ABORT(); + }, + "YT_ABORT"); + + EXPECT_DEATH( + { + YT_ABORT("MY_PROBLEM"); + }, + "MY_PROBLEM"); +} + +TEST(TAssertTest, Verify) +{ + YT_VERIFY(true); + YT_VERIFY(true, "12345"); + YT_VERIFY(true, [] { + YT_ABORT(); + return "NEVER_PRINTED"; + } ()); + EXPECT_DEATH( + { + YT_VERIFY(false); + }, + "YT_VERIFY"); + EXPECT_DEATH( + { + YT_VERIFY(false, "MY_MESSAGE"); + }, + "YT_VERIFY.*MY_MESSAGE"); + EXPECT_DEATH( + { + YT_VERIFY(false && "my_specific_expression_part", "MY_MESSAGE"); + }, + "false && \"my_specific_expression_part\""); +} + +TEST(TAssertTest, Assert) +{ + YT_ASSERT(true); + YT_ASSERT(true, [] { + YT_ABORT(); + return "NEVER_PRINTED"; + } ()); + #ifndef NDEBUG + EXPECT_DEATH( + { + YT_ASSERT(false); + }, + "YT_ASSERT"); + EXPECT_DEATH( + { + YT_ASSERT(false, "MY_MESSAGE"); + }, + "MY_MESSAGE"); + EXPECT_DEATH( + { + YT_ASSERT(false && "my_specific_expression_part", "MY_MESSAGE"); + }, + "my_specific_expression_part"); + #endif +} + +TEST(TAssertTest, Unimplemented) +{ + EXPECT_DEATH( + { + YT_UNIMPLEMENTED(); + }, + "YT_UNIMPLEMENTED"); +} + +TEST(TAssertTest, AcceptString) +{ + EXPECT_DEATH( + { + YT_ABORT(std::string("MY_PROBLEM")); + }, + "MY_PROBLEM"); +} + + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace +} // namespace NYT diff --git a/library/cpp/yt/assert/unittests/ya.make b/library/cpp/yt/assert/unittests/ya.make new file mode 100644 index 00000000000..01e9479f4cd --- /dev/null +++ b/library/cpp/yt/assert/unittests/ya.make @@ -0,0 +1,13 @@ +GTEST() + +INCLUDE(${ARCADIA_ROOT}/library/cpp/yt/ya_cpp.make.inc) + +PEERDIR( + library/cpp/yt/assert +) + +SRCS( + assert_ut.cpp +) + +END() diff --git a/library/cpp/yt/assert/ya.make b/library/cpp/yt/assert/ya.make index a9833ab70e9..4754d1d39a5 100644 --- a/library/cpp/yt/assert/ya.make +++ b/library/cpp/yt/assert/ya.make @@ -7,3 +7,7 @@ SRCS( ) END() + +RECURSE_FOR_TESTS( + unittests +) |