- Notifications
You must be signed in to change notification settings - Fork 4.9k
/
Copy pathintegration_tcp_client.h
93 lines (79 loc) · 3.99 KB
/
integration_tcp_client.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
#pragma once
#include<chrono>
#include<cstddef>
#include<cstdint>
#include<memory>
#include<string>
#include"envoy/event/dispatcher.h"
#include"envoy/network/address.h"
#include"envoy/network/connection.h"
#include"envoy/network/listen_socket.h"
#include"envoy/network/socket.h"
#include"test/integration/utility.h"
#include"test/mocks/buffer/mocks.h"
#include"test/test_common/utility.h"
#include"absl/types/optional.h"
#include"gtest/gtest.h"
#include"gtest/gtest_pred_impl.h"
namespaceEnvoy {
/**
* TCP client used during integration testing.
*/
classIntegrationTcpClient {
public:
IntegrationTcpClient(Event::Dispatcher& dispatcher, MockBufferFactory& factory, uint32_t port,
Network::Address::IpVersion version, bool enable_half_close,
const Network::ConnectionSocket::OptionsSharedPtr& options,
Network::Address::InstanceConstSharedPtr source_address = nullptr,
absl::string_view destination_address = "");
voidclose();
voidclose(Network::ConnectionCloseType close_type);
voidwaitForData(const std::string& data, bool exact_match = true);
// wait for at least `length` bytes to be received
ABSL_MUST_USE_RESULT AssertionResult
waitForData(size_t length, std::chrono::milliseconds timeout = TestUtility::DefaultTimeout);
voidwaitForDisconnect(bool ignore_spurious_events = false);
voidwaitForHalfClose(bool ignore_spurious_events = false);
voidwaitForHalfClose(std::chrono::milliseconds timeout, bool ignore_spurious_events = false);
voidreadDisable(bool disabled);
ABSL_MUST_USE_RESULT AssertionResult
write(const std::string& data, bool end_stream = false, bool verify = true,
std::chrono::milliseconds timeout = TestUtility::DefaultTimeout);
const std::string& data() { return payload_reader_->data(); }
boolconnected() const { return !disconnected_; }
// clear up to the `count` number of bytes of received data
voidclearData(size_t count = std::string::npos) { payload_reader_->clearData(count); }
Network::Connection* connection() const { return connection_.get(); }
// Waits for the TCP response to match the given matcher, with a timeout
// of two seconds of no data being received.
boolwaitForTcpResponse(testing::Matcher<absl::string_view> matcher,
std::chrono::milliseconds timeout = std::chrono::seconds(2));
private:
structConnectionCallbacks : publicNetwork::ConnectionCallbacks {
ConnectionCallbacks(IntegrationTcpClient& parent) : parent_(parent) {}
// Network::ConnectionCallbacks
voidonEvent(Network::ConnectionEvent event) override;
voidonAboveWriteBufferHighWatermark() override {}
voidonBelowWriteBufferLowWatermark() override {}
IntegrationTcpClient& parent_;
};
std::shared_ptr<WaitForPayloadReader> payload_reader_;
std::shared_ptr<ConnectionCallbacks> callbacks_;
Network::ClientConnectionPtr connection_;
bool disconnected_{};
MockWatermarkBuffer* client_write_buffer_;
};
using IntegrationTcpClientPtr = std::unique_ptr<IntegrationTcpClient>;
// Waits for the TCP response to match the given matcher. If two seconds
// passes with no more data arriving, times out and explains the difference
// between the received data and the matcher.
// This can't be implemented as a matcher because it has side-effects, and
// implementing it as a function results in the test line number being lost
// from the output on failure, so this is an appropriate case for a macro.
#defineEXPECT_TCP_RESPONSE(tcp_client, matcher) \
{ \
testing::Matcher<absl::string_view> m = matcher; \
tcp_client->waitForTcpResponse(m); \
EXPECT_THAT(tcp_client->data(), m); \
}
} // namespace Envoy