-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add quic_test_output_impl.(h|cc) to QUICHE platform implementation. #6058
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
52b7311
ec02e27
fe2af18
1a2711b
80837ae
3cf7f7d
c65b728
c677256
e268e03
f0d1018
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // 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 <cstdlib> | ||
|
|
||
| #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 { | ||
| namespace { | ||
|
|
||
| void QuicRecordTestOutputToFile(const std::string& filename, QuicStringPiece data) { | ||
wu-bin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice if the Filesystem::Instance could be obtained from Api::Api::fileSystem(), but I can't think of a way to do that, since we don't have access to the Api::Api instance here, and there's no good way to pass it down explicitly. What you have here looks like best immediate solution to me, but leaving this comment in case Envoy folks have any other ideas. I do wonder if this will come up in other places as well though, e.g. if other platform impls need to make use of functionality abstracted under Api::Api. Maybe we need a singleton (ick) or other means to fetch the Api::Api when it can't be passed explicitly?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd love @mattklein123 take on this one.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code in this PR is purely for tests, IMHO, making test code more testable via a mock is going a little bit too far. Does it make any sense?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough, I'm fine with not using a mock and checking for the file directly.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we are going to have to end up plumbing an
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mpwarres Agree we need a solution for the general Api issue, I think we can circle back when we have a concrete issue related to it. I still think quic_test_output_impl.cc can continue to write directly to real files. I found that test function TestEnvironment::writeStringToFileForTest is already doing something similar. @mattklein123 The code in this PR is test only, all it does is to allow some unit tests to save some test output to somewhere(in this case, a file). We have a test of this test-code in quic_platform_test.cc(QuicPlatformTest.QuicTestOutput), I think the point of plumbing Api into here is to test this test-code better, which seems a little overkill? @mattklein123 Most platform abstractions, including this one, do not have shared states. I won't be surprised if some of them end up needing a shared Api, I think we can deal with that when the need arises.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is only used in test code, can we put it in the test directory to make that clear? Can you have a test platform split out?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mattklein123 I have tried moving it to the test directory previously, but gave up due to some complications. The issue is quic_test_output.h, which is part of upstream QUICHE, and built in cc_library "quic_platform_base" in bazel/external/quiche.BUILD, wants to include 'extensions/quic_listeners/quiche/platform/quic_test_output_impl.h', this path does not work if quic_test_output_impl.h is in the test directory.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re: @mattklein123's earlier question, we could add shared state to the platform implementation that is initialized early on via an Init() call, which IIUC would amount to a singleton maintained within the QUICHE platform impl. If that seems reasonable, we can add that, though I think our preference would be to do it separate from this PR, if that's ok. |
||
| 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<ssize_t>(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(); | ||
| } | ||
| } // namespace | ||
|
|
||
| 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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Uh oh!
There was an error while loading. Please reload this page.