| /* | |
| * 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 "logunit.h" | |
| #include <log4cxx/logger.h> | |
| #include <log4cxx/jsonlayout.h> | |
| #include <log4cxx/ndc.h> | |
| #include <log4cxx/mdc.h> | |
| #include <log4cxx/private/layout_priv.h> | |
| #include <iostream> | |
| #include <limits> | |
| #include <log4cxx/helpers/stringhelper.h> | |
| #include <log4cxx/helpers/transcoder.h> | |
| using namespace log4cxx; | |
| using namespace log4cxx::helpers; | |
| using namespace log4cxx::spi; | |
| #if defined(__LOG4CXX_FUNC__) | |
| #undef __LOG4CXX_FUNC__ | |
| #define __LOG4CXX_FUNC__ "X::X()" | |
| #else | |
| #error __LOG4CXX_FUNC__ expected to be defined | |
| #endif | |
| static LogString ppIndentL1(LOG4CXX_STR(" ")); | |
| static LogString ppIndentL2(LOG4CXX_STR(" ")); | |
| /** | |
| * Test for JSONLayout. | |
| * | |
| */ | |
| LOGUNIT_CLASS(JSONLayoutTest), public JSONLayout | |
| { | |
| LOGUNIT_TEST_SUITE(JSONLayoutTest); | |
| LOGUNIT_TEST(testGetContentType); | |
| LOGUNIT_TEST(testIgnoresThrowable); | |
| LOGUNIT_TEST(testAppendQuotedEscapedStringWithPrintableChars); | |
| LOGUNIT_TEST(testAppendQuotedEscapedStringWithControlChars); | |
| #if LOG4CXX_LOGCHAR_IS_UTF8 | |
| LOGUNIT_TEST(testAppendQuotedEscapedStringWithInvalidByte); | |
| #endif | |
| LOGUNIT_TEST(testAppendSerializedMDC); | |
| LOGUNIT_TEST(testAppendSerializedMDCWithPrettyPrint); | |
| LOGUNIT_TEST(testAppendSerializedNDC); | |
| LOGUNIT_TEST(testAppendSerializedNDCWithPrettyPrint); | |
| LOGUNIT_TEST(testAppendSerializedLocationInfo); | |
| LOGUNIT_TEST(testAppendSerializedLocationInfoWithPrettyPrint); | |
| LOGUNIT_TEST(testFormat); | |
| LOGUNIT_TEST(testFormatWithPrettyPrint); | |
| LOGUNIT_TEST(testGetSetLocationInfo); | |
| LOGUNIT_TEST(testAppendQuotedEscapedString); | |
| LOGUNIT_TEST(testLayoutSizeOverflowGuards); | |
| LOGUNIT_TEST(testLayoutSizeEdgeCases); | |
| LOGUNIT_TEST(testReserveFormattedEventSizing); | |
| LOGUNIT_TEST_SUITE_END(); | |
| public: | |
| /** | |
| * Clear MDC and NDC before test. | |
| */ | |
| void setUp() | |
| { | |
| NDC::clear(); | |
| MDC::clear(); | |
| } | |
| /** | |
| * Clear MDC and NDC after test. | |
| */ | |
| void tearDown() | |
| { | |
| setUp(); | |
| } | |
| public: | |
| /** | |
| * Tests getContentType. | |
| */ | |
| void testGetContentType() | |
| { | |
| LogString expected(LOG4CXX_STR("application/json")); | |
| LogString actual(JSONLayout().getContentType()); | |
| LOGUNIT_ASSERT(expected == actual); | |
| } | |
| /** | |
| * Tests ignoresThrowable. | |
| */ | |
| void testIgnoresThrowable() | |
| { | |
| LOGUNIT_ASSERT_EQUAL(false, JSONLayout().ignoresThrowable()); | |
| } | |
| /** | |
| * Tests appendQuotedEscapedString with printable characters. | |
| */ | |
| void testAppendQuotedEscapedStringWithPrintableChars() | |
| { | |
| LogString s1(LOG4CXX_STR("foo")); /* foo */ | |
| LogString s2; | |
| appendQuotedEscapedString(s2, s1); /* "foo" */ | |
| LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"foo\""), s2); | |
| LogString s3; | |
| appendQuotedEscapedString(s3, s2); /* "\"foo\"" */ | |
| LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"\\\"foo\\\"\""), s3); | |
| LogString t1(LOG4CXX_STR("bar\"baz")); /* bar"baz */ | |
| LogString t2; | |
| appendQuotedEscapedString(t2, t1); /* "bar\"baz" */ | |
| LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"bar\\\"baz\""), t2); | |
| LogString t3; | |
| appendQuotedEscapedString(t3, t2); /* "\"bar\\\"baz\"" */ | |
| LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("\"\\\"bar\\\\\\\"baz\\\"\""), t3); | |
| } | |
| /** | |
| * Tests appendQuotedEscapedString with control characters. | |
| */ | |
| void testAppendQuotedEscapedStringWithControlChars() | |
| { | |
| logchar bs[] = {0x08, 0x00}; | |
| logchar bs_expected[] = {0x22, 0x5c, 'b', 0x22, 0x00}; /* "\b" */ | |
| LogString bs_escaped; | |
| appendQuotedEscapedString(bs_escaped, bs); | |
| LOGUNIT_ASSERT_EQUAL(bs_expected, bs_escaped); | |
| logchar tab[] = {0x09, 0x00}; | |
| logchar tab_expected[] = {0x22, 0x5c, 't', 0x22, 0x00}; /* "\t" */ | |
| LogString tab_escaped; | |
| appendQuotedEscapedString(tab_escaped, tab); | |
| LOGUNIT_ASSERT_EQUAL(tab_expected, tab_escaped); | |
| logchar newline[] = {0x0a, 0x00}; | |
| logchar newline_expected[] = {0x22, 0x5c, 'n', 0x22, 0x00}; /* "\n" */ | |
| LogString newline_escaped; | |
| appendQuotedEscapedString(newline_escaped, newline); | |
| LOGUNIT_ASSERT_EQUAL(newline_expected, newline_escaped); | |
| logchar ff[] = {0x0c, 0x00}; | |
| logchar ff_expected[] = {0x22, 0x5c, 'f', 0x22, 0x00}; /* "\f" */ | |
| LogString ff_escaped; | |
| appendQuotedEscapedString(ff_escaped, ff); | |
| LOGUNIT_ASSERT_EQUAL(ff_expected, ff_escaped); | |
| logchar cr[] = {0x0d, 0x00}; | |
| logchar cr_expected[] = {0x22, 0x5c, 'r', 0x22, 0x00}; /* "\r" */ | |
| LogString cr_escaped; | |
| appendQuotedEscapedString(cr_escaped, cr); | |
| LOGUNIT_ASSERT_EQUAL(cr_expected, cr_escaped); | |
| logchar sub[] = {0x1a, 0x00}; | |
| logchar sub_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31, 0x61, 0x22, 0x00}; /* SUB */ | |
| LogString sub_escaped; | |
| appendQuotedEscapedString(sub_escaped, sub); | |
| LOGUNIT_ASSERT_EQUAL(sub_expected, sub_escaped); | |
| logchar esc[] = {0x1e, 0x00}; | |
| logchar esc_expected[] = {0x22, 0x5c, 'u', 0x30, 0x30, 0x31, 0x65, 0x22, 0x00}; /* ESC */ | |
| LogString esc_escaped; | |
| appendQuotedEscapedString(esc_escaped, esc); | |
| LOGUNIT_ASSERT_EQUAL(esc_expected, esc_escaped); | |
| } | |
| #if LOG4CXX_LOGCHAR_IS_UTF8 | |
| /** | |
| * An undecodable byte must be replaced and the text following it kept, | |
| * not dropped along with the rest of the input. | |
| */ | |
| void testAppendQuotedEscapedStringWithInvalidByte() | |
| { | |
| logchar in[] = {'A', (logchar) 0xFF, 'B', 0}; | |
| LogString expected(LOG4CXX_STR("\"A\\ufffdB\"")); | |
| LogString actual; | |
| appendQuotedEscapedString(actual, in); | |
| LOGUNIT_ASSERT_EQUAL(expected, actual); | |
| } | |
| #endif | |
| /** | |
| * Tests appendSerializedMDC. | |
| */ | |
| void testAppendSerializedMDC() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| LOG4CXX_LOCATION)); | |
| MDC::put("key1", "value1"); | |
| MDC::put("key2", "value2"); | |
| LogString output1; | |
| LogString expected1 = LOG4CXX_STR(", \"context_map\": { " | |
| "\"key1\": \"value1\", \"key2\": \"value2\" }"); | |
| appendSerializedMDC(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests appendSerializedMDC with prettyPrint set to true. | |
| */ | |
| void testAppendSerializedMDCWithPrettyPrint() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| LOG4CXX_LOCATION)); | |
| MDC::put("key1", "value1"); | |
| MDC::put("key2", "value2"); | |
| LogString output1; | |
| LogString expected1; | |
| expected1 | |
| .append(LOG4CXX_STR(",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"context_map\": {")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"key1\": \"value1\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"key2\": \"value2\"")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("}")); | |
| setPrettyPrint(true); | |
| appendSerializedMDC(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests appendSerializedNDC. | |
| */ | |
| void testAppendSerializedNDC() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| LOG4CXX_LOCATION)); | |
| NDC::push("one"); | |
| NDC::push("two"); | |
| NDC::push("three"); | |
| LogString output1; | |
| LogString expected1 = LOG4CXX_STR(", \"context_stack\": [ \"one two three\" ]"); | |
| appendSerializedNDC(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests appendSerializedNDC with prettyPrint set to true. | |
| */ | |
| void testAppendSerializedNDCWithPrettyPrint() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| LOG4CXX_LOCATION)); | |
| NDC::push("one"); | |
| NDC::push("two"); | |
| NDC::push("three"); | |
| LogString output1; | |
| LogString expected1; | |
| expected1 | |
| .append(LOG4CXX_STR(",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"context_stack\": [")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"one two three\"")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("]")); | |
| setPrettyPrint(true); | |
| appendSerializedNDC(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests appendSerializedLocationInfo. | |
| */ | |
| void testAppendSerializedLocationInfo() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42))); | |
| LogString output1; | |
| LogString expected1; | |
| expected1 | |
| .append(LOG4CXX_STR("\"location_info\": { ")) | |
| .append(LOG4CXX_STR("\"file\": \"FooFile\", ")) | |
| .append(LOG4CXX_STR("\"line\": \"42\", ")) | |
| .append(LOG4CXX_STR("\"class\": \"\", ")) | |
| .append(LOG4CXX_STR("\"method\": \"BarFunc\" }")); | |
| appendSerializedLocationInfo(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests appendSerializedLocationInfo with prettyPrint set to true. | |
| */ | |
| void testAppendSerializedLocationInfoWithPrettyPrint() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42))); | |
| LogString output1; | |
| LogString expected1; | |
| expected1 | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"location_info\": {")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"file\": \"FooFile\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"line\": \"42\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"class\": \"\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL2) | |
| .append(LOG4CXX_STR("\"method\": \"BarFunc\"")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("}")); | |
| setPrettyPrint(true); | |
| appendSerializedLocationInfo(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests format. | |
| */ | |
| void testFormat() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42))); | |
| LogString timestamp; | |
| helpers::ISO8601DateFormat dateFormat; | |
| dateFormat.format(timestamp, event1->getTimeStamp()); | |
| NDC::push("one"); | |
| NDC::push("two"); | |
| NDC::push("three"); | |
| MDC::put("key1", "value1"); | |
| MDC::put("key2", "value2"); | |
| LogString output1; | |
| LogString expected1; | |
| expected1 | |
| .append(LOG4CXX_STR("{ \"timestamp\": \"")) | |
| .append(timestamp) | |
| .append(LOG4CXX_STR("\", ")) | |
| .append(LOG4CXX_STR("\"level\": \"INFO\", ")) | |
| .append(LOG4CXX_STR("\"logger\": \"Logger\", ")) | |
| .append(LOG4CXX_STR("\"message\": \"A message goes here.\"")); | |
| setLocationInfo(true); | |
| appendSerializedMDC(expected1, event1); | |
| appendSerializedNDC(expected1, event1); | |
| expected1.append(LOG4CXX_STR(", ")); | |
| appendSerializedLocationInfo(expected1, event1); | |
| expected1.append(LOG4CXX_STR(" }")); | |
| expected1.append(LOG4CXX_EOL); | |
| format(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests format with PrettyPrint set to true. | |
| */ | |
| void testFormatWithPrettyPrint() | |
| { | |
| LoggingEventPtr event1 = LoggingEventPtr(new LoggingEvent(LOG4CXX_STR("Logger"), | |
| Level::getInfo(), | |
| LOG4CXX_STR("A message goes here."), | |
| spi::LocationInfo("FooFile", "FooFile", "BarFunc", 42))); | |
| LogString timestamp; | |
| helpers::ISO8601DateFormat dateFormat; | |
| dateFormat.format(timestamp, event1->getTimeStamp()); | |
| NDC::push("one"); | |
| NDC::push("two"); | |
| NDC::push("three"); | |
| MDC::put("key1", "value1"); | |
| MDC::put("key2", "value2"); | |
| LogString output1; | |
| LogString expected1; | |
| expected1 | |
| .append(LOG4CXX_STR("{")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"timestamp\": \"")) | |
| .append(timestamp) | |
| .append(LOG4CXX_STR("\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"level\": \"INFO\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"logger\": \"Logger\",")) | |
| .append(LOG4CXX_EOL) | |
| .append(ppIndentL1) | |
| .append(LOG4CXX_STR("\"message\": \"A message goes here.\"")); | |
| setPrettyPrint(true); | |
| setLocationInfo(true); | |
| appendSerializedMDC(expected1, event1); | |
| appendSerializedNDC(expected1, event1); | |
| expected1.append(LOG4CXX_STR(",")); | |
| expected1.append(LOG4CXX_EOL); | |
| appendSerializedLocationInfo(expected1, event1); | |
| expected1.append(LOG4CXX_EOL); | |
| expected1.append(LOG4CXX_STR("}")); | |
| expected1.append(LOG4CXX_EOL); | |
| format(output1, event1); | |
| LOGUNIT_ASSERT_EQUAL(expected1, output1); | |
| } | |
| /** | |
| * Tests getLocationInfo and setLocationInfo. | |
| */ | |
| void testGetSetLocationInfo() | |
| { | |
| JSONLayout layout; | |
| LOGUNIT_ASSERT_EQUAL(false, layout.getLocationInfo()); | |
| layout.setLocationInfo(true); | |
| LOGUNIT_ASSERT_EQUAL(true, layout.getLocationInfo()); | |
| layout.setLocationInfo(false); | |
| LOGUNIT_ASSERT_EQUAL(false, layout.getLocationInfo()); | |
| } | |
| /** | |
| * Tests getPrettyPrint and setPrettyPrint. | |
| */ | |
| void testGetSetPrettyPrint() | |
| { | |
| JSONLayout layout; | |
| LOGUNIT_ASSERT_EQUAL(false, layout.getPrettyPrint()); | |
| layout.setPrettyPrint(true); | |
| LOGUNIT_ASSERT_EQUAL(true, layout.getPrettyPrint()); | |
| layout.setPrettyPrint(false); | |
| LOGUNIT_ASSERT_EQUAL(false, layout.getPrettyPrint()); | |
| } | |
| /** | |
| * Tests Unicode characters. | |
| */ | |
| void testAppendQuotedEscapedString() | |
| { | |
| std::string problemMessage = "'\001\"Hello \"\004'"; | |
| LogString expectedQuotedEscapedMessage = LOG4CXX_STR("\"'\\u0001\\\"Hello \\\"\\u0004'\""); | |
| LOG4CXX_DECODE_CHAR(problemMessageLS, problemMessage); | |
| LogString quotedEscapedMessage; | |
| appendQuotedEscapedString(quotedEscapedMessage, problemMessageLS); | |
| LOGUNIT_ASSERT_EQUAL(expectedQuotedEscapedMessage, quotedEscapedMessage); | |
| // '\"räksmörgås.josefsson.org\"' | |
| std::string problemName = "'\"\162\303\244\153\163\155\303\266\162\147\303\245\163\056\152\157\163\145\146\163\163\157\156\056\157\162\147\"'"; | |
| LOG4CXX_DECODE_CHAR(problemNameLS, problemName); | |
| LogString expectedQuotedEscapedName = LOG4CXX_STR("\"") + problemNameLS + LOG4CXX_STR("\""); | |
| expectedQuotedEscapedName.insert(2, 1, 0x5c); // insert a backslash before the first double quote | |
| expectedQuotedEscapedName.insert(expectedQuotedEscapedName.size() - 3, 1, 0x5c); // insert a backslash before the last double quote | |
| LogString quotedEscapedName; | |
| appendQuotedEscapedString(quotedEscapedName, problemNameLS); | |
| LOGUNIT_ASSERT_EQUAL(expectedQuotedEscapedName, quotedEscapedName); | |
| Transcoder::encode(0xD822, problemNameLS); // Add a character that cannot be converted to UTF16 | |
| #if LOG4CXX_LOGCHAR_IS_WCHAR && !defined(__STDC_ISO_10646__) | |
| // encodeUTF16 adds 0xD822, but decodeUTF16 cannot convert 0xD822 | |
| expectedQuotedEscapedName.insert(expectedQuotedEscapedName.size() - 1, LOG4CXX_STR("\\ufffd")); // The Unicode replacement character | |
| #else | |
| expectedQuotedEscapedName.insert(expectedQuotedEscapedName.size() - 1, LOG4CXX_STR("\\ufffd")); // The Unicode replacement character | |
| #endif | |
| LogString escapedQuoted0xD822Name; | |
| appendQuotedEscapedString(escapedQuoted0xD822Name, problemNameLS); | |
| LOGUNIT_ASSERT_EQUAL(expectedQuotedEscapedName, escapedQuoted0xD822Name); | |
| } | |
| void testLayoutSizeOverflowGuards() | |
| { | |
| const size_t maxSize = (std::numeric_limits<size_t>::max)(); | |
| LOGUNIT_ASSERT_EQUAL(maxSize, priv::doubledLayoutSize(maxSize)); | |
| LOGUNIT_ASSERT_EQUAL(maxSize - 1, priv::doubledLayoutSize((maxSize - 1) / 2)); | |
| LogString output; | |
| const size_t initialCapacity = output.capacity(); | |
| priv::reserveFormattedEvent(output, output.max_size(), 1); | |
| LOGUNIT_ASSERT_EQUAL(initialCapacity, output.capacity()); | |
| } | |
| void testLayoutSizeEdgeCases() | |
| { | |
| const size_t maxSize = (std::numeric_limits<size_t>::max)(); | |
| LOGUNIT_ASSERT_EQUAL(static_cast<size_t>(0), priv::doubledLayoutSize(0)); | |
| LOGUNIT_ASSERT_EQUAL(static_cast<size_t>(2), priv::doubledLayoutSize(1)); | |
| LOGUNIT_ASSERT_EQUAL(maxSize - 1, priv::doubledLayoutSize(maxSize / 2)); | |
| LOGUNIT_ASSERT_EQUAL(maxSize, priv::doubledLayoutSize((maxSize / 2) + 1)); | |
| LOGUNIT_ASSERT_EQUAL(maxSize, priv::doubledLayoutSize(maxSize)); | |
| } | |
| void testReserveFormattedEventSizing() | |
| { | |
| LogString output; | |
| const size_t initialCapacity = output.capacity(); | |
| priv::reserveFormattedEvent(output, 16, 8); | |
| LOGUNIT_ASSERT(output.capacity() >= 24); | |
| LOGUNIT_ASSERT(output.capacity() >= initialCapacity); | |
| const size_t maxSize = output.max_size(); | |
| const size_t fixedSize = 16; | |
| const size_t boundaryMessageSize = maxSize - fixedSize; | |
| LOGUNIT_ASSERT_EQUAL(maxSize, fixedSize + boundaryMessageSize); | |
| LOGUNIT_ASSERT(boundaryMessageSize <= maxSize); | |
| LOGUNIT_ASSERT(fixedSize <= maxSize - boundaryMessageSize); | |
| const size_t capacityBeforeSkip = output.capacity(); | |
| priv::reserveFormattedEvent(output, 16, (std::numeric_limits<size_t>::max)()); | |
| LOGUNIT_ASSERT_EQUAL(capacityBeforeSkip, output.capacity()); | |
| } | |
| }; | |
| LOGUNIT_TEST_SUITE_REGISTRATION(JSONLayoutTest); |