Skip to content

Commit 685a61b

Browse files
committed
Add one more test
Signed-off-by: Yan Avlasov <yavlasov@google.com>
1 parent d93457e commit 685a61b

1 file changed

Lines changed: 89 additions & 2 deletions

File tree

test/extensions/filters/http/rate_limit_quota/filter_persistence_test.cc

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,11 @@ class FilterPersistenceTest : public Event::TestUsingSimulatedTime,
157157
}
158158
});
159159
tls_store_emptied_ = std::make_unique<absl::Notification>();
160-
GlobalTlsStores::registerEmptiedCb([&]() { tls_store_emptied_->Notify(); });
160+
GlobalTlsStores::registerEmptiedCb([&]() {
161+
if (tls_store_emptied_ != nullptr && !tls_store_emptied_->HasBeenNotified()) {
162+
tls_store_emptied_->Notify();
163+
}
164+
});
161165
}
162166

163167
void updateConfigInPlace(std::function<void(envoy::config::bootstrap::v3::Bootstrap&)> modifier) {
@@ -210,7 +214,10 @@ class FilterPersistenceTest : public Event::TestUsingSimulatedTime,
210214
cleanupUpstreamAndDownstream();
211215
}
212216

213-
void TearDown() override { cleanUp(); }
217+
void TearDown() override {
218+
cleanUp();
219+
GlobalTlsStores::registerEmptiedCb(nullptr);
220+
}
214221

215222
// Send a request through the envoy & possibly to traffic_upstream_. Returns
216223
// the response's status code.
@@ -535,6 +542,86 @@ domain: "test_domain"
535542
ASSERT_EQ(sendRequest(&headers), "429");
536543
}
537544

545+
// Verify that the callback registered via registerEmptiedCb fires every time
546+
// the stores map becomes empty.
547+
TEST_P(FilterPersistenceTest, TestEmptiedCallbackFiresMultipleTimes) {
548+
uint32_t emptied_count = 0;
549+
auto n1 = std::make_shared<absl::Notification>();
550+
GlobalTlsStores::registerEmptiedCb([&emptied_count, &n1]() {
551+
emptied_count++;
552+
if (!n1->HasBeenNotified()) {
553+
n1->Notify();
554+
}
555+
});
556+
557+
auto remove_rlqs = [&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
558+
auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0);
559+
auto* hcm_filter = listener->mutable_filter_chains(0)->mutable_filters(0);
560+
HttpConnectionManager hcm_config;
561+
hcm_filter->mutable_typed_config()->UnpackTo(&hcm_config);
562+
auto* filters = hcm_config.mutable_http_filters();
563+
for (int i = 0; i < filters->size();) {
564+
if (filters->Get(i).name() == "envoy.filters.http.rate_limit_quota") {
565+
filters->DeleteSubrange(i, 1);
566+
} else {
567+
i++;
568+
}
569+
}
570+
hcm_filter->mutable_typed_config()->PackFrom(hcm_config);
571+
};
572+
573+
// 1. Initial removal of the RLQS filter to trigger the first call of the callback.
574+
updateConfigInPlace(remove_rlqs);
575+
ASSERT_TRUE(n1->WaitForNotificationWithTimeout(absl::Seconds(3)));
576+
EXPECT_EQ(emptied_count, 1);
577+
578+
// 2. Add the filter back and verify it works.
579+
updateConfigInPlace([&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
580+
auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0);
581+
auto* hcm_filter = listener->mutable_filter_chains(0)->mutable_filters(0);
582+
HttpConnectionManager hcm_config;
583+
hcm_filter->mutable_typed_config()->UnpackTo(&hcm_config);
584+
// Prepend the RLQS filter.
585+
(void)hcm_config.add_http_filters();
586+
for (int i = hcm_config.http_filters_size() - 1; i > 0; --i) {
587+
hcm_config.mutable_http_filters()->SwapElements(i, i - 1);
588+
}
589+
TestUtility::loadFromYaml(kDefaultRateLimitQuotaFilter, *hcm_config.mutable_http_filters(0));
590+
hcm_filter->mutable_typed_config()->PackFrom(hcm_config);
591+
});
592+
absl::flat_hash_map<std::string, std::string> headers = {{"environment", "staging"}};
593+
ASSERT_EQ(sendRequest(&headers), "200");
594+
595+
// 3. Remove the filter again. The callback should be called a second time.
596+
n1 = std::make_shared<absl::Notification>();
597+
updateConfigInPlace(remove_rlqs);
598+
ASSERT_TRUE(n1->WaitForNotificationWithTimeout(absl::Seconds(3)));
599+
EXPECT_EQ(emptied_count, 2);
600+
601+
// Restore the callback for TearDown/subsequent tests.
602+
GlobalTlsStores::registerEmptiedCb([&]() {
603+
if (tls_store_emptied_ != nullptr && !tls_store_emptied_->HasBeenNotified()) {
604+
tls_store_emptied_->Notify();
605+
}
606+
});
607+
608+
// Add it back one last time so TearDown has something to wipe and the
609+
// notification is triggered.
610+
tls_store_emptied_ = std::make_unique<absl::Notification>();
611+
updateConfigInPlace([&](envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
612+
auto* listener = bootstrap.mutable_static_resources()->mutable_listeners(0);
613+
auto* hcm_filter = listener->mutable_filter_chains(0)->mutable_filters(0);
614+
HttpConnectionManager hcm_config;
615+
hcm_filter->mutable_typed_config()->UnpackTo(&hcm_config);
616+
(void)hcm_config.add_http_filters();
617+
for (int i = hcm_config.http_filters_size() - 1; i > 0; --i) {
618+
hcm_config.mutable_http_filters()->SwapElements(i, i - 1);
619+
}
620+
TestUtility::loadFromYaml(kDefaultRateLimitQuotaFilter, *hcm_config.mutable_http_filters(0));
621+
hcm_filter->mutable_typed_config()->PackFrom(hcm_config);
622+
});
623+
}
624+
538625
} // namespace
539626
} // namespace RateLimitQuota
540627
} // namespace HttpFilters

0 commit comments

Comments
 (0)