1 // Copyright 2019 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 // http://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/resumable_upload_session.h"
16 #include <gmock/gmock.h>
17
18 namespace google {
19 namespace cloud {
20 namespace storage {
21 inline namespace STORAGE_CLIENT_NS {
22 namespace internal {
23 namespace {
24
25 using ::testing::HasSubstr;
26
TEST(ResumableUploadResponseTest,Base)27 TEST(ResumableUploadResponseTest, Base) {
28 auto actual = ResumableUploadResponse::FromHttpResponse(
29 HttpResponse{200,
30 R"""({"name": "test-object-name"})""",
31 {{"ignored-header", "value"},
32 {"location", "location-value"},
33 {"range", "bytes=0-2000"}}})
34 .value();
35 ASSERT_TRUE(actual.payload.has_value());
36 EXPECT_EQ("test-object-name", actual.payload->name());
37 EXPECT_EQ("location-value", actual.upload_session_url);
38 EXPECT_EQ(2000, actual.last_committed_byte);
39 EXPECT_EQ(ResumableUploadResponse::kDone, actual.upload_state);
40
41 std::ostringstream os;
42 os << actual;
43 auto actual_str = os.str();
44 EXPECT_THAT(actual_str, HasSubstr("upload_session_url=location-value"));
45 EXPECT_THAT(actual_str, HasSubstr("last_committed_byte=2000"));
46 EXPECT_THAT(actual_str, HasSubstr("annotations="));
47 }
48
TEST(ResumableUploadResponseTest,NoLocation)49 TEST(ResumableUploadResponseTest, NoLocation) {
50 auto actual = ResumableUploadResponse::FromHttpResponse(
51 HttpResponse{308, {}, {{"range", "bytes=0-2000"}}})
52 .value();
53 EXPECT_FALSE(actual.payload.has_value());
54 EXPECT_EQ("", actual.upload_session_url);
55 EXPECT_EQ(2000, actual.last_committed_byte);
56 EXPECT_EQ("", actual.annotations);
57 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
58 }
59
TEST(ResumableUploadResponseTest,NoRange)60 TEST(ResumableUploadResponseTest, NoRange) {
61 auto actual = ResumableUploadResponse::FromHttpResponse(
62 HttpResponse{201,
63 R"""({"name": "test-object-name"})""",
64 {{"location", "location-value"}}})
65 .value();
66 ASSERT_TRUE(actual.payload.has_value());
67 EXPECT_EQ("test-object-name", actual.payload->name());
68 EXPECT_EQ("location-value", actual.upload_session_url);
69 EXPECT_EQ(0, actual.last_committed_byte);
70 EXPECT_NE("", actual.annotations);
71 EXPECT_EQ(ResumableUploadResponse::kDone, actual.upload_state);
72 }
73
TEST(ResumableUploadResponseTest,MissingBytesInRange)74 TEST(ResumableUploadResponseTest, MissingBytesInRange) {
75 auto actual = ResumableUploadResponse::FromHttpResponse(
76 HttpResponse{308,
77 {},
78 {{"location", "location-value"},
79 {"range", "units=0-2000"}}})
80 .value();
81 EXPECT_FALSE(actual.payload.has_value());
82 EXPECT_EQ("location-value", actual.upload_session_url);
83 EXPECT_EQ(0, actual.last_committed_byte);
84 EXPECT_NE("", actual.annotations);
85 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
86 }
87
TEST(ResumableUploadResponseTest,MissingRangeEnd)88 TEST(ResumableUploadResponseTest, MissingRangeEnd) {
89 auto actual = ResumableUploadResponse::FromHttpResponse(
90 HttpResponse{308, {}, {{"range", "bytes=0-"}}})
91 .value();
92 EXPECT_FALSE(actual.payload.has_value());
93 EXPECT_EQ("", actual.upload_session_url);
94 EXPECT_EQ(0, actual.last_committed_byte);
95 EXPECT_NE("", actual.annotations);
96 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
97 }
98
TEST(ResumableUploadResponseTest,InvalidRangeEnd)99 TEST(ResumableUploadResponseTest, InvalidRangeEnd) {
100 auto actual = ResumableUploadResponse::FromHttpResponse(
101 HttpResponse{308, {}, {{"range", "bytes=0-abcd"}}})
102 .value();
103 EXPECT_FALSE(actual.payload.has_value());
104 EXPECT_EQ("", actual.upload_session_url);
105 EXPECT_EQ(0, actual.last_committed_byte);
106 EXPECT_NE("", actual.annotations);
107 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
108 }
109
TEST(ResumableUploadResponseTest,InvalidRangeBegin)110 TEST(ResumableUploadResponseTest, InvalidRangeBegin) {
111 auto actual = ResumableUploadResponse::FromHttpResponse(
112 HttpResponse{308, {}, {{"range", "bytes=abcd-2000"}}})
113 .value();
114 EXPECT_FALSE(actual.payload.has_value());
115 EXPECT_EQ("", actual.upload_session_url);
116 EXPECT_EQ(0, actual.last_committed_byte);
117 EXPECT_NE("", actual.annotations);
118 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
119 }
120
TEST(ResumableUploadResponseTest,UnexpectedRangeBegin)121 TEST(ResumableUploadResponseTest, UnexpectedRangeBegin) {
122 auto actual = ResumableUploadResponse::FromHttpResponse(
123 HttpResponse{308, {}, {{"range", "bytes=3000-2000"}}})
124 .value();
125 EXPECT_FALSE(actual.payload.has_value());
126 EXPECT_EQ("", actual.upload_session_url);
127 EXPECT_EQ(0, actual.last_committed_byte);
128 EXPECT_NE("", actual.annotations);
129 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
130 }
131
TEST(ResumableUploadResponseTest,NegativeEnd)132 TEST(ResumableUploadResponseTest, NegativeEnd) {
133 auto actual = ResumableUploadResponse::FromHttpResponse(
134 HttpResponse{308, {}, {{"range", "bytes=0--7"}}})
135 .value();
136 EXPECT_FALSE(actual.payload.has_value());
137 EXPECT_EQ("", actual.upload_session_url);
138 EXPECT_EQ(0, actual.last_committed_byte);
139 EXPECT_NE("", actual.annotations);
140 EXPECT_EQ(ResumableUploadResponse::kInProgress, actual.upload_state);
141 }
142
143 } // namespace
144 } // namespace internal
145 } // namespace STORAGE_CLIENT_NS
146 } // namespace storage
147 } // namespace cloud
148 } // namespace google
149