Path: blob/master/test/hotspot/gtest/logging/test_logMessageTest.cpp
41145 views
/*1* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "jvm.h"25#include "logTestFixture.hpp"26#include "logTestUtils.inline.hpp"27#include "logging/log.hpp"28#include "logging/logMessage.hpp"29#include "memory/allocation.inline.hpp"30#include "unittest.hpp"31#include "utilities/globalDefinitions.hpp"3233class LogMessageTest : public LogTestFixture {34protected:35static Log(logging) _log;36static const char* _level_filename[];37LogMessageTest();38~LogMessageTest();39};4041Log(logging) LogMessageTest::_log;4243const char* LogMessageTest::_level_filename[] = {44NULL, // LogLevel::Off45#define LOG_LEVEL(name, printname) "multiline-" #printname ".log",46LOG_LEVEL_LIST47#undef LOG_LEVEL48};4950LogMessageTest::LogMessageTest() {51for (int i = 0; i < LogLevel::Count; i++) {52char buf[32];53// Attempt to remove possibly pre-existing log files54remove(_level_filename[i]);5556jio_snprintf(buf, sizeof(buf), "logging=%s", LogLevel::name(static_cast<LogLevelType>(i)));57set_log_config(_level_filename[i], buf);58}59}6061LogMessageTest::~LogMessageTest() {62// Stop logging to the files and remove them.63for (int i = 0; i < LogLevel::Count; i++) {64set_log_config(_level_filename[i], "all=off");65remove(_level_filename[i]);66}67}6869// Verify that messages with multiple levels are written70// to outputs configured for all the corresponding levels71TEST_VM_F(LogMessageTest, level_inclusion) {72const size_t message_count = 10;73LogMessageBuffer msg[message_count];7475struct {76int message_number;77LogLevelType level;78} lines[] = {79{ 0, LogLevel::Error },80{ 1, LogLevel::Info },81{ 2, LogLevel::Info }, { 2, LogLevel::Debug },82{ 3, LogLevel::Info }, { 3, LogLevel::Warning },83{ 4, LogLevel::Debug }, { 4, LogLevel::Warning },84{ 5, LogLevel::Trace }, { 5, LogLevel::Debug },85{ 6, LogLevel::Warning }, { 6, LogLevel::Error },86{ 7, LogLevel::Trace }, { 7, LogLevel::Info }, { 7, LogLevel::Debug },87{ 8, LogLevel::Trace }, { 8, LogLevel::Debug }, { 8, LogLevel::Info },88{ 8, LogLevel::Warning }, { 8, LogLevel::Error},89{ 9, LogLevel::Trace }90};9192// Fill in messages with the above lines93for (size_t i = 0; i < ARRAY_SIZE(lines); i++) {94switch (lines[i].level) {95#define LOG_LEVEL(name, printname) \96case LogLevel::name: \97msg[lines[i].message_number].printname("msg[%d]: " #printname, lines[i].message_number); \98break;99LOG_LEVEL_LIST100#undef LOG_LEVEL101default:102break;103}104}105106for (size_t i = 0; i < message_count; i++) {107_log.write(msg[i]);108}109110// Verify that lines are written to the expected log files111for (size_t i = 0; i < ARRAY_SIZE(lines); i++) {112char expected[256];113jio_snprintf(expected, sizeof(expected), "msg[%d]: %s",114lines[i].message_number, LogLevel::name(lines[i].level));115for (int level = lines[i].level; level > 0; level--) {116EXPECT_TRUE(file_contains_substring(_level_filename[level], expected))117<< "line #" << i << " missing from log file " << _level_filename[level];118}119for (int level = lines[i].level + 1; level < LogLevel::Count; level++) {120EXPECT_FALSE(file_contains_substring(_level_filename[level], expected))121<< "line #" << i << " erroneously included in log file " << _level_filename[level];122}123}124}125126// Verify that messages are logged in the order they are added to the log message127TEST_VM_F(LogMessageTest, line_order) {128LogMessageBuffer msg;129msg.info("info line").error("error line").trace("trace line")130.error("another error").warning("warning line").debug("debug line");131_log.write(msg);132133const char* expected[] = { "info line", "error line", "trace line",134"another error", "warning line", "debug line", NULL };135EXPECT_TRUE(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected))136<< "output missing or in incorrect order";137}138139TEST_VM_F(LogMessageTest, long_message) {140// Write 10K bytes worth of log data141LogMessageBuffer msg;142const size_t size = 10 * K;143const char* start_marker = "#start#";144const char* end_marker = "#the end#";145char* data = NEW_C_HEAP_ARRAY(char, size, mtLogging);146147// fill buffer with start_marker...some data...end_marker148sprintf(data, "%s", start_marker);149for (size_t i = strlen(start_marker); i < size; i++) {150data[i] = '0' + (i % 10);151}152sprintf(data + size - strlen(end_marker) - 1, "%s", end_marker);153154msg.trace("%s", data); // Adds a newline, making the message exactly 10K in length.155_log.write(msg);156157const char* expected[] = { start_marker, "0123456789", end_marker, NULL };158EXPECT_TRUE(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected))159<< "unable to print long line";160FREE_C_HEAP_ARRAY(char, data);161}162163TEST_VM_F(LogMessageTest, message_with_many_lines) {164const size_t lines = 100;165const size_t line_length = 16;166167LogMessageBuffer msg;168for (size_t i = 0; i < lines; i++) {169msg.info("Line #" SIZE_FORMAT, i);170}171_log.write(msg);172173char expected_lines_data[lines][line_length];174const char* expected_lines[lines + 1];175for (size_t i = 0; i < lines; i++) {176jio_snprintf(&expected_lines_data[i][0], line_length, "Line #" SIZE_FORMAT, i);177expected_lines[i] = expected_lines_data[i];178}179expected_lines[lines] = NULL;180181EXPECT_TRUE(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected_lines))182<< "couldn't find all lines in multiline message";183}184185static size_t dummy_prefixer(char* buf, size_t len) {186static int i = 0;187const char* prefix = "some prefix: ";188const size_t prefix_len = strlen(prefix);189if (len < prefix_len) {190return prefix_len;191}192jio_snprintf(buf, len, "%s", prefix);193return prefix_len;194}195196TEST_VM_F(LogMessageTest, prefixing) {197LogMessageBuffer msg;198msg.set_prefix(dummy_prefixer);199for (int i = 0; i < 3; i++) {200msg.info("test %d", i);201}202msg.set_prefix(NULL);203msg.info("test 3");204_log.write(msg);205206const char* expected[] = {207"] some prefix: test 0",208"] some prefix: test 1",209"] some prefix: test 2",210"] test 3",211NULL212};213EXPECT_TRUE(file_contains_substrings_in_order(_level_filename[LogLevel::Trace], expected))214<< "error in prefixed output";215}216217TEST_VM_F(LogMessageTest, scoped_messages) {218{219LogMessage(logging) msg;220msg.info("scoped info");221msg.warning("scoped warn");222EXPECT_FALSE(file_contains_substring(_level_filename[LogLevel::Info], "scoped info"))223<< "scoped log message written prematurely";224}225EXPECT_TRUE(file_contains_substring(_level_filename[LogLevel::Info], "scoped info"))226<< "missing output from scoped log message";227EXPECT_TRUE(file_contains_substring(_level_filename[LogLevel::Warning], "scoped warn"))228<< "missing output from scoped log message";229}230231TEST_VM_F(LogMessageTest, scoped_flushing) {232{233LogMessage(logging) msg;234msg.info("manual flush info");235msg.flush();236EXPECT_TRUE(file_contains_substring(_level_filename[LogLevel::Info], "manual flush info"))237<< "missing output from manually flushed scoped log message";238}239const char* tmp[] = {"manual flush info", "manual flush info", NULL};240EXPECT_FALSE(file_contains_substrings_in_order(_level_filename[LogLevel::Info], tmp))241<< "log file contains duplicate lines from single scoped log message";242}243244TEST_VM_F(LogMessageTest, scoped_reset) {245{246LogMessage(logging) msg, partial;247msg.info("%s", "info reset msg");248msg.reset();249partial.info("%s", "info reset msg");250partial.reset();251partial.trace("%s", "trace reset msg");252}253EXPECT_FALSE(file_contains_substring(_level_filename[LogLevel::Info], "info reset msg"))254<< "reset message written anyway";255EXPECT_TRUE(file_contains_substring(_level_filename[LogLevel::Trace], "trace reset msg"))256<< "missing message from partially reset scoped log message";257}258259260