Coverage Report

Created: 2023-11-12 09:30

/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