forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utility.h
194 lines (164 loc) · 6.84 KB
/
utility.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#pragma once
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include "envoy/api/api.h"
#include "envoy/http/codec.h"
#include "envoy/http/header_map.h"
#include "envoy/network/filter.h"
#include "common/common/assert.h"
#include "common/common/utility.h"
#include "common/http/codec_client.h"
#include "test/test_common/printers.h"
#include "test/test_common/test_time.h"
namespace Envoy {
/**
* A buffering response decoder used for testing.
*/
class BufferingStreamDecoder : public Http::StreamDecoder, public Http::StreamCallbacks {
public:
BufferingStreamDecoder(std::function<void()> on_complete_cb) : on_complete_cb_(on_complete_cb) {}
bool complete() { return complete_; }
const Http::HeaderMap& headers() { return *headers_; }
const std::string& body() { return body_; }
// Http::StreamDecoder
void decode100ContinueHeaders(Http::HeaderMapPtr&&) override {}
void decodeHeaders(Http::HeaderMapPtr&& headers, bool end_stream) override;
void decodeData(Buffer::Instance&, bool end_stream) override;
void decodeTrailers(Http::HeaderMapPtr&& trailers) override;
// Http::StreamCallbacks
void onResetStream(Http::StreamResetReason reason) override;
void onAboveWriteBufferHighWatermark() override {}
void onBelowWriteBufferLowWatermark() override {}
private:
void onComplete();
Http::HeaderMapPtr headers_;
std::string body_;
bool complete_{};
std::function<void()> on_complete_cb_;
};
typedef std::unique_ptr<BufferingStreamDecoder> BufferingStreamDecoderPtr;
/**
* Basic driver for a raw connection.
*/
class RawConnectionDriver {
public:
typedef std::function<void(Network::ClientConnection&, const Buffer::Instance&)> ReadCallback;
RawConnectionDriver(uint32_t port, Buffer::Instance& initial_data, ReadCallback data_callback,
Network::Address::IpVersion version);
~RawConnectionDriver();
const Network::Connection& connection() { return *client_; }
bool connecting() { return callbacks_->connecting_; }
void run(Event::Dispatcher::RunType run_type = Event::Dispatcher::RunType::Block);
void close();
Network::ConnectionEvent last_connection_event() const {
return callbacks_->last_connection_event_;
}
private:
struct ForwardingFilter : public Network::ReadFilterBaseImpl {
ForwardingFilter(RawConnectionDriver& parent, ReadCallback cb)
: parent_(parent), data_callback_(cb) {}
// Network::ReadFilter
Network::FilterStatus onData(Buffer::Instance& data, bool) override {
data_callback_(*parent_.client_, data);
data.drain(data.length());
return Network::FilterStatus::StopIteration;
}
RawConnectionDriver& parent_;
ReadCallback data_callback_;
};
struct ConnectionCallbacks : public Network::ConnectionCallbacks {
void onEvent(Network::ConnectionEvent event) override {
last_connection_event_ = event;
connecting_ = false;
}
void onAboveWriteBufferHighWatermark() override {}
void onBelowWriteBufferLowWatermark() override {}
bool connecting_{true};
Network::ConnectionEvent last_connection_event_;
};
Api::ApiPtr api_;
Event::DispatcherPtr dispatcher_;
std::unique_ptr<ConnectionCallbacks> callbacks_;
Network::ClientConnectionPtr client_;
};
/**
* Utility routines for integration tests.
*/
class IntegrationUtil {
public:
/**
* Make a new connection, issues a request, and then disconnect when the request is complete.
* @param addr supplies the address to connect to.
* @param method supplies the request method.
* @param url supplies the request url.
* @param body supplies the optional request body to send.
* @param type supplies the codec to use for the request.
* @param host supplies the host header to use for the request.
* @param content_type supplies the content-type header to use for the request, if any.
* @return BufferingStreamDecoderPtr the complete request or a partial request if there was
* remote easly disconnection.
*/
static BufferingStreamDecoderPtr
makeSingleRequest(const Network::Address::InstanceConstSharedPtr& addr, const std::string& method,
const std::string& url, const std::string& body, Http::CodecClient::Type type,
const std::string& host = "host", const std::string& content_type = "");
/**
* Make a new connection, issues a request, and then disconnect when the request is complete.
* @param port supplies the port to connect to on localhost.
* @param method supplies the request method.
* @param url supplies the request url.
* @param body supplies the optional request body to send.
* @param type supplies the codec to use for the request.
* @param version the IP addess version of the client and server.
* @param host supplies the host header to use for the request.
* @param content_type supplies the content-type header to use for the request, if any.
* @return BufferingStreamDecoderPtr the complete request or a partial request if there was
* remote easly disconnection.
*/
static BufferingStreamDecoderPtr
makeSingleRequest(uint32_t port, const std::string& method, const std::string& url,
const std::string& body, Http::CodecClient::Type type,
Network::Address::IpVersion ip_version, const std::string& host = "host",
const std::string& content_type = "");
// TODO(jmarantz): this should be injectable.
static DangerousDeprecatedTestTime evil_singleton_test_time_;
};
// A set of connection callbacks which tracks connection state.
class ConnectionStatusCallbacks : public Network::ConnectionCallbacks {
public:
bool connected() const { return connected_; }
bool closed() const { return closed_; }
// Network::ConnectionCallbacks
void onEvent(Network::ConnectionEvent event) override {
closed_ |= (event == Network::ConnectionEvent::RemoteClose ||
event == Network::ConnectionEvent::LocalClose);
connected_ |= (event == Network::ConnectionEvent::Connected);
}
void onAboveWriteBufferHighWatermark() override {}
void onBelowWriteBufferLowWatermark() override {}
private:
bool connected_{false};
bool closed_{false};
};
// A read filter which waits for a given data then stops the dispatcher loop.
class WaitForPayloadReader : public Network::ReadFilterBaseImpl {
public:
WaitForPayloadReader(Event::Dispatcher& dispatcher);
// Network::ReadFilter
Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override;
void set_data_to_wait_for(const std::string& data, bool exact_match = true) {
data_to_wait_for_ = data;
exact_match_ = exact_match;
}
const std::string& data() { return data_; }
bool readLastByte() { return read_end_stream_; }
private:
Event::Dispatcher& dispatcher_;
std::string data_to_wait_for_;
std::string data_;
bool exact_match_{true};
bool read_end_stream_{};
};
} // namespace Envoy