From 52b73118e2f538ca3e800e569fd9bfc0fa8495e1 Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Mon, 25 Feb 2019 15:26:55 -0500 Subject: [PATCH 1/5] Add quic_test_output_impl.(h|cc) to QUICHE platform implementation. Signed-off-by: Bin Wu --- bazel/external/quiche.BUILD | 2 +- .../quic_listeners/quiche/platform/BUILD | 12 +++- .../quiche/platform/quic_test_output_impl.cc | 71 +++++++++++++++++++ .../quiche/platform/quic_test_output_impl.h | 15 ++++ .../quiche/platform/quic_platform_test.cc | 11 +++ 5 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc create mode 100644 source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h diff --git a/bazel/external/quiche.BUILD b/bazel/external/quiche.BUILD index 1e69791548fcc..bcb6145dfbd40 100644 --- a/bazel/external/quiche.BUILD +++ b/bazel/external/quiche.BUILD @@ -145,6 +145,7 @@ cc_library( "quiche/quic/platform/api/quic_string_piece.h", "quiche/quic/platform/api/quic_string_utils.h", "quiche/quic/platform/api/quic_test.h", + "quiche/quic/platform/api/quic_test_output.h", "quiche/quic/platform/api/quic_text_utils.h", "quiche/quic/platform/api/quic_uint128.h", # TODO: uncomment the following files as implementations are added. @@ -172,7 +173,6 @@ cc_library( # "quiche/quic/platform/api/quic_test.h", # "quiche/quic/platform/api/quic_test_loopback.h", # "quiche/quic/platform/api/quic_test_mem_slice_vector.h", - # "quiche/quic/platform/api/quic_test_output.h", # "quiche/quic/platform/api/quic_thread.h", ], visibility = ["//visibility:public"], diff --git a/source/extensions/quic_listeners/quiche/platform/BUILD b/source/extensions/quic_listeners/quiche/platform/BUILD index e83bd57298d47..c8bc47157a4af 100644 --- a/source/extensions/quic_listeners/quiche/platform/BUILD +++ b/source/extensions/quic_listeners/quiche/platform/BUILD @@ -97,21 +97,29 @@ envoy_cc_library( srcs = [ "quic_cert_utils_impl.cc", "quic_text_utils_impl.cc", - ], + ] + envoy_select_quiche([ + "quic_test_output_impl.cc", + ]), hdrs = [ "quic_cert_utils_impl.h", "quic_mutex_impl.h", "quic_str_cat_impl.h", "quic_string_utils_impl.h", "quic_text_utils_impl.h", - ], + ] + envoy_select_quiche([ + "quic_test_output_impl.h", + ]), external_deps = [ "quiche_quic_platform_base", "abseil_str_format", "abseil_synchronization", + "abseil_time", "ssl", ], visibility = ["//visibility:public"], + deps = envoy_select_quiche([ + "//source/common/filesystem:filesystem_lib", + ]), ) envoy_cc_library( diff --git a/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc new file mode 100644 index 0000000000000..ed21fc14e7d1b --- /dev/null +++ b/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc @@ -0,0 +1,71 @@ +// NOLINT(namespace-envoy) + +// This file is part of the QUICHE platform implementation, and is not to be +// consumed or referenced directly by other Envoy code. It serves purely as a +// porting layer for QUICHE. + +#include "extensions/quic_listeners/quiche/platform/quic_test_output_impl.h" + +#include + +#include "common/filesystem/filesystem_impl.h" + +#include "absl/time/clock.h" +#include "absl/time/time.h" +#include "fmt/printf.h" +#include "gtest/gtest.h" +#include "quiche/quic/platform/api/quic_logging.h" + +namespace quic { + +void QuicRecordTestOutputToFile(const std::string& filename, QuicStringPiece data) { + const char* output_dir_env = std::getenv("QUIC_TEST_OUTPUT_DIR"); + if (output_dir_env == nullptr) { + QUIC_LOG(WARNING) << "Could not save test output since QUIC_TEST_OUTPUT_DIR is not set"; + return; + } + + std::string output_dir = output_dir_env; + if (output_dir.empty()) { + QUIC_LOG(WARNING) << "Could not save test output since QUIC_TEST_OUTPUT_DIR is empty"; + return; + } + + if (output_dir.back() != '/') { + output_dir += '/'; + } + + Envoy::Filesystem::InstanceImpl file_system; + if (!file_system.directoryExists(output_dir)) { + QUIC_LOG(ERROR) << "Directory does not exist while writing test output: " << output_dir; + return; + } + + const std::string output_path = output_dir + filename; + Envoy::Filesystem::FilePtr file = file_system.createFile(output_path); + if (!file->open().rc_) { + QUIC_LOG(ERROR) << "Failed to open test output file: " << output_path; + return; + } + + if (file->write(data).rc_ != static_cast(data.size())) { + QUIC_LOG(ERROR) << "Failed to write to test output file: " << output_path; + } else { + QUIC_LOG(INFO) << "Recorded test output into " << output_path; + } + + file->close(); +} + +void QuicRecordTestOutputImpl(QuicStringPiece identifier, QuicStringPiece data) { + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + + std::string timestamp = absl::FormatTime("%Y%m%d%H%M%S", absl::Now(), absl::LocalTimeZone()); + + std::string filename = fmt::sprintf("%s.%s.%s.%s.qtr", test_info->name(), + test_info->test_case_name(), identifier.data(), timestamp); + + QuicRecordTestOutputToFile(filename, data); +} + +} // namespace quic diff --git a/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h b/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h new file mode 100644 index 0000000000000..a611ad7af6edb --- /dev/null +++ b/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.h @@ -0,0 +1,15 @@ +#pragma once + +// NOLINT(namespace-envoy) +// +// This file is part of the QUICHE platform implementation, and is not to be +// consumed or referenced directly by other Envoy code. It serves purely as a +// porting layer for QUICHE. + +#include "quiche/quic/platform/api/quic_string_piece.h" + +namespace quic { + +void QuicRecordTestOutputImpl(QuicStringPiece identifier, QuicStringPiece data); + +} // namespace quic diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index 43ea8012963ac..fde4df42f1f03 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -19,6 +19,7 @@ #include "quiche/quic/platform/api/quic_stack_trace.h" #include "quiche/quic/platform/api/quic_string.h" #include "quiche/quic/platform/api/quic_string_piece.h" +#include "quiche/quic/platform/api/quic_test_output.h" #include "quiche/quic/platform/api/quic_uint128.h" using testing::HasSubstr; @@ -355,6 +356,16 @@ TEST(QuicPlatformTest, QuicCertUtils) { OPENSSL_free(static_cast(der)); } +TEST(QuicPlatformTest, QuicTestOutput) { + QuicLogThresholdSaver saver; + + // Set log level to INFO to see the test output path in log. + quic::GetLogger().set_level(quic::INFO); + + quic::QuicRecordTestOutput("quic_test_output.1", "output 1 content\n"); + quic::QuicRecordTestOutput("quic_test_output.2", "output 2 content\n"); +} + } // namespace Quiche } // namespace QuicListeners } // namespace Extensions From fe2af183cf45a9ea005260579e7230d4ec0f5431 Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Wed, 27 Feb 2019 14:32:09 -0500 Subject: [PATCH 2/5] Update per comments. Signed-off-by: Bin Wu --- bazel/envoy_build_system.bzl | 1 + .../quic_listeners/quiche/platform/quic_test_output_impl.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/bazel/envoy_build_system.bzl b/bazel/envoy_build_system.bzl index 80a322427eb83..ecd0df4421713 100644 --- a/bazel/envoy_build_system.bzl +++ b/bazel/envoy_build_system.bzl @@ -675,6 +675,7 @@ def envoy_select_boringssl(if_fips, default = None): "//conditions:default": default or [], }) +# Selects the part of QUICHE that does not yet work with the current CI. def envoy_select_quiche(xs, repository = ""): return select({ repository + "//bazel:enable_quiche": xs, diff --git a/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc b/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc index ed21fc14e7d1b..2ab6a1fa66615 100644 --- a/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc +++ b/source/extensions/quic_listeners/quiche/platform/quic_test_output_impl.cc @@ -17,6 +17,7 @@ #include "quiche/quic/platform/api/quic_logging.h" namespace quic { +namespace { void QuicRecordTestOutputToFile(const std::string& filename, QuicStringPiece data) { const char* output_dir_env = std::getenv("QUIC_TEST_OUTPUT_DIR"); @@ -56,6 +57,7 @@ void QuicRecordTestOutputToFile(const std::string& filename, QuicStringPiece dat file->close(); } +} // namespace void QuicRecordTestOutputImpl(QuicStringPiece identifier, QuicStringPiece data) { const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); From 1a2711b6e67355ce5c5bb023217d9d7289992154 Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Wed, 27 Feb 2019 20:46:51 -0500 Subject: [PATCH 3/5] In test QuicPlatformTest.QuicTestOutput, if QUIC_TEST_OUTPUT_DIR is not defined in the program environment, set it to "/tmp" such that test output file is always created. Signed-off-by: Bin Wu --- .../quic_listeners/quiche/platform/quic_platform_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index fde4df42f1f03..096f9be387844 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -1,4 +1,5 @@ #include "test/extensions/transport_sockets/tls/ssl_test_utility.h" +#include "test/test_common/environment.h" #include "test/test_common/logging.h" #include "gmock/gmock.h" @@ -359,6 +360,10 @@ TEST(QuicPlatformTest, QuicCertUtils) { TEST(QuicPlatformTest, QuicTestOutput) { QuicLogThresholdSaver saver; + if (!Envoy::TestEnvironment::getOptionalEnvVar("QUIC_TEST_OUTPUT_DIR").has_value()) { + Envoy::TestEnvironment::setEnvVar("QUIC_TEST_OUTPUT_DIR", "/tmp", /*overwrite=*/true); + } + // Set log level to INFO to see the test output path in log. quic::GetLogger().set_level(quic::INFO); From 80837aea2f0a4bcb0ea921e118fd33083d64f88c Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Wed, 27 Feb 2019 20:54:48 -0500 Subject: [PATCH 4/5] Remove a unnecessary getenv in test QuicPlatformTest.QuicTestOutput. Signed-off-by: Bin Wu --- .../quic_listeners/quiche/platform/quic_platform_test.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index 096f9be387844..6d4f6468ce911 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -360,9 +360,7 @@ TEST(QuicPlatformTest, QuicCertUtils) { TEST(QuicPlatformTest, QuicTestOutput) { QuicLogThresholdSaver saver; - if (!Envoy::TestEnvironment::getOptionalEnvVar("QUIC_TEST_OUTPUT_DIR").has_value()) { - Envoy::TestEnvironment::setEnvVar("QUIC_TEST_OUTPUT_DIR", "/tmp", /*overwrite=*/true); - } + Envoy::TestEnvironment::setEnvVar("QUIC_TEST_OUTPUT_DIR", "/tmp", /*overwrite=*/false); // Set log level to INFO to see the test output path in log. quic::GetLogger().set_level(quic::INFO); From e268e03888161071e7a683612c6a20c08c931072 Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Wed, 6 Mar 2019 16:28:19 -0500 Subject: [PATCH 5/5] Add EXPECT_LOG(_NOT)_CONTAINS to QuicPlatformTest.QuicTestOutput. Signed-off-by: Bin Wu --- .../quic_listeners/quiche/platform/quic_platform_test.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc index 49f640bc93938..2e97be87ed996 100644 --- a/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc +++ b/test/extensions/quic_listeners/quiche/platform/quic_platform_test.cc @@ -426,8 +426,12 @@ TEST(QuicPlatformTest, QuicTestOutput) { // Set log level to INFO to see the test output path in log. quic::GetLogger().set_level(quic::INFO); - quic::QuicRecordTestOutput("quic_test_output.1", "output 1 content\n"); - quic::QuicRecordTestOutput("quic_test_output.2", "output 2 content\n"); + EXPECT_LOG_NOT_CONTAINS("warn", "", + quic::QuicRecordTestOutput("quic_test_output.1", "output 1 content\n")); + EXPECT_LOG_NOT_CONTAINS("error", "", + quic::QuicRecordTestOutput("quic_test_output.2", "output 2 content\n")); + EXPECT_LOG_CONTAINS("info", "Recorded test output into", + quic::QuicRecordTestOutput("quic_test_output.3", "output 3 content\n")); } } // namespace