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/spanner/row.h"
16 #include "google/cloud/testing_util/assert_ok.h"
17 #include <gmock/gmock.h>
18 #include <tuple>
19 #include <utility>
20 
21 namespace google {
22 namespace cloud {
23 namespace spanner {
24 inline namespace SPANNER_CLIENT_NS {
25 namespace {
26 
27 using ::testing::HasSubstr;
28 
29 // Given a `vector<StatusOr<Row>>` creates a 'Row::Source' object. This is
30 // helpeful for unit testing and letting the test inject a non-OK Status.
MakeRowStreamIteratorSource(std::vector<StatusOr<Row>> const & rows)31 RowStreamIterator::Source MakeRowStreamIteratorSource(
32     std::vector<StatusOr<Row>> const& rows) {
33   std::size_t index = 0;
34   return [=]() mutable -> StatusOr<Row> {
35     if (index == rows.size()) return Row{};
36     return rows[index++];
37   };
38 }
39 
40 // Given a `vector<Row>` creates a 'Row::Source' object.
MakeRowStreamIteratorSource(std::vector<Row> const & rows={})41 RowStreamIterator::Source MakeRowStreamIteratorSource(
42     std::vector<Row> const& rows = {}) {
43   return MakeRowStreamIteratorSource(
44       std::vector<StatusOr<Row>>(rows.begin(), rows.end()));
45 }
46 
47 class RowRange {
48  public:
RowRange(RowStreamIterator::Source s)49   explicit RowRange(RowStreamIterator::Source s) : s_(std::move(s)) {}
begin()50   RowStreamIterator begin() { return RowStreamIterator(s_); }
51   // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
end()52   RowStreamIterator end() { return RowStreamIterator(); }
53 
54  private:
55   RowStreamIterator::Source s_;
56 };
57 
TEST(Row,DefaultConstruct)58 TEST(Row, DefaultConstruct) {
59   Row row;
60   EXPECT_EQ(0, row.size());
61 }
62 
TEST(Row,ValueSemantics)63 TEST(Row, ValueSemantics) {
64   Row row = MakeTestRow(1, "blah", true);
65 
66   Row copy = row;
67   EXPECT_EQ(copy, row);
68 
69   copy = row;
70   EXPECT_EQ(copy, row);
71 
72   Row move = std::move(row);
73   EXPECT_EQ(move, copy);
74 
75   row = copy;
76   move = std::move(row);
77   EXPECT_EQ(move, copy);
78 }
79 
TEST(Row,BasicAccessors)80 TEST(Row, BasicAccessors) {
81   auto values = std::vector<Value>{Value(1), Value("blah"), Value(true)};
82   auto columns = std::vector<std::string>{"a", "b", "c"};
83   Row row = MakeTestRow({
84       {columns[0], values[0]},  //
85       {columns[1], values[1]},  //
86       {columns[2], values[2]}   //
87   });
88 
89   EXPECT_EQ(3, row.size());
90   EXPECT_EQ(values, row.values());
91   EXPECT_EQ(columns, row.columns());
92   EXPECT_EQ(values, std::move(row).values());
93 }
94 
TEST(Row,GetByPosition)95 TEST(Row, GetByPosition) {
96   Row row = MakeTestRow(1, "blah", true);
97 
98   EXPECT_STATUS_OK(row.get(0));
99   EXPECT_STATUS_OK(row.get(1));
100   EXPECT_STATUS_OK(row.get(2));
101   EXPECT_FALSE(row.get(3).ok());
102 
103   EXPECT_EQ(Value(1), *row.get(0));
104   EXPECT_EQ(Value("blah"), *row.get(1));
105   EXPECT_EQ(Value(true), *row.get(2));
106 }
107 
TEST(Row,GetByColumnName)108 TEST(Row, GetByColumnName) {
109   Row row = MakeTestRow({
110       {"a", Value(1)},       //
111       {"b", Value("blah")},  //
112       {"c", Value(true)}     //
113   });
114 
115   EXPECT_STATUS_OK(row.get("a"));
116   EXPECT_STATUS_OK(row.get("b"));
117   EXPECT_STATUS_OK(row.get("c"));
118   EXPECT_FALSE(row.get("not a column name").ok());
119 
120   EXPECT_EQ(Value(1), *row.get("a"));
121   EXPECT_EQ(Value("blah"), *row.get("b"));
122   EXPECT_EQ(Value(true), *row.get("c"));
123 }
124 
TEST(Row,TemplatedGetByPosition)125 TEST(Row, TemplatedGetByPosition) {
126   Row row = MakeTestRow(1, "blah", true);
127 
128   EXPECT_STATUS_OK(row.get<std::int64_t>(0));
129   EXPECT_STATUS_OK(row.get<std::string>(1));
130   EXPECT_STATUS_OK(row.get<bool>(2));
131 
132   // Ensures that the wrong type specification results in a failure.
133   EXPECT_FALSE(row.get<bool>(0).ok());
134   EXPECT_FALSE(row.get<std::int64_t>(1).ok());
135   EXPECT_FALSE(row.get<std::string>(2).ok());
136   EXPECT_FALSE(row.get<std::int64_t>(3).ok());
137 
138   EXPECT_EQ(1, *row.get<std::int64_t>(0));
139   EXPECT_EQ("blah", *row.get<std::string>(1));
140   EXPECT_EQ(true, *row.get<bool>(2));
141 }
142 
TEST(Row,TemplatedGetByColumnName)143 TEST(Row, TemplatedGetByColumnName) {
144   Row row = MakeTestRow({
145       {"a", Value(1)},       //
146       {"b", Value("blah")},  //
147       {"c", Value(true)}     //
148   });
149 
150   EXPECT_STATUS_OK(row.get<std::int64_t>("a"));
151   EXPECT_STATUS_OK(row.get<std::string>("b"));
152   EXPECT_STATUS_OK(row.get<bool>("c"));
153 
154   // Ensures that the wrong type specification results in a failure.
155   EXPECT_FALSE(row.get<bool>("a").ok());
156   EXPECT_FALSE(row.get<std::int64_t>("b").ok());
157   EXPECT_FALSE(row.get<std::string>("c").ok());
158   EXPECT_FALSE(row.get<std::string>("column does not exist").ok());
159 
160   EXPECT_EQ(1, *row.get<std::int64_t>("a"));
161   EXPECT_EQ("blah", *row.get<std::string>("b"));
162   EXPECT_EQ(true, *row.get<bool>("c"));
163 }
164 
TEST(Row,TemplatedGetAsTuple)165 TEST(Row, TemplatedGetAsTuple) {
166   Row row = MakeTestRow(1, "blah", true);
167 
168   using RowType = std::tuple<std::int64_t, std::string, bool>;
169   EXPECT_STATUS_OK(row.get<RowType>());
170   EXPECT_EQ(std::make_tuple(1, "blah", true), *row.get<RowType>());
171 
172   using TooFewTypes = std::tuple<std::int64_t, std::string>;
173   EXPECT_FALSE(row.get<TooFewTypes>().ok());
174   Row copy = row;
175   EXPECT_FALSE(std::move(copy).get<TooFewTypes>().ok());
176 
177   using TooManyTypes = std::tuple<std::int64_t, std::string, bool, bool>;
178   EXPECT_FALSE(row.get<TooManyTypes>().ok());
179   copy = row;
180   EXPECT_FALSE(std::move(copy).get<TooManyTypes>().ok());
181 
182   using WrongType = std::tuple<std::int64_t, std::string, std::int64_t>;
183   EXPECT_FALSE(row.get<WrongType>().ok());
184   copy = row;
185   EXPECT_FALSE(std::move(copy).get<WrongType>().ok());
186 
187   EXPECT_EQ(std::make_tuple(1, "blah", true), *std::move(row).get<RowType>());
188 }
189 
TEST(MakeTestRow,ExplicitColumNames)190 TEST(MakeTestRow, ExplicitColumNames) {
191   auto row = MakeTestRow({{"a", Value(42)}, {"b", Value(52)}});
192   EXPECT_EQ(Value(42), *row.get("a"));
193   EXPECT_EQ(Value(52), *row.get("b"));
194 }
195 
TEST(MakeTestRow,ImplicitColumNames)196 TEST(MakeTestRow, ImplicitColumNames) {
197   auto row = MakeTestRow(42, 52);
198   EXPECT_EQ(Value(42), *row.get("0"));
199   EXPECT_EQ(Value(52), *row.get("1"));
200 }
201 
TEST(RowStreamIterator,Basics)202 TEST(RowStreamIterator, Basics) {
203   RowStreamIterator end;
204   EXPECT_EQ(end, end);
205 
206   std::vector<Row> rows;
207   rows.emplace_back(MakeTestRow(1, "foo", true));
208   rows.emplace_back(MakeTestRow(2, "bar", true));
209   rows.emplace_back(MakeTestRow(3, "baz", true));
210 
211   auto it = RowStreamIterator(MakeRowStreamIteratorSource(rows));
212   EXPECT_EQ(it, it);
213   EXPECT_NE(it, end);
214   EXPECT_STATUS_OK(*it);
215   EXPECT_EQ(rows[0], **it);
216 
217   ++it;
218   EXPECT_EQ(it, it);
219   EXPECT_NE(it, end);
220   EXPECT_STATUS_OK(*it);
221   EXPECT_EQ(rows[1], **it);
222 
223   it++;
224   EXPECT_EQ(it, it);
225   EXPECT_NE(it, end);
226   EXPECT_STATUS_OK(*it);
227   EXPECT_EQ(rows[2], **it);
228 
229   // Tests const op*() and op->()
230   auto const copy = it;
231   EXPECT_EQ(copy, it);
232   EXPECT_NE(copy, end);
233   EXPECT_STATUS_OK(*copy);
234   EXPECT_STATUS_OK(copy->status());
235 
236   ++it;
237   EXPECT_EQ(it, it);
238   EXPECT_EQ(it, end);
239 }
240 
TEST(RowStreamIterator,Empty)241 TEST(RowStreamIterator, Empty) {
242   RowStreamIterator end;
243   auto it = RowStreamIterator(MakeRowStreamIteratorSource());
244   EXPECT_EQ(it, end);
245 }
246 
TEST(RowStreamIterator,OneRow)247 TEST(RowStreamIterator, OneRow) {
248   RowStreamIterator end;
249   std::vector<Row> rows;
250   rows.emplace_back(MakeTestRow(1, "foo", true));
251   auto it = RowStreamIterator(MakeRowStreamIteratorSource(rows));
252   EXPECT_NE(it, end);
253   EXPECT_STATUS_OK(*it);
254   EXPECT_EQ(rows[0], **it);
255 
256   ++it;
257   EXPECT_EQ(it, it);
258   EXPECT_EQ(it, end);
259 }
260 
TEST(RowStreamIterator,IterationError)261 TEST(RowStreamIterator, IterationError) {
262   RowStreamIterator end;
263   std::vector<StatusOr<Row>> rows;
264   rows.emplace_back(MakeTestRow(1, "foo", true));
265   rows.emplace_back(Status(StatusCode::kUnknown, "some error"));
266   rows.emplace_back(MakeTestRow(2, "bar", true));
267 
268   auto it = RowStreamIterator(MakeRowStreamIteratorSource(rows));
269   EXPECT_NE(it, end);
270   EXPECT_STATUS_OK(*it);
271   EXPECT_EQ(rows[0], *it);
272 
273   ++it;
274   EXPECT_EQ(it, it);
275   EXPECT_NE(it, end);
276   EXPECT_FALSE(*it);
277   EXPECT_EQ(StatusCode::kUnknown, it->status().code());
278   EXPECT_EQ("some error", it->status().message());
279 
280   ++it;
281   EXPECT_EQ(it, it);
282   EXPECT_EQ(it, end);
283 }
284 
TEST(RowStreamIterator,ForLoop)285 TEST(RowStreamIterator, ForLoop) {
286   std::vector<Row> rows;
287   rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
288   rows.emplace_back(MakeTestRow({{"num", Value(3)}}));
289   rows.emplace_back(MakeTestRow({{"num", Value(5)}}));
290 
291   auto source = MakeRowStreamIteratorSource(rows);
292   std::int64_t product = 1;
293   for (RowStreamIterator it(source), end; it != end; ++it) {
294     EXPECT_STATUS_OK(*it);
295     auto num = (*it)->get<std::int64_t>("num");
296     EXPECT_STATUS_OK(num);
297     product *= *num;
298   }
299   EXPECT_EQ(product, 30);
300 }
301 
TEST(RowStreamIterator,RangeForLoop)302 TEST(RowStreamIterator, RangeForLoop) {
303   std::vector<Row> rows;
304   rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
305   rows.emplace_back(MakeTestRow({{"num", Value(3)}}));
306   rows.emplace_back(MakeTestRow({{"num", Value(5)}}));
307 
308   RowRange range(MakeRowStreamIteratorSource(rows));
309   std::int64_t product = 1;
310   for (auto const& row : range) {
311     EXPECT_STATUS_OK(row);
312     auto num = row->get<std::int64_t>("num");
313     EXPECT_STATUS_OK(num);
314     product *= *num;
315   }
316   EXPECT_EQ(product, 30);
317 }
318 
TEST(TupleStreamIterator,Basics)319 TEST(TupleStreamIterator, Basics) {
320   std::vector<Row> rows;
321   rows.emplace_back(MakeTestRow(1, "foo", true));
322   rows.emplace_back(MakeTestRow(2, "bar", true));
323   rows.emplace_back(MakeTestRow(3, "baz", true));
324 
325   using RowType = std::tuple<std::int64_t, std::string, bool>;
326   using TupleIterator = TupleStreamIterator<RowType>;
327 
328   auto end = TupleIterator();
329   EXPECT_EQ(end, end);
330 
331   auto it = TupleIterator(RowStreamIterator(MakeRowStreamIteratorSource(rows)),
332                           RowStreamIterator());
333 
334   EXPECT_EQ(it, it);
335   EXPECT_NE(it, end);
336   EXPECT_STATUS_OK(*it);
337   EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
338 
339   ++it;
340   EXPECT_EQ(it, it);
341   EXPECT_NE(it, end);
342   EXPECT_STATUS_OK(*it);
343   EXPECT_EQ(std::make_tuple(2, "bar", true), **it);
344 
345   ++it;
346   EXPECT_EQ(it, it);
347   EXPECT_NE(it, end);
348   EXPECT_STATUS_OK(*it);
349   EXPECT_EQ(std::make_tuple(3, "baz", true), **it);
350 
351   // Tests const op*() and op->()
352   auto const copy = it;
353   EXPECT_EQ(copy, it);
354   EXPECT_NE(copy, end);
355   EXPECT_STATUS_OK(*copy);
356   EXPECT_STATUS_OK(copy->status());
357 
358   ++it;
359   EXPECT_EQ(it, it);
360   EXPECT_EQ(it, end);
361 }
362 
TEST(TupleStreamIterator,Empty)363 TEST(TupleStreamIterator, Empty) {
364   using RowType = std::tuple<std::int64_t, std::string, bool>;
365   using TupleIterator = TupleStreamIterator<RowType>;
366 
367   auto end = TupleIterator();
368   EXPECT_EQ(end, end);
369 
370   auto it = TupleIterator(RowStreamIterator(MakeRowStreamIteratorSource()),
371                           RowStreamIterator());
372   EXPECT_EQ(it, end);
373 }
374 
TEST(TupleStreamIterator,Error)375 TEST(TupleStreamIterator, Error) {
376   std::vector<Row> rows;
377   rows.emplace_back(MakeTestRow(1, "foo", true));
378   rows.emplace_back(MakeTestRow(2, "bar", "should be a bool"));
379   rows.emplace_back(MakeTestRow(3, "baz", true));
380 
381   using RowType = std::tuple<std::int64_t, std::string, bool>;
382   using TupleIterator = TupleStreamIterator<RowType>;
383 
384   auto end = TupleIterator();
385   EXPECT_EQ(end, end);
386 
387   auto it = TupleIterator(RowStreamIterator(MakeRowStreamIteratorSource(rows)),
388                           RowStreamIterator());
389 
390   EXPECT_EQ(it, it);
391   EXPECT_NE(it, end);
392   EXPECT_STATUS_OK(*it);
393   EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
394 
395   ++it;
396   EXPECT_EQ(it, it);
397   EXPECT_NE(it, end);
398   EXPECT_FALSE(it->ok());  // Error parsing the 2nd element
399 
400   ++it;  // Due to the previous error, jumps straight to "end"
401   EXPECT_EQ(it, it);
402   EXPECT_EQ(it, end);
403 }
404 
TEST(TupleStream,Basics)405 TEST(TupleStream, Basics) {
406   std::vector<Row> rows;
407   rows.emplace_back(MakeTestRow(1, "foo", true));
408   rows.emplace_back(MakeTestRow(2, "bar", true));
409   rows.emplace_back(MakeTestRow(3, "baz", true));
410 
411   using RowType = std::tuple<std::int64_t, std::string, bool>;
412   RowRange range(MakeRowStreamIteratorSource(rows));
413   auto parser = StreamOf<RowType>(range);
414   auto it = parser.begin();
415   auto end = parser.end();
416   EXPECT_EQ(end, end);
417 
418   EXPECT_EQ(it, it);
419   EXPECT_NE(it, end);
420   EXPECT_STATUS_OK(*it);
421   EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
422 
423   ++it;
424   EXPECT_EQ(it, it);
425   EXPECT_NE(it, end);
426   EXPECT_STATUS_OK(*it);
427   EXPECT_EQ(std::make_tuple(2, "bar", true), **it);
428 
429   ++it;
430   EXPECT_EQ(it, it);
431   EXPECT_NE(it, end);
432   EXPECT_STATUS_OK(*it);
433   EXPECT_EQ(std::make_tuple(3, "baz", true), **it);
434 
435   ++it;
436   EXPECT_EQ(it, it);
437   EXPECT_EQ(it, end);
438 }
439 
TEST(TupleStream,RangeForLoop)440 TEST(TupleStream, RangeForLoop) {
441   std::vector<Row> rows;
442   rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
443   rows.emplace_back(MakeTestRow({{"num", Value(3)}}));
444   rows.emplace_back(MakeTestRow({{"num", Value(5)}}));
445   using RowType = std::tuple<std::int64_t>;
446 
447   RowRange range(MakeRowStreamIteratorSource(rows));
448   std::int64_t product = 1;
449   for (auto const& row : StreamOf<RowType>(range)) {
450     EXPECT_STATUS_OK(row);
451     product *= std::get<0>(*row);
452   }
453   EXPECT_EQ(product, 30);
454 }
455 
TEST(TupleStream,IterationError)456 TEST(TupleStream, IterationError) {
457   std::vector<StatusOr<Row>> rows;
458   rows.emplace_back(MakeTestRow(1, "foo", true));
459   rows.emplace_back(Status(StatusCode::kUnknown, "some error"));
460   rows.emplace_back(MakeTestRow(2, "bar", true));
461 
462   RowRange range(MakeRowStreamIteratorSource(rows));
463 
464   using RowType = std::tuple<std::int64_t, std::string, bool>;
465   auto stream = StreamOf<RowType>(range);
466 
467   auto end = stream.end();
468   auto it = stream.begin();
469   EXPECT_NE(it, end);
470   EXPECT_STATUS_OK(*it);
471   EXPECT_EQ(std::make_tuple(1, "foo", true), **it);
472 
473   ++it;
474   EXPECT_EQ(it, it);
475   EXPECT_NE(it, end);
476   EXPECT_FALSE(*it);
477   EXPECT_EQ(StatusCode::kUnknown, it->status().code());
478   EXPECT_EQ("some error", it->status().message());
479 
480   ++it;
481   EXPECT_EQ(it, it);
482   EXPECT_EQ(it, end);
483 }
484 
TEST(GetSingularRow,BasicEmpty)485 TEST(GetSingularRow, BasicEmpty) {
486   std::vector<Row> rows;
487   RowRange range(MakeRowStreamIteratorSource(rows));
488   auto row = GetSingularRow(range);
489   EXPECT_FALSE(row.ok());
490   EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
491   EXPECT_THAT(row.status().message(), HasSubstr("no rows"));
492 }
493 
TEST(GetSingularRow,TupleStreamEmpty)494 TEST(GetSingularRow, TupleStreamEmpty) {
495   std::vector<Row> rows;
496   RowRange range(MakeRowStreamIteratorSource(rows));
497   auto row = GetSingularRow(StreamOf<std::tuple<std::int64_t>>(range));
498   EXPECT_FALSE(row.ok());
499   EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
500   EXPECT_THAT(row.status().message(), HasSubstr("no rows"));
501 }
502 
TEST(GetSingularRow,BasicSingleRow)503 TEST(GetSingularRow, BasicSingleRow) {
504   std::vector<Row> rows;
505   rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
506 
507   RowRange range(MakeRowStreamIteratorSource(rows));
508   auto row = GetSingularRow(range);
509   EXPECT_STATUS_OK(row);
510   EXPECT_EQ(1, *row->get<std::int64_t>(0));
511 }
512 
TEST(GetSingularRow,TupleStreamSingleRow)513 TEST(GetSingularRow, TupleStreamSingleRow) {
514   std::vector<Row> rows;
515   rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
516 
517   auto row_range = RowRange(MakeRowStreamIteratorSource(rows));
518   auto tup_range = StreamOf<std::tuple<std::int64_t>>(row_range);
519 
520   auto row = GetSingularRow(tup_range);
521   EXPECT_STATUS_OK(row);
522   EXPECT_EQ(1, std::get<0>(*row));
523 }
524 
TEST(GetSingularRow,BasicTooManyRows)525 TEST(GetSingularRow, BasicTooManyRows) {
526   std::vector<Row> rows;
527   rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
528   rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
529 
530   RowRange range(MakeRowStreamIteratorSource(rows));
531   auto row = GetSingularRow(range);
532   EXPECT_FALSE(row.ok());
533   EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
534   EXPECT_THAT(row.status().message(), HasSubstr("too many rows"));
535 }
536 
TEST(GetSingularRow,TupleStreamTooManyRows)537 TEST(GetSingularRow, TupleStreamTooManyRows) {
538   std::vector<Row> rows;
539   rows.emplace_back(MakeTestRow({{"num", Value(1)}}));
540   rows.emplace_back(MakeTestRow({{"num", Value(2)}}));
541 
542   RowRange range(MakeRowStreamIteratorSource(rows));
543   auto row = GetSingularRow(StreamOf<std::tuple<std::int64_t>>(range));
544   EXPECT_FALSE(row.ok());
545   EXPECT_EQ(row.status().code(), StatusCode::kInvalidArgument);
546   EXPECT_THAT(row.status().message(), HasSubstr("too many rows"));
547 }
548 
549 }  // namespace
550 }  // namespace SPANNER_CLIENT_NS
551 }  // namespace spanner
552 }  // namespace cloud
553 }  // namespace google
554