Skip to content

Commit 4e32737

Browse files
committed
adding more tests
1 parent e7c56d8 commit 4e32737

4 files changed

Lines changed: 324 additions & 0 deletions

File tree

google/cloud/storage/google_cloud_cpp_storage.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ if (BUILD_TESTING)
462462
internal/connection_impl_bucket_acl_test.cc
463463
internal/connection_impl_bucket_test.cc
464464
internal/connection_impl_default_object_acl_test.cc
465+
internal/connection_impl_file_upload_test.cc
465466
internal/connection_impl_notifications_test.cc
466467
internal/connection_impl_object_acl_test.cc
467468
internal/connection_impl_object_copy_test.cc
@@ -499,6 +500,7 @@ if (BUILD_TESTING)
499500
internal/service_account_requests_test.cc
500501
internal/sign_blob_requests_test.cc
501502
internal/signed_url_requests_test.cc
503+
internal/storage_connection_test.cc
502504
internal/tracing_connection_test.cc
503505
internal/tracing_object_read_source_test.cc
504506
internal/tuple_filter_test.cc
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/storage/internal/connection_impl.h"
16+
#include "google/cloud/storage/testing/mock_generic_stub.h"
17+
#include "google/cloud/storage/testing/temp_file.h"
18+
#include "google/cloud/testing_util/status_matchers.h"
19+
#include <gmock/gmock.h>
20+
#include <iterator>
21+
22+
namespace google {
23+
namespace cloud {
24+
namespace storage {
25+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
26+
namespace internal {
27+
namespace {
28+
29+
using ::google::cloud::storage::testing::MockGenericStub;
30+
using ::google::cloud::storage::testing::TempFile;
31+
using ::google::cloud::testing_util::IsOk;
32+
using ::google::cloud::testing_util::StatusIs;
33+
using ::testing::_;
34+
using ::testing::Return;
35+
36+
class ConnectionImplFileUploadTest : public ::testing::Test {
37+
protected:
38+
std::shared_ptr<StorageConnectionImpl> MakeConnection() {
39+
auto mock = std::make_unique<MockGenericStub>();
40+
EXPECT_CALL(*mock, options).WillRepeatedly(Return(Options{}));
41+
return StorageConnectionImpl::Create(std::move(mock));
42+
}
43+
};
44+
45+
TEST_F(ConnectionImplFileUploadTest, UploadFileSimpleSuccess) {
46+
auto connection = MakeConnection();
47+
auto const contents = std::string{"some simple contents"};
48+
TempFile temp(contents);
49+
InsertObjectMediaRequest request("test-bucket", "test-object", "");
50+
auto payload =
51+
connection->UploadFileSimple(temp.name(), contents.size(), request);
52+
ASSERT_STATUS_OK(payload);
53+
EXPECT_EQ(*payload.value(), contents);
54+
}
55+
56+
TEST_F(ConnectionImplFileUploadTest, UploadFileSimpleNonExistentFile) {
57+
auto connection = MakeConnection();
58+
InsertObjectMediaRequest request("test-bucket", "test-object", "");
59+
auto payload =
60+
connection->UploadFileSimple("/no/such/file/exists.txt", 123, request);
61+
EXPECT_THAT(payload, StatusIs(StatusCode::kNotFound));
62+
}
63+
64+
TEST_F(ConnectionImplFileUploadTest, UploadFileSimpleOffsetLargerThanSize) {
65+
auto connection = MakeConnection();
66+
auto const contents = std::string{"some simple contents"};
67+
TempFile temp(contents);
68+
InsertObjectMediaRequest request("test-bucket", "test-object", "");
69+
request.set_option(UploadFromOffset(contents.size() + 1));
70+
auto payload =
71+
connection->UploadFileSimple(temp.name(), contents.size(), request);
72+
EXPECT_THAT(payload, StatusIs(StatusCode::kInvalidArgument));
73+
}
74+
75+
TEST_F(ConnectionImplFileUploadTest, UploadFileSimpleWithLimit) {
76+
auto connection = MakeConnection();
77+
auto const contents = std::string{"0123456789"};
78+
TempFile temp(contents);
79+
InsertObjectMediaRequest request("test-bucket", "test-object", "");
80+
request.set_option(UploadLimit(5));
81+
auto payload =
82+
connection->UploadFileSimple(temp.name(), contents.size(), request);
83+
ASSERT_STATUS_OK(payload);
84+
EXPECT_EQ(*payload.value(), "01234");
85+
}
86+
87+
TEST_F(ConnectionImplFileUploadTest, UploadFileSimpleReadError) {
88+
auto connection = MakeConnection();
89+
auto const contents = std::string{"some simple contents"};
90+
TempFile temp(contents);
91+
// Pass a size larger than the file to trigger a read error.
92+
InsertObjectMediaRequest request("test-bucket", "test-object", "");
93+
auto payload =
94+
connection->UploadFileSimple(temp.name(), contents.size() + 1, request);
95+
EXPECT_THAT(payload, StatusIs(StatusCode::kInternal));
96+
}
97+
98+
TEST_F(ConnectionImplFileUploadTest, UploadFileResumableSuccess) {
99+
auto connection = MakeConnection();
100+
auto const contents = std::string{"some resumable contents"};
101+
TempFile temp(contents);
102+
ResumableUploadRequest request("test-bucket", "test-object");
103+
auto stream = connection->UploadFileResumable(temp.name(), request);
104+
ASSERT_STATUS_OK(stream);
105+
EXPECT_TRUE(request.HasOption<UploadContentLength>());
106+
EXPECT_EQ(request.GetOption<UploadContentLength>().value(), contents.size());
107+
std::string actual(std::istreambuf_iterator<char>(**stream), {});
108+
EXPECT_EQ(contents, actual);
109+
}
110+
111+
TEST_F(ConnectionImplFileUploadTest, UploadFileResumableNonExistentFile) {
112+
auto connection = MakeConnection();
113+
ResumableUploadRequest request("test-bucket", "test-object");
114+
auto stream =
115+
connection->UploadFileResumable("/no/such/file/exists.txt", request);
116+
EXPECT_THAT(stream, StatusIs(StatusCode::kNotFound));
117+
}
118+
119+
TEST_F(ConnectionImplFileUploadTest, UploadFileResumableOffsetLargerThanSize) {
120+
auto connection = MakeConnection();
121+
auto const contents = std::string{"some resumable contents"};
122+
TempFile temp(contents);
123+
ResumableUploadRequest request("test-bucket", "test-object");
124+
request.set_option(UploadFromOffset(contents.size() + 1));
125+
auto stream = connection->UploadFileResumable(temp.name(), request);
126+
EXPECT_THAT(stream, StatusIs(StatusCode::kInvalidArgument));
127+
}
128+
129+
TEST_F(ConnectionImplFileUploadTest, UploadFileResumableWithLimit) {
130+
auto connection = MakeConnection();
131+
auto const contents = std::string{"0123456789"};
132+
TempFile temp(contents);
133+
ResumableUploadRequest request("test-bucket", "test-object");
134+
auto const limit = 5;
135+
request.set_option(UploadLimit(limit));
136+
auto stream = connection->UploadFileResumable(temp.name(), request);
137+
ASSERT_STATUS_OK(stream);
138+
EXPECT_TRUE(request.HasOption<UploadContentLength>());
139+
EXPECT_EQ(request.GetOption<UploadContentLength>().value(), limit);
140+
141+
// Read only the limited number of bytes from the stream.
142+
std::vector<char> buffer(limit);
143+
(*stream)->read(buffer.data(), buffer.size());
144+
std::string actual(buffer.begin(), buffer.end());
145+
146+
EXPECT_EQ("01234", actual);
147+
}
148+
149+
} // namespace
150+
} // namespace internal
151+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
152+
} // namespace storage
153+
} // namespace cloud
154+
} // namespace google
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/storage/internal/storage_connection.h"
16+
#include "google/cloud/testing_util/status_matchers.h"
17+
#include <gmock/gmock.h>
18+
19+
namespace google {
20+
namespace cloud {
21+
namespace storage {
22+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
23+
namespace internal {
24+
namespace {
25+
26+
using ::google::cloud::testing_util::StatusIs;
27+
28+
// A minimal implementation of StorageConnection to test the default
29+
// implementation of some of its virtual functions.
30+
class TestStorageConnection : public StorageConnection {
31+
public:
32+
~TestStorageConnection() override = default;
33+
MOCK_METHOD(ClientOptions const&, client_options, (), (const, override));
34+
MOCK_METHOD(StatusOr<ListBucketsResponse>, ListBuckets,
35+
(ListBucketsRequest const&), (override));
36+
MOCK_METHOD(StatusOr<BucketMetadata>, CreateBucket,
37+
(CreateBucketRequest const&), (override));
38+
MOCK_METHOD(StatusOr<BucketMetadata>, GetBucketMetadata,
39+
(GetBucketMetadataRequest const&), (override));
40+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteBucket,
41+
(DeleteBucketRequest const&), (override));
42+
MOCK_METHOD(StatusOr<BucketMetadata>, UpdateBucket,
43+
(UpdateBucketRequest const&), (override));
44+
MOCK_METHOD(StatusOr<BucketMetadata>, PatchBucket,
45+
(PatchBucketRequest const&), (override));
46+
MOCK_METHOD(StatusOr<NativeIamPolicy>, GetNativeBucketIamPolicy,
47+
(GetBucketIamPolicyRequest const&), (override));
48+
MOCK_METHOD(StatusOr<NativeIamPolicy>, SetNativeBucketIamPolicy,
49+
(SetNativeBucketIamPolicyRequest const&), (override));
50+
MOCK_METHOD(StatusOr<TestBucketIamPermissionsResponse>,
51+
TestBucketIamPermissions,
52+
(TestBucketIamPermissionsRequest const&), (override));
53+
MOCK_METHOD(StatusOr<BucketMetadata>, LockBucketRetentionPolicy,
54+
(LockBucketRetentionPolicyRequest const&), (override));
55+
MOCK_METHOD(StatusOr<ObjectMetadata>, InsertObjectMedia,
56+
(InsertObjectMediaRequest const&), (override));
57+
MOCK_METHOD(StatusOr<ObjectMetadata>, CopyObject, (CopyObjectRequest const&),
58+
(override));
59+
MOCK_METHOD(StatusOr<ObjectMetadata>, GetObjectMetadata,
60+
(GetObjectMetadataRequest const&), (override));
61+
MOCK_METHOD(StatusOr<std::unique_ptr<ObjectReadSource>>, ReadObject,
62+
(ReadObjectRangeRequest const&), (override));
63+
MOCK_METHOD(StatusOr<ListObjectsResponse>, ListObjects,
64+
(ListObjectsRequest const&), (override));
65+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteObject,
66+
(DeleteObjectRequest const&), (override));
67+
MOCK_METHOD(StatusOr<ObjectMetadata>, UpdateObject,
68+
(UpdateObjectRequest const&), (override));
69+
MOCK_METHOD(StatusOr<ObjectMetadata>, MoveObject, (MoveObjectRequest const&),
70+
(override));
71+
MOCK_METHOD(StatusOr<ObjectMetadata>, PatchObject,
72+
(PatchObjectRequest const&), (override));
73+
MOCK_METHOD(StatusOr<ObjectMetadata>, ComposeObject,
74+
(ComposeObjectRequest const&), (override));
75+
MOCK_METHOD(StatusOr<RewriteObjectResponse>, RewriteObject,
76+
(RewriteObjectRequest const&), (override));
77+
MOCK_METHOD(StatusOr<ObjectMetadata>, RestoreObject,
78+
(RestoreObjectRequest const&), (override));
79+
MOCK_METHOD(StatusOr<CreateResumableUploadResponse>, CreateResumableUpload,
80+
(ResumableUploadRequest const&), (override));
81+
MOCK_METHOD(StatusOr<QueryResumableUploadResponse>, QueryResumableUpload,
82+
(QueryResumableUploadRequest const&), (override));
83+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteResumableUpload,
84+
(DeleteResumableUploadRequest const&), (override));
85+
MOCK_METHOD(StatusOr<QueryResumableUploadResponse>, UploadChunk,
86+
(UploadChunkRequest const&), (override));
87+
MOCK_METHOD(StatusOr<ListBucketAclResponse>, ListBucketAcl,
88+
(ListBucketAclRequest const&), (override));
89+
MOCK_METHOD(StatusOr<BucketAccessControl>, CreateBucketAcl,
90+
(CreateBucketAclRequest const&), (override));
91+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteBucketAcl,
92+
(DeleteBucketAclRequest const&), (override));
93+
MOCK_METHOD(StatusOr<BucketAccessControl>, GetBucketAcl,
94+
(GetBucketAclRequest const&), (override));
95+
MOCK_METHOD(StatusOr<BucketAccessControl>, UpdateBucketAcl,
96+
(UpdateBucketAclRequest const&), (override));
97+
MOCK_METHOD(StatusOr<BucketAccessControl>, PatchBucketAcl,
98+
(PatchBucketAclRequest const&), (override));
99+
MOCK_METHOD(StatusOr<ListObjectAclResponse>, ListObjectAcl,
100+
(ListObjectAclRequest const&), (override));
101+
MOCK_METHOD(StatusOr<ObjectAccessControl>, CreateObjectAcl,
102+
(CreateObjectAclRequest const&), (override));
103+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteObjectAcl,
104+
(DeleteObjectAclRequest const&), (override));
105+
MOCK_METHOD(StatusOr<ObjectAccessControl>, GetObjectAcl,
106+
(GetObjectAclRequest const&), (override));
107+
MOCK_METHOD(StatusOr<ObjectAccessControl>, UpdateObjectAcl,
108+
(UpdateObjectAclRequest const&), (override));
109+
MOCK_METHOD(StatusOr<ObjectAccessControl>, PatchObjectAcl,
110+
(PatchObjectAclRequest const&), (override));
111+
MOCK_METHOD(StatusOr<ListDefaultObjectAclResponse>, ListDefaultObjectAcl,
112+
(ListDefaultObjectAclRequest const&), (override));
113+
MOCK_METHOD(StatusOr<ObjectAccessControl>, CreateDefaultObjectAcl,
114+
(CreateDefaultObjectAclRequest const&), (override));
115+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteDefaultObjectAcl,
116+
(DeleteDefaultObjectAclRequest const&), (override));
117+
MOCK_METHOD(StatusOr<ObjectAccessControl>, GetDefaultObjectAcl,
118+
(GetDefaultObjectAclRequest const&), (override));
119+
MOCK_METHOD(StatusOr<ObjectAccessControl>, UpdateDefaultObjectAcl,
120+
(UpdateDefaultObjectAclRequest const&), (override));
121+
MOCK_METHOD(StatusOr<ObjectAccessControl>, PatchDefaultObjectAcl,
122+
(PatchDefaultObjectAclRequest const&), (override));
123+
MOCK_METHOD(StatusOr<ServiceAccount>, GetServiceAccount,
124+
(GetProjectServiceAccountRequest const&), (override));
125+
MOCK_METHOD(StatusOr<ListHmacKeysResponse>, ListHmacKeys,
126+
(ListHmacKeysRequest const&), (override));
127+
MOCK_METHOD(StatusOr<CreateHmacKeyResponse>, CreateHmacKey,
128+
(CreateHmacKeyRequest const&), (override));
129+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteHmacKey,
130+
(DeleteHmacKeyRequest const&), (override));
131+
MOCK_METHOD(StatusOr<HmacKeyMetadata>, GetHmacKey, (GetHmacKeyRequest const&),
132+
(override));
133+
MOCK_METHOD(StatusOr<HmacKeyMetadata>, UpdateHmacKey,
134+
(UpdateHmacKeyRequest const&), (override));
135+
MOCK_METHOD(StatusOr<SignBlobResponse>, SignBlob, (SignBlobRequest const&),
136+
(override));
137+
MOCK_METHOD(StatusOr<ListNotificationsResponse>, ListNotifications,
138+
(ListNotificationsRequest const&), (override));
139+
MOCK_METHOD(StatusOr<NotificationMetadata>, CreateNotification,
140+
(CreateNotificationRequest const&), (override));
141+
MOCK_METHOD(StatusOr<NotificationMetadata>, GetNotification,
142+
(GetNotificationRequest const&), (override));
143+
MOCK_METHOD(StatusOr<EmptyResponse>, DeleteNotification,
144+
(DeleteNotificationRequest const&), (override));
145+
};
146+
147+
TEST(StorageConnectionTest, UploadFileSimpleUnimplemented) {
148+
TestStorageConnection connection;
149+
InsertObjectMediaRequest request;
150+
auto response = connection.UploadFileSimple("test-file.txt", 1234, request);
151+
EXPECT_THAT(response, StatusIs(StatusCode::kUnimplemented));
152+
}
153+
154+
TEST(StorageConnectionTest, UploadFileResumableUnimplemented) {
155+
TestStorageConnection connection;
156+
ResumableUploadRequest request;
157+
auto response = connection.UploadFileResumable("test-file.txt", request);
158+
EXPECT_THAT(response, StatusIs(StatusCode::kUnimplemented));
159+
}
160+
161+
} // namespace
162+
} // namespace internal
163+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
164+
} // namespace storage
165+
} // namespace cloud
166+
} // namespace google

google/cloud/storage/storage_client_unit_tests.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ storage_client_unit_tests = [
5353
"internal/connection_impl_bucket_acl_test.cc",
5454
"internal/connection_impl_bucket_test.cc",
5555
"internal/connection_impl_default_object_acl_test.cc",
56+
"internal/connection_impl_file_upload_test.cc",
5657
"internal/connection_impl_notifications_test.cc",
5758
"internal/connection_impl_object_acl_test.cc",
5859
"internal/connection_impl_object_copy_test.cc",
@@ -90,6 +91,7 @@ storage_client_unit_tests = [
9091
"internal/service_account_requests_test.cc",
9192
"internal/sign_blob_requests_test.cc",
9293
"internal/signed_url_requests_test.cc",
94+
"internal/storage_connection_test.cc",
9395
"internal/tracing_connection_test.cc",
9496
"internal/tracing_object_read_source_test.cc",
9597
"internal/tuple_filter_test.cc",

0 commit comments

Comments
 (0)