1- // Test for logging functionality.
2- // This test verifies that the logging system works correctly with different
3- // log levels, formats, and macros.
4-
51#include " ut/ut.hpp"
62#include < luisa/core/logging.h>
73#include < luisa/core/stl/string.h>
84#include < luisa/core/stl/vector.h>
5+ #include < mutex>
96
107using namespace boost ::ut;
118using namespace boost ::ut::literals;
129
13- // Simple test to verify logging doesn't crash and produces output
10+ #ifndef LUISA_CUSTOM_LOGGER
11+
12+ struct CapturedMessage {
13+ luisa::string level;
14+ luisa::string message;
15+ };
16+
17+ static inline const auto _reg_logging_custom_sink = [] {
18+ " logging_custom_sink_captures_messages" _test = [] {
19+ std::mutex mtx;
20+ luisa::vector<CapturedMessage> captured;
21+
22+ auto sink = luisa::detail::create_sink_with_callback (
23+ [&](const char *level, const char *message) {
24+ std::lock_guard lock{mtx};
25+ captured.push_back ({luisa::string{level}, luisa::string{message}});
26+ });
27+
28+ auto &logger = luisa::detail::default_logger ();
29+ auto original_sinks = logger.sinks ();
30+ logger.sinks ().clear ();
31+ logger.sinks ().push_back (sink);
32+ luisa::log_level_verbose ();
33+
34+ luisa::log_verbose (" verbose_msg_42" );
35+ luisa::log_info (" info_msg_100" );
36+ luisa::log_warning (" warning_msg_xyz" );
37+ luisa::log_flush ();
38+
39+ logger.sinks () = original_sinks;
40+ luisa::log_level_verbose ();
41+
42+ expect (captured.size () >= 3u ) << " expected at least 3 captured messages, got " << captured.size ();
43+
44+ bool found_verbose = false , found_info = false , found_warning = false ;
45+ for (auto &cm : captured) {
46+ if (cm.message .find (" verbose_msg_42" ) != luisa::string::npos) found_verbose = true ;
47+ if (cm.message .find (" info_msg_100" ) != luisa::string::npos) found_info = true ;
48+ if (cm.message .find (" warning_msg_xyz" ) != luisa::string::npos) found_warning = true ;
49+ }
50+ expect (found_verbose) << " custom sink should capture verbose message" ;
51+ expect (found_info) << " custom sink should capture info message" ;
52+ expect (found_warning) << " custom sink should capture warning message" ;
53+ };
54+ return 0 ;
55+ }();
56+
57+ static inline const auto _reg_logging_level_filtering = [] {
58+ " logging_level_filtering_via_sink" _test = [] {
59+ std::mutex mtx;
60+ luisa::vector<CapturedMessage> captured;
61+
62+ auto sink = luisa::detail::create_sink_with_callback (
63+ [&](const char *level, const char *message) {
64+ std::lock_guard lock{mtx};
65+ captured.push_back ({luisa::string{level}, luisa::string{message}});
66+ });
67+
68+ auto &logger = luisa::detail::default_logger ();
69+ auto original_sinks = logger.sinks ();
70+ logger.sinks ().clear ();
71+ logger.sinks ().push_back (sink);
72+
73+ luisa::log_level_warning ();
74+ captured.clear ();
75+
76+ luisa::log_verbose (" should_be_filtered_verbose" );
77+ luisa::log_info (" should_be_filtered_info" );
78+ luisa::log_warning (" should_appear_warning" );
79+ luisa::log_flush ();
80+
81+ logger.sinks () = original_sinks;
82+ luisa::log_level_verbose ();
83+
84+ bool found_filtered_verbose = false ;
85+ bool found_filtered_info = false ;
86+ bool found_warning = false ;
87+ for (auto &cm : captured) {
88+ if (cm.message .find (" should_be_filtered_verbose" ) != luisa::string::npos) found_filtered_verbose = true ;
89+ if (cm.message .find (" should_be_filtered_info" ) != luisa::string::npos) found_filtered_info = true ;
90+ if (cm.message .find (" should_appear_warning" ) != luisa::string::npos) found_warning = true ;
91+ }
92+ expect (!found_filtered_verbose) << " verbose should be filtered at warning level" ;
93+ expect (!found_filtered_info) << " info should be filtered at warning level" ;
94+ expect (found_warning) << " warning should pass at warning level" ;
95+ };
96+ return 0 ;
97+ }();
98+
99+ static inline const auto _reg_logging_add_sink = [] {
100+ " logging_add_sink_preserves_existing" _test = [] {
101+ std::mutex mtx;
102+ luisa::vector<CapturedMessage> captured;
103+
104+ auto sink = luisa::detail::create_sink_with_callback (
105+ [&](const char *level, const char *message) {
106+ std::lock_guard lock{mtx};
107+ captured.push_back ({luisa::string{level}, luisa::string{message}});
108+ });
109+
110+ luisa::detail::default_logger_add_sink (sink);
111+ luisa::log_level_verbose ();
112+
113+ luisa::log_info (" add_sink_test_msg" );
114+ luisa::log_flush ();
115+
116+ auto &sinks = luisa::detail::default_logger ().sinks ();
117+ sinks.erase (std::remove (sinks.begin (), sinks.end (), sink), sinks.end ());
118+
119+ bool found = false ;
120+ for (auto &cm : captured) {
121+ if (cm.message .find (" add_sink_test_msg" ) != luisa::string::npos) found = true ;
122+ }
123+ expect (found) << " added sink should capture messages alongside default sink" ;
124+ };
125+ return 0 ;
126+ }();
127+
128+ static inline const auto _reg_logging_formatted_args = [] {
129+ " logging_formatted_args_in_sink" _test = [] {
130+ std::mutex mtx;
131+ luisa::vector<CapturedMessage> captured;
132+
133+ auto sink = luisa::detail::create_sink_with_callback (
134+ [&](const char *level, const char *message) {
135+ std::lock_guard lock{mtx};
136+ captured.push_back ({luisa::string{level}, luisa::string{message}});
137+ });
138+
139+ auto &logger = luisa::detail::default_logger ();
140+ auto original_sinks = logger.sinks ();
141+ logger.sinks ().clear ();
142+ logger.sinks ().push_back (sink);
143+ luisa::log_level_verbose ();
144+
145+ luisa::log_info (" answer is {}" , 42 );
146+ luisa::log_info (" pi is {:.2f}" , 3.14159 );
147+ luisa::log_info (" bool={}, str={}" , true , " hello" );
148+ luisa::log_flush ();
149+
150+ logger.sinks () = original_sinks;
151+ luisa::log_level_verbose ();
152+
153+ bool found_42 = false , found_pi = false , found_bool = false ;
154+ for (auto &cm : captured) {
155+ if (cm.message .find (" answer is 42" ) != luisa::string::npos) found_42 = true ;
156+ if (cm.message .find (" pi is 3.14" ) != luisa::string::npos) found_pi = true ;
157+ if (cm.message .find (" bool=true" ) != luisa::string::npos) found_bool = true ;
158+ }
159+ expect (found_42) << " formatted int arg should appear in sink" ;
160+ expect (found_pi) << " formatted float arg should appear in sink" ;
161+ expect (found_bool) << " formatted bool/string args should appear in sink" ;
162+ };
163+ return 0 ;
164+ }();
165+
166+ #endif
167+
14168static inline const auto _luisa_reg_logging_basic_functionality = [] {
15- boost::ut::detail::test{ " test " , " logging basic functionality " } = [] {
16- // Test basic log functions with simple messages
169+ " logging_basic_no_crash " _test = [] {
170+ luisa::log_level_verbose ();
17171 luisa::log_verbose (" Verbose message from test" );
18172 luisa::log_info (" Info message from test" );
19173 luisa::log_warning (" Warning message from test" );
20-
21- // Test formatted log messages
22174 luisa::log_verbose (" Verbose with args: {}, {}" , 42 , 3.14 );
23175 luisa::log_info (" Info with args: {}, {}" , " test_string" , true );
24176 luisa::log_warning (" Warning with args: {}, {}" , ' a' , 123u );
25-
26- // Test flush
27177 luisa::log_flush ();
178+ expect (true ) << " basic logging calls completed without crash" ;
28179 };
29180 return 0 ;
30181}();
31182
32183static inline const auto _luisa_reg_logging_macros = [] {
33- boost::ut::detail::test{ " test " , " logging macros " } = [] {
34- // Test all logging macros
184+ " logging_macros_no_crash " _test = [] {
185+ luisa::log_level_verbose ();
35186 LUISA_VERBOSE (" Macro verbose message" );
36187 LUISA_INFO (" Macro info message" );
37188 LUISA_WARNING (" Macro warning message" );
38-
39- // Test macros with format arguments
40189 LUISA_VERBOSE (" Verbose macro: {}, {}" , 1 , 2 );
41190 LUISA_INFO (" Info macro: {}, {}, {}" , " a" , " b" , " c" );
42191 LUISA_WARNING (" Warning macro: value = {}" , 3.14159 );
192+ expect (true ) << " logging macros completed without crash" ;
43193 };
44194 return 0 ;
45195}();
46196
47197static inline const auto _luisa_reg_logging_with_location_macros = [] {
48- boost::ut::detail::test{ " test " , " logging with location macros " } = [] {
49- // Test location macros
198+ " logging_location_macros_no_crash " _test = [] {
199+ luisa::log_level_verbose ();
50200 LUISA_VERBOSE_WITH_LOCATION (" Verbose with location: {}" , 100 );
51201 LUISA_INFO_WITH_LOCATION (" Info with location: {}" , 200 );
52202 LUISA_WARNING_WITH_LOCATION (" Warning with location: {}" , 300 );
203+ expect (true ) << " location macros completed without crash" ;
53204 };
54205 return 0 ;
55206}();
56207
57- static inline const auto _luisa_reg_logging_log_level_changes = [] {
58- boost::ut::detail::test{" test" , " logging log level changes" } = [] {
59- // Save current log level (we can't query it, but we can test setting doesn't crash)
60-
61- // Test all log level functions
208+ static inline const auto _luisa_reg_logging_log_level_transitions = [] {
209+ " logging_level_transitions_no_crash" _test = [] {
62210 luisa::log_level_verbose ();
63- LUISA_VERBOSE (" This verbose should be visible after log_level_verbose()" );
64-
65211 luisa::log_level_info ();
66- LUISA_VERBOSE (" This verbose should be hidden after log_level_info()" );
67- LUISA_INFO (" This info should be visible after log_level_info()" );
68-
69212 luisa::log_level_warning ();
70- LUISA_VERBOSE (" This verbose should be hidden after log_level_warning()" );
71- LUISA_INFO (" This info should be hidden after log_level_warning()" );
72- LUISA_WARNING (" This warning should be visible after log_level_warning()" );
73-
74213 luisa::log_level_error ();
75- LUISA_VERBOSE (" This verbose should be hidden after log_level_error()" );
76- LUISA_INFO (" This info should be hidden after log_level_error()" );
77- LUISA_WARNING (" This warning should be hidden after log_level_error()" );
78-
79- // Reset to verbose for other tests
214+ luisa::log_level_verbose ();
215+ luisa::log_level_warning ();
216+ luisa::log_level_info ();
80217 luisa::log_level_verbose ();
81218 luisa::log_flush ();
219+ expect (true ) << " rapid level transitions completed without crash" ;
82220 };
83221 return 0 ;
84222}();
85223
86224static inline const auto _luisa_reg_logging_complex_format_strings = [] {
87- boost::ut::detail::test{ " test " , " logging complex format strings " } = [] {
88- // Test various format specifiers
225+ " logging_complex_format_strings " _test = [] {
226+ luisa::log_level_verbose ();
89227 LUISA_INFO (" Integer: {}" , -123456 );
90228 LUISA_INFO (" Unsigned: {}" , 123456u );
91229 LUISA_INFO (" Float: {}" , 3 .14159265f );
@@ -97,27 +235,24 @@ static inline const auto _luisa_reg_logging_complex_format_strings = [] {
97235 LUISA_INFO (" Binary: {:b}" , 170 );
98236 LUISA_INFO (" Scientific: {:e}" , 12345.6789 );
99237 LUISA_INFO (" Fixed: {:.2f}" , 3.14159 );
238+ expect (true ) << " complex format strings completed without crash" ;
100239 };
101240 return 0 ;
102241}();
103242
104243static inline const auto _luisa_reg_logging_empty_and_special_messages = [] {
105- boost::ut::detail::test{ " test " , " logging empty and special messages " } = [] {
106- // Test empty message (via format)
244+ " logging_empty_and_special_messages " _test = [] {
245+ luisa::log_level_verbose ();
107246 LUISA_INFO (" " );
108-
109- // Test message with special characters
110247 LUISA_INFO (" Special chars: \t\n\r !@#$%^&*()_+-=[]{}|;':\" ,./<>?" );
111-
112- // Test message with braces
113248 LUISA_INFO (" Braces: {{escaped}}, {{{{nested}}}}" );
114249
115- // Test long message
116250 luisa::string long_message;
117251 for (int i = 0 ; i < 100 ; ++i) {
118252 long_message += " This is a long message repeated multiple times. " ;
119253 }
120254 LUISA_INFO (" Long message: {}" , long_message);
255+ expect (long_message.size () > 4000u ) << " long message should be substantial" ;
121256 };
122257 return 0 ;
123258}();
0 commit comments