| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <common/logging.h> |
| #include <bindings/c/hdfs.cc> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include <iostream> |
| |
| using namespace hdfs; |
| |
| struct log_state { |
| int trace_count; |
| int debug_count; |
| int info_count; |
| int warning_count; |
| int error_count; |
| |
| int origin_unknown; |
| int origin_rpc; |
| int origin_blockreader; |
| int origin_filehandle; |
| int origin_filesystem; |
| |
| std::string msg; |
| |
| log_state() { |
| reset(); |
| } |
| |
| void reset() { |
| trace_count = 0; |
| debug_count = 0; |
| info_count = 0; |
| warning_count = 0; |
| error_count = 0; |
| |
| origin_unknown = 0; |
| origin_rpc = 0; |
| origin_blockreader = 0; |
| origin_filehandle = 0; |
| origin_filesystem = 0; |
| |
| msg = ""; |
| } |
| }; |
| log_state log_state_instance; |
| |
| void process_log_msg(LogData *data) { |
| if(data->msg) |
| log_state_instance.msg = data->msg; |
| |
| switch(data->level) { |
| case HDFSPP_LOG_LEVEL_TRACE: |
| log_state_instance.trace_count++; |
| break; |
| case HDFSPP_LOG_LEVEL_DEBUG: |
| log_state_instance.debug_count++; |
| break; |
| case HDFSPP_LOG_LEVEL_INFO: |
| log_state_instance.info_count++; |
| break; |
| case HDFSPP_LOG_LEVEL_WARN: |
| log_state_instance.warning_count++; |
| break; |
| case HDFSPP_LOG_LEVEL_ERROR: |
| log_state_instance.error_count++; |
| break; |
| default: |
| //should never happen |
| std::cout << "foo" << std::endl; |
| ASSERT_FALSE(true); |
| } |
| |
| switch(data->component) { |
| case HDFSPP_LOG_COMPONENT_UNKNOWN: |
| log_state_instance.origin_unknown++; |
| break; |
| case HDFSPP_LOG_COMPONENT_RPC: |
| log_state_instance.origin_rpc++; |
| break; |
| case HDFSPP_LOG_COMPONENT_BLOCKREADER: |
| log_state_instance.origin_blockreader++; |
| break; |
| case HDFSPP_LOG_COMPONENT_FILEHANDLE: |
| log_state_instance.origin_filehandle++; |
| break; |
| case HDFSPP_LOG_COMPONENT_FILESYSTEM: |
| log_state_instance.origin_filesystem++; |
| break; |
| default: |
| std::cout << "bar" << std::endl; |
| ASSERT_FALSE(true); |
| } |
| |
| } |
| |
| void reset_log_counters() { |
| log_state_instance.reset(); |
| } |
| |
| void assert_nothing_logged() { |
| if(log_state_instance.trace_count || log_state_instance.debug_count || |
| log_state_instance.info_count || log_state_instance.warning_count || |
| log_state_instance.error_count) { |
| ASSERT_FALSE(true); |
| } |
| } |
| |
| void assert_trace_logged() { ASSERT_TRUE(log_state_instance.trace_count > 0); } |
| void assert_debug_logged() { ASSERT_TRUE(log_state_instance.debug_count > 0); } |
| void assert_info_logged() { ASSERT_TRUE(log_state_instance.info_count > 0); } |
| void assert_warning_logged() { ASSERT_TRUE(log_state_instance.warning_count > 0); } |
| void assert_error_logged() { ASSERT_TRUE(log_state_instance.error_count > 0); } |
| |
| void assert_no_trace_logged() { ASSERT_EQ(log_state_instance.trace_count, 0); } |
| void assert_no_debug_logged() { ASSERT_EQ(log_state_instance.debug_count, 0); } |
| void assert_no_info_logged() { ASSERT_EQ(log_state_instance.info_count, 0); } |
| void assert_no_warning_logged() { ASSERT_EQ(log_state_instance.warning_count, 0); } |
| void assert_no_error_logged() { ASSERT_EQ(log_state_instance.error_count, 0); } |
| |
| void assert_unknown_logged() { ASSERT_TRUE(log_state_instance.origin_unknown > 0); } |
| void assert_rpc_logged() { ASSERT_TRUE(log_state_instance.origin_rpc > 0); } |
| void assert_blockreader_logged() { ASSERT_TRUE(log_state_instance.origin_blockreader > 0); } |
| void assert_filehandle_logged() { ASSERT_TRUE(log_state_instance.origin_filehandle > 0); } |
| void assert_filesystem_logged() { ASSERT_TRUE(log_state_instance.origin_filesystem > 0); } |
| |
| void assert_no_unknown_logged() { ASSERT_EQ(log_state_instance.origin_unknown, 0); } |
| void assert_no_rpc_logged() { ASSERT_EQ(log_state_instance.origin_rpc, 0); } |
| void assert_no_blockreader_logged() { ASSERT_EQ(log_state_instance.origin_blockreader, 0); } |
| void assert_no_filehandle_logged() { ASSERT_EQ(log_state_instance.origin_filehandle, 0); } |
| void assert_no_filesystem_logged() { ASSERT_EQ(log_state_instance.origin_filesystem, 0); } |
| |
| void log_all_components_at_level(LogLevel lvl) { |
| if(lvl == kTrace) { |
| LOG_TRACE(kUnknown, << 'a'); |
| LOG_TRACE(kRPC, << 'b'); |
| LOG_TRACE(kBlockReader, << 'c'); |
| LOG_TRACE(kFileHandle, << 'd'); |
| LOG_TRACE(kFileSystem, << 'e'); |
| } else if (lvl == kDebug) { |
| LOG_DEBUG(kUnknown, << 'a'); |
| LOG_DEBUG(kRPC, << 'b'); |
| LOG_DEBUG(kBlockReader, << 'c'); |
| LOG_DEBUG(kFileHandle, << 'd'); |
| LOG_DEBUG(kFileSystem, << 'e'); |
| } else if (lvl == kInfo) { |
| LOG_INFO(kUnknown, << 'a'); |
| LOG_INFO(kRPC, << 'b'); |
| LOG_INFO(kBlockReader, << 'c'); |
| LOG_INFO(kFileHandle, << 'd'); |
| LOG_INFO(kFileSystem, << 'e'); |
| } else if (lvl == kWarning) { |
| LOG_WARN(kUnknown, << 'a'); |
| LOG_WARN(kRPC, << 'b'); |
| LOG_WARN(kBlockReader, << 'c'); |
| LOG_WARN(kFileHandle, << 'd'); |
| LOG_WARN(kFileSystem, << 'e'); |
| } else if (lvl == kError) { |
| LOG_ERROR(kUnknown, << 'a'); |
| LOG_ERROR(kRPC, << 'b'); |
| LOG_ERROR(kBlockReader, << 'c'); |
| LOG_ERROR(kFileHandle, << 'd'); |
| LOG_ERROR(kFileSystem, << 'e'); |
| } else { |
| // A level was added and not accounted for here |
| ASSERT_TRUE(false); |
| } |
| } |
| |
| // make sure everything can be masked |
| TEST(LoggingTest, MaskAll) { |
| LogManager::DisableLogForComponent(kUnknown); |
| LogManager::DisableLogForComponent(kRPC); |
| LogManager::DisableLogForComponent(kBlockReader); |
| LogManager::DisableLogForComponent(kFileHandle); |
| LogManager::DisableLogForComponent(kFileSystem); |
| |
| // use trace so anything that isn't masked should come through |
| LogManager::SetLogLevel(kTrace); |
| log_state_instance.reset(); |
| log_all_components_at_level(kError); |
| assert_nothing_logged(); |
| log_state_instance.reset(); |
| } |
| |
| // make sure components can be masked individually |
| TEST(LoggingTest, MaskOne) { |
| LogManager::DisableLogForComponent(kUnknown); |
| LogManager::DisableLogForComponent(kRPC); |
| LogManager::DisableLogForComponent(kBlockReader); |
| LogManager::DisableLogForComponent(kFileHandle); |
| LogManager::DisableLogForComponent(kFileSystem); |
| LogManager::SetLogLevel(kTrace); |
| |
| // Unknown - aka component not provided |
| LogManager::EnableLogForComponent(kUnknown); |
| log_all_components_at_level(kError); |
| assert_unknown_logged(); |
| assert_error_logged(); |
| assert_no_rpc_logged(); |
| assert_no_blockreader_logged(); |
| assert_no_filehandle_logged(); |
| assert_no_filesystem_logged(); |
| log_state_instance.reset(); |
| LogManager::DisableLogForComponent(kUnknown); |
| |
| // RPC |
| LogManager::EnableLogForComponent(kRPC); |
| log_all_components_at_level(kError); |
| assert_rpc_logged(); |
| assert_error_logged(); |
| assert_no_unknown_logged(); |
| assert_no_blockreader_logged(); |
| assert_no_filehandle_logged(); |
| assert_no_filesystem_logged(); |
| log_state_instance.reset(); |
| LogManager::DisableLogForComponent(kRPC); |
| |
| // BlockReader |
| LogManager::EnableLogForComponent(kBlockReader); |
| log_all_components_at_level(kError); |
| assert_blockreader_logged(); |
| assert_error_logged(); |
| assert_no_unknown_logged(); |
| assert_no_rpc_logged(); |
| assert_no_filehandle_logged(); |
| assert_no_filesystem_logged(); |
| log_state_instance.reset(); |
| LogManager::DisableLogForComponent(kBlockReader); |
| |
| // FileHandle |
| LogManager::EnableLogForComponent(kFileHandle); |
| log_all_components_at_level(kError); |
| assert_filehandle_logged(); |
| assert_error_logged(); |
| assert_no_unknown_logged(); |
| assert_no_rpc_logged(); |
| assert_no_blockreader_logged(); |
| assert_no_filesystem_logged(); |
| log_state_instance.reset(); |
| LogManager::DisableLogForComponent(kFileHandle); |
| |
| // FileSystem |
| LogManager::EnableLogForComponent(kFileSystem); |
| log_all_components_at_level(kError); |
| assert_filesystem_logged(); |
| assert_error_logged(); |
| assert_no_unknown_logged(); |
| assert_no_rpc_logged(); |
| assert_no_blockreader_logged(); |
| assert_no_filehandle_logged(); |
| log_state_instance.reset(); |
| LogManager::DisableLogForComponent(kFileSystem); |
| } |
| |
| TEST(LoggingTest, Levels) { |
| // should be safe to focus on one component if MaskOne passes |
| LogManager::EnableLogForComponent(kUnknown); |
| LogManager::SetLogLevel(kError); |
| |
| LOG_TRACE(kUnknown, << "a"); |
| LOG_DEBUG(kUnknown, << "b"); |
| LOG_INFO(kUnknown,<< "c"); |
| LOG_WARN(kUnknown, << "d"); |
| assert_nothing_logged(); |
| LOG_ERROR(kUnknown, << "e"); |
| assert_error_logged(); |
| assert_unknown_logged(); |
| log_state_instance.reset(); |
| |
| // anything >= warning |
| LogManager::SetLogLevel(kWarning); |
| LOG_TRACE(kUnknown, << "a"); |
| LOG_DEBUG(kUnknown, << "b"); |
| LOG_INFO(kUnknown, << "c"); |
| assert_nothing_logged(); |
| LOG_WARN(kUnknown, << "d"); |
| assert_warning_logged(); |
| LOG_ERROR(kUnknown, << "e"); |
| assert_error_logged(); |
| log_state_instance.reset(); |
| |
| // anything >= info |
| LogManager::SetLogLevel(kInfo); |
| LOG_TRACE(kUnknown, << "a"); |
| LOG_DEBUG(kUnknown, << "b"); |
| assert_nothing_logged(); |
| LOG_INFO(kUnknown, << "c"); |
| assert_info_logged(); |
| LOG_WARN(kUnknown, << "d"); |
| assert_warning_logged(); |
| LOG_ERROR(kUnknown, << "e"); |
| assert_error_logged(); |
| log_state_instance.reset(); |
| |
| // anything >= debug |
| LogManager::SetLogLevel(kDebug); |
| LOG_TRACE(kUnknown, << "a"); |
| assert_nothing_logged(); |
| LOG_DEBUG(kUnknown, << "b"); |
| assert_debug_logged(); |
| assert_no_info_logged(); |
| assert_no_warning_logged(); |
| assert_no_error_logged(); |
| LOG_INFO(kUnknown, << "c"); |
| assert_info_logged(); |
| assert_no_warning_logged(); |
| assert_no_error_logged(); |
| LOG_WARN(kUnknown, << "d"); |
| assert_warning_logged(); |
| assert_no_error_logged(); |
| LOG_ERROR(kUnknown, << "e"); |
| assert_error_logged(); |
| log_state_instance.reset(); |
| |
| // anything |
| LogManager::SetLogLevel(kTrace); |
| assert_nothing_logged(); |
| LOG_TRACE(kUnknown, << "a"); |
| assert_trace_logged(); |
| log_state_instance.reset(); |
| LOG_DEBUG(kUnknown, << "b"); |
| assert_debug_logged(); |
| log_state_instance.reset(); |
| LOG_INFO(kUnknown, << "c"); |
| assert_info_logged(); |
| log_state_instance.reset(); |
| LOG_WARN(kUnknown, << "d"); |
| assert_warning_logged(); |
| log_state_instance.reset(); |
| LOG_ERROR(kUnknown, << "e"); |
| assert_error_logged(); |
| } |
| |
| TEST(LoggingTest, Text) { |
| LogManager::EnableLogForComponent(kRPC); |
| |
| std::string text; |
| LOG_ERROR(kRPC, << text); |
| |
| ASSERT_EQ(text, log_state_instance.msg); |
| } |
| |
| |
| int main(int argc, char *argv[]) { |
| CForwardingLogger *logger = new CForwardingLogger(); |
| logger->SetCallback(process_log_msg); |
| LogManager::SetLoggerImplementation(std::unique_ptr<LoggerInterface>(logger)); |
| |
| // The following line must be executed to initialize Google Mock |
| // (and Google Test) before running the tests. |
| ::testing::InitGoogleMock(&argc, argv); |
| int res = RUN_ALL_TESTS(); |
| google::protobuf::ShutdownProtobufLibrary(); |
| return res; |
| } |