Skip to content

Commit 0511bbc

Browse files
fix: fix 1000+ buckets pagination issue (#15112)
* test: add unit test to confirm absence of pageToken param in listBuckets request, which causes the 1000+ buckets infinite pagination loop * test: add unit test to confirm absence of pageToken param in listBuckets request, which causes the 1000+ buckets infinite pagination loop * test: add unit test to confirm absence of pageToken param in listBuckets request, which causes the 1000+ buckets infinite pagination loop * test: add unit test to confirm absence of pageToken param in listBuckets request, which causes the 1000+ buckets infinite pagination loop * test: add unit test to confirm absence of pageToken param in listBuckets request, which causes the 1000+ buckets infinite pagination loop * test: add unit test to confirm absence of pageToken param in listBuckets request, which causes the 1000+ buckets infinite pagination loop --------- Co-authored-by: Denis DelGrosso <[email protected]>
1 parent 67bbff6 commit 0511bbc

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

google/cloud/storage/internal/rest/stub.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ StatusOr<ListBucketsResponse> RestStub::ListBuckets(
183183
if (!headers.ok()) return headers;
184184
request.AddOptionsToHttpRequest(builder);
185185
builder.AddQueryParameter("project", request.project_id());
186+
if (!request.page_token().empty()) {
187+
builder.AddQueryParameter("pageToken", request.page_token());
188+
}
186189
return ParseFromRestResponse<ListBucketsResponse>(
187190
storage_rest_client_->Get(context, std::move(builder).BuildRequest()));
188191
}

google/cloud/storage/internal/rest/stub_test.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ using ::testing::ElementsAre;
4040
using ::testing::Eq;
4141
using ::testing::HasSubstr;
4242
using ::testing::Matcher;
43+
using ::testing::Not;
4344
using ::testing::Pair;
4445
using ::testing::ResultOf;
4546
using ::testing::Return;
@@ -193,6 +194,42 @@ TEST(RestStubTest, CreateBucket) {
193194
StatusIs(PermanentError().code(), PermanentError().message()));
194195
}
195196

197+
TEST(RestStubTest, ListBucketsIncludesPageTokenWhenPresentInRequest) {
198+
auto mock = std::make_shared<MockRestClient>();
199+
std::string expected_token = "test-page-token";
200+
ListBucketsRequest request("test-project-id");
201+
request.set_page_token(expected_token);
202+
203+
EXPECT_CALL(*mock,
204+
Get(ExpectedContext(),
205+
ResultOf(
206+
"request parameters contain 'pageToken'",
207+
[](RestRequest const& r) { return r.parameters(); },
208+
Contains(Pair("pageToken", expected_token)))))
209+
.WillOnce(Return(PermanentError()));
210+
211+
auto tested = std::make_unique<RestStub>(Options{}, mock, mock);
212+
auto context = TestContext();
213+
tested->ListBuckets(context, TestOptions(), request);
214+
}
215+
216+
TEST(RestStubTest, ListBucketsOmitsPageTokenWhenEmptyInRequest) {
217+
auto mock = std::make_shared<MockRestClient>();
218+
ListBucketsRequest request("test-project-id");
219+
220+
EXPECT_CALL(*mock,
221+
Get(ExpectedContext(),
222+
ResultOf(
223+
"request parameters do not contain 'pageToken'",
224+
[](RestRequest const& r) { return r.parameters(); },
225+
Not(Contains(Pair("pageToken", _))))))
226+
.WillOnce(Return(PermanentError()));
227+
228+
auto tested = std::make_unique<RestStub>(Options{}, mock, mock);
229+
auto context = TestContext();
230+
tested->ListBuckets(context, TestOptions(), request);
231+
}
232+
196233
TEST(RestStubTest, GetBucketMetadata) {
197234
auto mock = std::make_shared<MockRestClient>();
198235
EXPECT_CALL(*mock, Get(ExpectedContext(), ExpectedRequest()))

0 commit comments

Comments
 (0)