Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openjdk/test/hotspot/gtest/logging/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 9 kB image not shown  

Quelle  test_asynclog.cpp   Sprache: C

 
/*
 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "jvm.h"
#include "logging/log.hpp"
#include "logging/logAsyncWriter.hpp"
#include "logging/logFileOutput.hpp"
#include "logging/logMessage.hpp"
#include "logTestFixture.hpp"
#include "logTestUtils.inline.hpp"
#include "unittest.hpp"

class AsyncLogTest : public LogTestFixture {
 public:
  AsyncLogTest() {
    if(!LogConfiguration::is_async_mode()) {
      fprintf(stderr, "Warning: asynclog is OFF.\n");
    }
  }

  void test_asynclog_ls() {
    LogStream ls(Log(logging)::info());
    outputStream* os = &ls;
    os->print_cr("LogStreamWithAsyncLogImpl");
    os->print_cr("LogStreamWithAsyncLogImpl secondline");

    //multi-lines
    os->print("logStream msg1-");
    os->print("msg2-");
    os->print("msg3\n");
    os->print_cr("logStream newline");
  }

  void test_asynclog_raw() {
    Log(logging) logger;
#define LOG_LEVEL(level, name) logger.name("1" #level);
LOG_LEVEL_LIST
#undef LOG_LEVEL

    LogTarget(Trace, logging) t;
    LogTarget(Debug, logging) d;
    EXPECT_FALSE(t.is_enabled());
    EXPECT_TRUE(d.is_enabled());

    d.print("AsyncLogTarget.print = %d", 1);
    log_trace(logging)("log_trace-test");
    log_debug(logging)("log_debug-test");
  }

  void test_asynclog_drop_messages() {
    auto writer = AsyncLogWriter::instance();
    if (writer != nullptr) {
      const size_t sz = 2000;

      // shrink async buffer.
      AsyncLogWriter::BufferUpdater saver(1024);
      LogMessage(logging) lm;

      // write more messages than its capacity in burst
      for (size_t i = 0; i < sz; ++i) {
        lm.debug("a lot of log...");
      }
      lm.flush();
    }
  }

  // stdout/stderr support
  bool write_to_file(const std::string& output) {
    FILE* f = os::fopen(TestLogFileName, "w");

    if (f != NULL) {
      size_t sz = output.size();
      size_t written = fwrite(output.c_str(), sizeof(char), output.size(), f);

      if (written == sz * sizeof(char)) {
        return fclose(f) == 0;
      }
    }

    return false;
  }
};

TEST_VM_F(AsyncLogTest, asynclog) {
  set_log_config(TestLogFileName, "logging=debug");

  test_asynclog_ls();
  test_asynclog_raw();
  AsyncLogWriter::flush();

  EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline"));

  EXPECT_TRUE(file_contains_substring(TestLogFileName, "1Debug"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "1Info"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "1Warning"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "1Error"));
  EXPECT_FALSE(file_contains_substring(TestLogFileName, "1Trace")); // trace message is masked out

  EXPECT_TRUE(file_contains_substring(TestLogFileName, "AsyncLogTarget.print = 1"));
  EXPECT_FALSE(file_contains_substring(TestLogFileName, "log_trace-test")); // trace message is masked out
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "log_debug-test"));
}

TEST_VM_F(AsyncLogTest, logMessage) {
  set_log_config(TestLogFileName, "logging=debug");

  const int MULTI_LINES = 20;
  {

    LogMessage(logging) msg;
    Log(logging) logger;

    for (int i = 0; i < MULTI_LINES; ++i) {
      msg.debug("nonbreakable log message line-%02d", i);

      if (0 == (i % 4)) {
        logger.debug("a noisy message from other logger");
      }
    }
    logger.debug("a noisy message from other logger");
  }
  AsyncLogWriter::flush();

  ResourceMark rm;
  LogMessageBuffer buffer;
  const char* strs[MULTI_LINES + 1];
  strs[MULTI_LINES] = NULL;
  for (int i = 0; i < MULTI_LINES; ++i) {
    stringStream ss;
    ss.print_cr("nonbreakable log message line-%02d", i);
    strs[i] = ss.as_string();
  }
  // check nonbreakable log messages are consecutive
  EXPECT_TRUE(file_contains_substrings_in_order(TestLogFileName, strs));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "a noisy message from other logger"));
}

TEST_VM_F(AsyncLogTest, logBuffer) {
  const auto Default = LogDecorations(LogLevel::Warning, LogTagSetMapping<LogTag::__NO_TAG>::tagset(),
                                      LogDecorators());
  size_t len = strlen(TestLogFileName) + strlen(LogFileOutput::Prefix) + 1;
  char* name = NEW_C_HEAP_ARRAY(char, len, mtLogging);
  snprintf(name, len, "%s%s", LogFileOutput::Prefix, TestLogFileName);

  LogFileStreamOutput* output = new LogFileOutput(name);
  output->initialize(nullptr, nullptr);
  auto buffer = new AsyncLogWriter::Buffer(1024);

  int line = 0;
  int written;
  uintptr_t addr;
  const uintptr_t mask = (uintptr_t)(sizeof(void*) - 1);
  bool res;

  res = buffer->push_back(output, Default"a log line");
  EXPECT_TRUE(res) << "first message should succeed.";
  line++;
  res = buffer->push_back(output, Default"yet another");
  EXPECT_TRUE(res) << "second message should succeed.";
  line++;

  auto it = buffer->iterator();
  EXPECT_TRUE(it.hasNext());
  const AsyncLogWriter::Message* e = it.next();
  addr = reinterpret_cast<uintptr_t>(e);
  EXPECT_EQ(0, (int)(addr & (sizeof(void*)-1))); // returned vaue aligns on sizeof(pointer)
  EXPECT_EQ(output, e->output());
  EXPECT_EQ(0, memcmp(&Default, &e->decorations(), sizeof(LogDecorations)));
  EXPECT_STREQ("a log line", e->message());
  written = e->output()->write_blocking(e->decorations(), e->message());
  EXPECT_GT(written, 0);

  EXPECT_TRUE(it.hasNext());
  e = it.next();
  addr = reinterpret_cast<uintptr_t>(e);
  EXPECT_EQ(0, (int)(addr & (sizeof(void*)-1)));
  EXPECT_EQ(output, e->output());
  EXPECT_EQ(0, memcmp(&Default, &e->decorations(), sizeof(LogDecorations)));
  EXPECT_STREQ("yet another", e->message());
  written = e->output()->write_blocking(e->decorations(), e->message());
  EXPECT_GT(written, 0);

  while (buffer->push_back(output, Default"0123456789abcdef")) {
    line++;
  }

  EXPECT_GT(line, 2);
  while (it.hasNext()) {
    e = it.next();
    addr = reinterpret_cast<uintptr_t>(e);
    EXPECT_EQ(0, (int)(addr & (sizeof(void*)-1)));
    EXPECT_EQ(output, e->output());
    EXPECT_STREQ("0123456789abcdef", e->message());
    written = e->output()->write_blocking(e->decorations(), e->message());
    EXPECT_GT(written, 0);
    line--;
  }
  EXPECT_EQ(line, 2);

  // last one, flush token. expect to succeed even buffer has been full.
  buffer->push_flush_token();
  EXPECT_TRUE(it.hasNext());
  e = it.next();
  EXPECT_EQ(e->output(), nullptr);
  EXPECT_TRUE(e->is_token());
  EXPECT_STREQ("", e->message());
  EXPECT_FALSE(it.hasNext());

  // reset buffer
  buffer->reset();
  EXPECT_FALSE(buffer->iterator().hasNext());

  delete output; // close file
  FREE_C_HEAP_ARRAY(char, name);

  const char* strs[4];
  strs[0] = "a log line";
  strs[1] = "yet another";
  strs[2] = "0123456789abcdef";
  strs[3] = nullptr; // sentinel!
  EXPECT_TRUE(file_contains_substrings_in_order(TestLogFileName, strs));
}

TEST_VM_F(AsyncLogTest, droppingMessage) {
  set_log_config(TestLogFileName, "logging=debug");
  test_asynclog_drop_messages();

  AsyncLogWriter::flush();
  if (AsyncLogWriter::instance() != nullptr) {
    EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging"));
  }
}

TEST_VM_F(AsyncLogTest, stdoutOutput) {
  testing::internal::CaptureStdout();
  set_log_config("stdout""logging=debug");

  test_asynclog_ls();
  test_asynclog_drop_messages();

  AsyncLogWriter::flush();
  EXPECT_TRUE(write_to_file(testing::internal::GetCapturedStdout()));

  EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline"));

  if (AsyncLogWriter::instance() != nullptr) {
    EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging"));
  }
}

TEST_VM_F(AsyncLogTest, stderrOutput) {
  testing::internal::CaptureStderr();
  set_log_config("stderr""logging=debug");

  test_asynclog_ls();
  test_asynclog_drop_messages();

  AsyncLogWriter::flush();
  EXPECT_TRUE(write_to_file(testing::internal::GetCapturedStderr()));

  EXPECT_TRUE(file_contains_substring(TestLogFileName, "LogStreamWithAsyncLogImpl"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream msg1-msg2-msg3"));
  EXPECT_TRUE(file_contains_substring(TestLogFileName, "logStream newline"));

  if (AsyncLogWriter::instance() != nullptr) {
    EXPECT_TRUE(file_contains_substring(TestLogFileName, "messages dropped due to async logging"));
  }
}

90%


¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.