forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubscription_test_harness.h
133 lines (112 loc) · 5.43 KB
/
subscription_test_harness.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
#pragma once
#include "source/common/config/utility.h"
#include "test/mocks/stats/mocks.h"
#include "test/test_common/simulated_time_system.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace Envoy {
namespace Config {
enum class LegacyOrUnified { Legacy, Unified };
const uint64_t TEST_TIME_MILLIS = 42000;
/**
* Interface for different Subscription implementation test harnesses. This has common functionality
* that we can use to write tests that work across all Subscription types. EDS is used as the API in
* tests depending on SubscriptionTestHarness, as representative of a subscription API.
*/
class SubscriptionTestHarness : public Event::TestUsingSimulatedTime {
public:
SubscriptionTestHarness()
: stats_(Utility::generateStats(stats_store_)),
control_plane_stats_(Utility::generateControlPlaneStats(stats_store_)) {
simTime().setSystemTime(SystemTime(std::chrono::milliseconds(TEST_TIME_MILLIS)));
}
virtual ~SubscriptionTestHarness() = default;
/**
* Start subscription and set related expectations.
* @param cluster_names initial cluster names to request via EDS.
*/
virtual void startSubscription(const std::set<std::string>& cluster_names) PURE;
/**
* Update cluster names to be delivered via EDS.
* @param cluster_names cluster names.
*/
virtual void updateResourceInterest(const std::set<std::string>& cluster_names) PURE;
/**
* Expect that an update request is sent by the Subscription implementation.
* @param cluster_names cluster names to expect in the request.
* @param version version_info to expect in the request.
* @param expect_node whether the node information should be expected
*/
virtual void expectSendMessage(const std::set<std::string>& cluster_names,
const std::string& version, bool expect_node) PURE;
/**
* Deliver a response to the Subscription implementation and validate.
* @param cluster_names cluster names to provide in the response
* @param version version_info to provide in the response.
* @param accept will the onConfigUpdate() callback accept the response?
*/
virtual void deliverConfigUpdate(const std::vector<std::string>& cluster_names,
const std::string& version, bool accept) PURE;
virtual testing::AssertionResult statsAre(uint32_t attempt, uint32_t success, uint32_t rejected,
uint32_t failure, uint32_t init_fetch_timeout,
uint64_t update_time, uint64_t version,
absl::string_view version_text) {
// TODO(fredlas) rework update_success_ to make sense across all xDS carriers. Its value in
// statsAre() calls in many tests will probably have to be changed.
UNREFERENCED_PARAMETER(attempt);
if (success != stats_.update_success_.value()) {
return testing::AssertionFailure() << "update_success: expected " << success << ", got "
<< stats_.update_success_.value();
}
if (rejected != stats_.update_rejected_.value()) {
return testing::AssertionFailure() << "update_rejected: expected " << rejected << ", got "
<< stats_.update_rejected_.value();
}
if (failure != stats_.update_failure_.value()) {
return testing::AssertionFailure() << "update_failure: expected " << failure << ", got "
<< stats_.update_failure_.value();
}
if (init_fetch_timeout != stats_.init_fetch_timeout_.value()) {
return testing::AssertionFailure() << "init_fetch_timeout: expected " << init_fetch_timeout
<< ", got " << stats_.init_fetch_timeout_.value();
}
if (update_time != stats_.update_time_.value()) {
return testing::AssertionFailure()
<< "update_time: expected " << update_time << ", got " << stats_.update_time_.value();
}
if (version != stats_.version_.value()) {
return testing::AssertionFailure()
<< "version: expected " << version << ", got " << stats_.version_.value();
}
if (version_text != stats_.version_text_.value()) {
return testing::AssertionFailure()
<< "version_text: expected " << version << ", got " << stats_.version_text_.value();
}
return testing::AssertionSuccess();
}
virtual void verifyControlPlaneStats(uint32_t connected_state) {
EXPECT_EQ(connected_state, control_plane_stats_.connected_state_.value());
}
virtual void expectConfigUpdateFailed() PURE;
virtual void expectEnableInitFetchTimeoutTimer(std::chrono::milliseconds timeout) PURE;
virtual void expectDisableInitFetchTimeoutTimer() PURE;
virtual void callInitFetchTimeoutCb() PURE;
virtual void doSubscriptionTearDown() {}
// Helper util to convert to absl::flat_hash_set when calling Subscription interface methods.
absl::flat_hash_set<std::string> flattenResources(const std::set<std::string>& resources) {
absl::flat_hash_set<std::string> flat_resources;
std::copy(resources.begin(), resources.end(),
std::inserter(flat_resources, flat_resources.begin()));
return flat_resources;
}
Stats::TestUtil::TestStore stats_store_;
SubscriptionStats stats_;
ControlPlaneStats control_plane_stats_;
};
ACTION_P(ThrowOnRejectedConfig, accept) {
if (!accept) {
throw EnvoyException("bad config");
}
}
} // namespace Config
} // namespace Envoy