/proc/self/cwd/test/integration/autonomous_upstream.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "test/integration/autonomous_upstream.h" |
2 | | |
3 | | namespace Envoy { |
4 | | namespace { |
5 | | |
6 | | void headerToInt(const char header_name[], int32_t& return_int, |
7 | 3.23k | Http::TestResponseHeaderMapImpl& headers) { |
8 | 3.23k | const std::string header_value(headers.get_(header_name)); |
9 | 3.23k | if (!header_value.empty()) { |
10 | 0 | uint64_t parsed_value; |
11 | 0 | RELEASE_ASSERT(absl::SimpleAtoi(header_value, &parsed_value) && |
12 | 0 | parsed_value < static_cast<uint32_t>(std::numeric_limits<int32_t>::max()), |
13 | 0 | ""); |
14 | 0 | return_int = parsed_value; |
15 | 0 | } |
16 | 3.23k | } |
17 | | |
18 | | } // namespace |
19 | | |
20 | | const char AutonomousStream::RESPONSE_SIZE_BYTES[] = "response_size_bytes"; |
21 | | const char AutonomousStream::RESPONSE_DATA_BLOCKS[] = "response_data_blocks"; |
22 | | const char AutonomousStream::EXPECT_REQUEST_SIZE_BYTES[] = "expect_request_size_bytes"; |
23 | | const char AutonomousStream::RESET_AFTER_REQUEST[] = "reset_after_request"; |
24 | | const char AutonomousStream::CLOSE_AFTER_RESPONSE[] = "close_after_response"; |
25 | | const char AutonomousStream::NO_TRAILERS[] = "no_trailers"; |
26 | | const char AutonomousStream::NO_END_STREAM[] = "no_end_stream"; |
27 | | |
28 | | AutonomousStream::AutonomousStream(FakeHttpConnection& parent, Http::ResponseEncoder& encoder, |
29 | | AutonomousUpstream& upstream, bool allow_incomplete_streams) |
30 | | : FakeStream(parent, encoder, upstream.timeSystem()), upstream_(upstream), |
31 | 1.07k | allow_incomplete_streams_(allow_incomplete_streams) {}Unexecuted instantiation: Envoy::AutonomousStream::AutonomousStream(Envoy::FakeHttpConnection&, Envoy::Http::ResponseEncoder&, Envoy::AutonomousUpstream&, bool) Envoy::AutonomousStream::AutonomousStream(Envoy::FakeHttpConnection&, Envoy::Http::ResponseEncoder&, Envoy::AutonomousUpstream&, bool) Line | Count | Source | 31 | 1.07k | allow_incomplete_streams_(allow_incomplete_streams) {} |
|
32 | | |
33 | 1.07k | AutonomousStream::~AutonomousStream() { |
34 | 1.07k | if (!allow_incomplete_streams_) { |
35 | 0 | RELEASE_ASSERT(complete(), "Found that end_stream is not true"); |
36 | 0 | } |
37 | 1.07k | } |
38 | | |
39 | | // By default, automatically send a response when the request is complete. |
40 | 2.03k | void AutonomousStream::setEndStream(bool end_stream) { |
41 | 2.03k | FakeStream::setEndStream(end_stream); |
42 | 2.03k | if (end_stream) { |
43 | 1.07k | sendResponse(); |
44 | 1.07k | } |
45 | 2.03k | } |
46 | | |
47 | | // Check all the special headers and send a customized response based on them. |
48 | 1.07k | void AutonomousStream::sendResponse() { |
49 | 1.07k | Http::TestResponseHeaderMapImpl headers(*headers_); |
50 | 1.07k | upstream_.setLastRequestHeaders(*headers_); |
51 | | |
52 | 1.07k | int32_t request_body_length = -1; |
53 | 1.07k | headerToInt(EXPECT_REQUEST_SIZE_BYTES, request_body_length, headers); |
54 | 1.07k | if (request_body_length >= 0) { |
55 | 0 | EXPECT_EQ(request_body_length, body_.length()); |
56 | 0 | } |
57 | | |
58 | 1.07k | if (!headers.get_(RESET_AFTER_REQUEST).empty()) { |
59 | 0 | encodeResetStream(); |
60 | 0 | return; |
61 | 0 | } |
62 | | |
63 | 1.07k | int32_t response_body_length = 10; |
64 | 1.07k | headerToInt(RESPONSE_SIZE_BYTES, response_body_length, headers); |
65 | | |
66 | 1.07k | int32_t response_data_blocks = 1; |
67 | 1.07k | headerToInt(RESPONSE_DATA_BLOCKS, response_data_blocks, headers); |
68 | | |
69 | 1.07k | const bool end_stream = headers.get_(NO_END_STREAM).empty(); |
70 | 1.07k | const bool send_trailers = end_stream && headers.get_(NO_TRAILERS).empty(); |
71 | 1.07k | const bool headers_only_response = !send_trailers && response_data_blocks == 0 && end_stream; |
72 | | |
73 | 1.07k | pre_response_headers_metadata_ = upstream_.preResponseHeadersMetadata(); |
74 | 1.07k | if (pre_response_headers_metadata_) { |
75 | 0 | encodeMetadata(*pre_response_headers_metadata_); |
76 | 0 | } |
77 | | |
78 | 1.07k | encodeHeaders(upstream_.responseHeaders(), headers_only_response); |
79 | 1.07k | if (!headers_only_response) { |
80 | 1.07k | if (upstream_.responseBody().has_value()) { |
81 | 0 | encodeData(*upstream_.responseBody(), !send_trailers); |
82 | 1.07k | } else { |
83 | 2.15k | for (int32_t i = 0; i < response_data_blocks; ++i) { |
84 | 1.07k | encodeData(response_body_length, |
85 | 1.07k | i == (response_data_blocks - 1) && !send_trailers && end_stream); |
86 | 1.07k | } |
87 | 1.07k | } |
88 | 1.07k | if (send_trailers) { |
89 | 1.07k | encodeTrailers(upstream_.responseTrailers()); |
90 | 1.07k | } |
91 | 1.07k | } |
92 | 1.07k | if (!headers.get_(CLOSE_AFTER_RESPONSE).empty()) { |
93 | 0 | parent_.connection().dispatcher().post( |
94 | 0 | [this]() -> void { parent_.connection().close(Network::ConnectionCloseType::FlushWrite); }); |
95 | 0 | return; |
96 | 0 | } |
97 | 1.07k | } |
98 | | |
99 | | AutonomousHttpConnection::AutonomousHttpConnection(AutonomousUpstream& autonomous_upstream, |
100 | | SharedConnectionWrapper& shared_connection, |
101 | | Http::CodecType type, |
102 | | uint32_t max_request_headers_kb, |
103 | | uint32_t max_request_headers_count, |
104 | | AutonomousUpstream& upstream) |
105 | | : FakeHttpConnection(autonomous_upstream, shared_connection, type, upstream.timeSystem(), |
106 | | max_request_headers_kb, max_request_headers_count, |
107 | | envoy::config::core::v3::HttpProtocolOptions::ALLOW), |
108 | 577 | upstream_(upstream) {}Unexecuted instantiation: Envoy::AutonomousHttpConnection::AutonomousHttpConnection(Envoy::AutonomousUpstream&, Envoy::SharedConnectionWrapper&, Envoy::Http::CodecType, unsigned int, unsigned int, Envoy::AutonomousUpstream&) Envoy::AutonomousHttpConnection::AutonomousHttpConnection(Envoy::AutonomousUpstream&, Envoy::SharedConnectionWrapper&, Envoy::Http::CodecType, unsigned int, unsigned int, Envoy::AutonomousUpstream&) Line | Count | Source | 108 | 577 | upstream_(upstream) {} |
|
109 | | |
110 | | Http::RequestDecoder& AutonomousHttpConnection::newStream(Http::ResponseEncoder& response_encoder, |
111 | 1.07k | bool) { |
112 | 1.07k | auto stream = |
113 | 1.07k | new AutonomousStream(*this, response_encoder, upstream_, upstream_.allow_incomplete_streams_); |
114 | 1.07k | streams_.push_back(FakeStreamPtr{stream}); |
115 | 1.07k | return *(stream); |
116 | 1.07k | } |
117 | | |
118 | 591 | AutonomousUpstream::~AutonomousUpstream() { |
119 | | // Make sure the dispatcher is stopped before the connections are destroyed. |
120 | 591 | cleanUp(); |
121 | 591 | http_connections_.clear(); |
122 | 591 | } |
123 | | |
124 | | bool AutonomousUpstream::createNetworkFilterChain(Network::Connection& connection, |
125 | 577 | const Filter::NetworkFilterFactoriesList&) { |
126 | 577 | shared_connections_.emplace_back(new SharedConnectionWrapper(connection)); |
127 | 577 | AutonomousHttpConnectionPtr http_connection(new AutonomousHttpConnection( |
128 | 577 | *this, *shared_connections_.back(), http_type_, config().max_request_headers_kb_, |
129 | 577 | config().max_request_headers_count_, *this)); |
130 | 577 | http_connection->initialize(); |
131 | 577 | http_connections_.push_back(std::move(http_connection)); |
132 | 577 | return true; |
133 | 577 | } |
134 | | |
135 | 577 | bool AutonomousUpstream::createListenerFilterChain(Network::ListenerFilterManager&) { return true; } |
136 | | |
137 | | void AutonomousUpstream::createUdpListenerFilterChain(Network::UdpListenerFilterManager&, |
138 | 0 | Network::UdpReadFilterCallbacks&) {} |
139 | | |
140 | 0 | bool AutonomousUpstream::createQuicListenerFilterChain(Network::QuicListenerFilterManager&) { |
141 | 0 | return true; |
142 | 0 | } |
143 | | |
144 | 1.07k | void AutonomousUpstream::setLastRequestHeaders(const Http::HeaderMap& headers) { |
145 | 1.07k | Thread::LockGuard lock(headers_lock_); |
146 | 1.07k | last_request_headers_ = std::make_unique<Http::TestRequestHeaderMapImpl>(headers); |
147 | 1.07k | } |
148 | | |
149 | 0 | std::unique_ptr<Http::TestRequestHeaderMapImpl> AutonomousUpstream::lastRequestHeaders() { |
150 | 0 | Thread::LockGuard lock(headers_lock_); |
151 | 0 | return std::move(last_request_headers_); |
152 | 0 | } |
153 | | |
154 | | void AutonomousUpstream::setResponseTrailers( |
155 | 0 | std::unique_ptr<Http::TestResponseTrailerMapImpl>&& response_trailers) { |
156 | 0 | Thread::LockGuard lock(headers_lock_); |
157 | 0 | response_trailers_ = std::move(response_trailers); |
158 | 0 | } |
159 | | |
160 | 0 | void AutonomousUpstream::setResponseBody(std::string body) { |
161 | 0 | Thread::LockGuard lock(headers_lock_); |
162 | 0 | response_body_ = body; |
163 | 0 | } |
164 | | |
165 | | void AutonomousUpstream::setResponseHeaders( |
166 | 0 | std::unique_ptr<Http::TestResponseHeaderMapImpl>&& response_headers) { |
167 | 0 | Thread::LockGuard lock(headers_lock_); |
168 | 0 | response_headers_ = std::move(response_headers); |
169 | 0 | } |
170 | | |
171 | | void AutonomousUpstream::setPreResponseHeadersMetadata( |
172 | 0 | std::unique_ptr<Http::MetadataMapVector>&& metadata) { |
173 | 0 | Thread::LockGuard lock(headers_lock_); |
174 | 0 | pre_response_headers_metadata_ = std::move(metadata); |
175 | 0 | } |
176 | | |
177 | 1.07k | Http::TestResponseTrailerMapImpl AutonomousUpstream::responseTrailers() { |
178 | 1.07k | Thread::LockGuard lock(headers_lock_); |
179 | 1.07k | Http::TestResponseTrailerMapImpl return_trailers = *response_trailers_; |
180 | 1.07k | return return_trailers; |
181 | 1.07k | } |
182 | | |
183 | 1.07k | absl::optional<std::string> AutonomousUpstream::responseBody() { |
184 | 1.07k | Thread::LockGuard lock(headers_lock_); |
185 | 1.07k | return response_body_; |
186 | 1.07k | } |
187 | | |
188 | 1.07k | Http::TestResponseHeaderMapImpl AutonomousUpstream::responseHeaders() { |
189 | 1.07k | Thread::LockGuard lock(headers_lock_); |
190 | 1.07k | Http::TestResponseHeaderMapImpl return_headers = *response_headers_; |
191 | 1.07k | return return_headers; |
192 | 1.07k | } |
193 | | |
194 | 1.07k | std::unique_ptr<Http::MetadataMapVector> AutonomousUpstream::preResponseHeadersMetadata() { |
195 | 1.07k | Thread::LockGuard lock(headers_lock_); |
196 | 1.07k | return std::move(pre_response_headers_metadata_); |
197 | 1.07k | } |
198 | | |
199 | | AssertionResult AutonomousUpstream::closeConnection(uint32_t index, |
200 | 0 | std::chrono::milliseconds timeout) { |
201 | 0 | return shared_connections_[index]->executeOnDispatcher( |
202 | 0 | [](Network::Connection& connection) { |
203 | 0 | ASSERT(connection.state() == Network::Connection::State::Open); |
204 | 0 | connection.close(Network::ConnectionCloseType::FlushWrite); |
205 | 0 | }, |
206 | 0 | timeout); |
207 | 0 | } |
208 | | |
209 | | } // namespace Envoy |