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