Skip to content

Add quic_test_output_impl.(h|cc) to QUICHE platform implementation.#6058

Merged
alyssawilk merged 10 commits intoenvoyproxy:masterfrom
wu-bin:quic_test_output_impl
Mar 7, 2019
Merged

Add quic_test_output_impl.(h|cc) to QUICHE platform implementation.#6058
alyssawilk merged 10 commits intoenvoyproxy:masterfrom
wu-bin:quic_test_output_impl

Conversation

@wu-bin
Copy link
Contributor

@wu-bin wu-bin commented Feb 25, 2019

Description:

Add quic_test_output_impl.(h|cc) to QUICHE platform implementation.

If environment variable "QUIC_TEST_OUTPUT_DIR" is set, tests using the QuicRecordTestOutput() function can save test output files to the $QUIC_TEST_OUTPUT_DIR directory.

Risk Level: minimal: code not used yet
Testing:

[No test output:] bazel test test/extensions/quic_listeners/quiche/platform:quic_platform_test --test_output=all --define quiche=enabled --experimental_remap_main_repo

[Test output saved to /tmp:] bazel test test/extensions/quic_listeners/quiche/platform:quic_platform_test --test_output=all --define quiche=enabled --experimental_remap_main_repo --action_env=QUIC_TEST_OUTPUT_DIR=/tmp

Docs Changes: none
Release Notes: none
[Optional Fixes #Issue]
[Optional Deprecated:]

@wu-bin
Copy link
Contributor Author

wu-bin commented Feb 26, 2019

/assign @mpwarres

Copy link
Contributor

@mpwarres mpwarres left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo a nit and one question

output_dir += '/';
}

Envoy::Filesystem::InstanceImpl file_system;
Copy link
Contributor

Choose a reason for hiding this comment

The 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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love @mattklein123 take on this one.
I had a similar issue with something the server owned lately and I reaaaally wanted to make it a singleton too, but then again I love singletons about as much as Matt and Josh dislike them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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?

Copy link
Contributor

Choose a reason for hiding this comment

The 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.
I do think we will need a solution to the general Api::Api issue, but maybe we should deal with that separately from this PR? If we do that, we'll need to remember to circle back and update quic_test_output_impl.cc to not hardcode FilesystemImpl later on.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are going to have to end up plumbing an Api into this platform abstraction somehow. Can the platform abstraction have shared state that is initialized? If we have that it should be quite easy to pass in an Api. cc @jmarantz

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

output_dir += '/';
}

Envoy::Filesystem::InstanceImpl file_system;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love @mattklein123 take on this one.
I had a similar issue with something the server owned lately and I reaaaally wanted to make it a singleton too, but then again I love singletons about as much as Matt and Josh dislike them.

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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just tests the fast-fail due to QUIC_TEST_OUTPUT_DIR not being set, right? It'd be nice to test that the filesystem work actually works and the various appends do as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. If we end up using Api::fileSystem(), the test could inject a mock Filesystem::Instance by way of that, which would simplify verifying this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it with --action_env=QUIC_TEST_OUTPUT_DIR=/tmp in the bazel command. (PR description has the full command).

Alternatively, we can do a setenv() at the beginning of the test, and check for the actual file content at the end of the test, which will make this test less manual. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think having CI actually cover the code path would be good. I think setenv is probably the best bet but I'd be fine if there's a way to build it into the test definition too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the test to setenv(), if the env is not already set, so the code is now covered by CI.
Checking the output is still manual though, because the test does not know the file path, which is generated by the QuicRecordTestOutput function internally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the Envoy log utils (EXPECT_LOG_NOT_CONTAINS) to verify there was no warning logged, to make sure we didn't hit the fast fail paths?

I'd think we could verify existence of /tmp/quic_test_output.1 unless we expect that to change under the hood

Copy link
Contributor Author

@wu-bin wu-bin Mar 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the Envoy log utils (EXPECT_LOG_NOT_CONTAINS) to verify there was no warning logged, to make sure we didn't hit the fast fail paths?

Good idea, done.

I'd think we could verify existence of /tmp/quic_test_output.1 unless we expect that to change under the hood

The filename is not visible to the test, but I added EXPECT_LOG_CONTAINS, which make sure some test output file is generated.

Signed-off-by: Bin Wu <wub@google.com>
defined in the program environment, set it to "/tmp" such that test
output file is always created.

Signed-off-by: Bin Wu <wub@google.com>
mpwarres
mpwarres previously approved these changes Mar 5, 2019
Copy link
Contributor

@mpwarres mpwarres left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

output_dir += '/';
}

Envoy::Filesystem::InstanceImpl file_system;
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - just one final test request

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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use the Envoy log utils (EXPECT_LOG_NOT_CONTAINS) to verify there was no warning logged, to make sure we didn't hit the fast fail paths?

I'd think we could verify existence of /tmp/quic_test_output.1 unless we expect that to change under the hood

@wu-bin
Copy link
Contributor Author

wu-bin commented Mar 7, 2019

Test has been updated to make sure some output file is generated. PTAL. @mpwarres @alyssawilk

@mpwarres
Copy link
Contributor

mpwarres commented Mar 7, 2019

Test has been updated to make sure some output file is generated. PTAL. @mpwarres @alyssawilk

LGTM, thanks!

@alyssawilk alyssawilk merged commit 088d978 into envoyproxy:master Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants