Skip to content
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

Crash Dumper: E2E tests using kill filter #15314

Merged
merged 5 commits into from
Mar 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions test/extensions/filters/http/kill_request/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_test",
"envoy_package",
)
load(
Expand Down Expand Up @@ -49,3 +50,13 @@ envoy_extension_cc_test(
"//test/integration:http_protocol_integration_lib",
],
)

envoy_cc_test(
name = "crash_integration_test",
srcs = ["crash_integration_test.cc"],
deps = [
"//source/extensions/filters/http/kill_request:kill_request_config",
"//test/integration:http_protocol_integration_lib",
"@envoy_api//envoy/extensions/filters/http/kill_request/v3:pkg_cc_proto",
],
)
102 changes: 102 additions & 0 deletions test/extensions/filters/http/kill_request/crash_integration_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "envoy/extensions/filters/http/kill_request/v3/kill_request.pb.h"

#include "test/integration/http_protocol_integration.h"

#include "gtest/gtest.h"

namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace KillRequest {
namespace {
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define ASANITIZED /* Sanitized by Clang */
#endif
#endif

#if defined(__SANITIZE_ADDRESS__)
#define ASANITIZED /* Sanitized by GCC */
#endif

htuch marked this conversation as resolved.
Show resolved Hide resolved
class CrashIntegrationTest : public Event::TestUsingSimulatedTime,
public HttpProtocolIntegrationTest {
protected:
void initializeFilter(const std::string& filter_config) {
config_helper_.addFilter(filter_config);
initialize();
}
};

// Insufficient support on Windows.
#ifndef WIN32
// ASAN hijacks the signal handlers, so the process will die but not output
// the particular messages we expect.
#ifndef ASANITIZED
// If we don't install any signal handlers (i.e. due to compile options), we
// won't get the crash report.
#ifdef ENVOY_HANDLE_SIGNALS

// Tests should run with all protocols.
class CrashIntegrationTestAllProtocols : public CrashIntegrationTest {};
INSTANTIATE_TEST_SUITE_P(Protocols, CrashIntegrationTestAllProtocols,
testing::ValuesIn(HttpProtocolIntegrationTest::getProtocolTestParams()),
HttpProtocolIntegrationTest::protocolTestParamsToString);

TEST_P(CrashIntegrationTestAllProtocols, UnwindsTrackedObjectStack) {
const std::string request_kill_config =
R"EOF(
name: envoy.filters.http.kill_request
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.kill_request.v3.KillRequest
probability:
numerator: 100
)EOF";
initializeFilter(request_kill_config);
codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http")));
const Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
{":path", "/test"},
{":scheme", "http"},
{":authority", "host"},
{"x-envoy-kill-request", "true"}};
// We should have the following directly on the tracked object stack and should dump them on
// crash:
// - ActiveStream
// - Http(1|2)::ConnectionImpl
// - Network::ConnectionImpl
const std::string death_string = GetParam().downstream_protocol == Http::CodecClient::Type::HTTP2
? "ActiveStream.*Http2::ConnectionImpl.*ConnectionImpl"
: "ActiveStream.*Http1::ConnectionImpl.*ConnectionImpl";
EXPECT_DEATH(sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 1024),
death_string);
}

TEST_P(CrashIntegrationTestAllProtocols, ResponseCrashDumpsTheCorrespondingRequest) {
const std::string response_kill_config =
R"EOF(
name: envoy.filters.http.kill_request
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.kill_request.v3.KillRequest
probability:
numerator: 100
direction: RESPONSE
)EOF";
initializeFilter(response_kill_config);
codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http")));

const Http::TestResponseHeaderMapImpl kill_response_headers = {{":status", "200"},
{"x-envoy-kill-request", "true"}};
// Check that we dump the downstream request
EXPECT_DEATH(
sendRequestAndWaitForResponse(default_request_headers_, 0, kill_response_headers, 1024),
"Dumping corresponding downstream request.*UpstreamRequest.*request_headers:");
}
#endif
#endif
#endif

} // namespace
} // namespace KillRequest
} // namespace HttpFilters
} // namespace Extensions
} // namespace Envoy