@@ -263,6 +263,16 @@ Status HasRow(std::shared_ptr<google::cloud::bigtable::emulator::Table>& table,
263263// Test that SetCell does the right thing when it receives a zero or
264264// negative timestamp, and that the cell created can be correctly
265265// deleted if rollback occurs.
266+ //
267+ // In particular:
268+ //
269+ // Supplied with a timestamp of -1, it should store the current system time as
270+ // timestamp.
271+ //
272+ // Supplied with a timestamp of 0, it should store it as is.
273+ //
274+ // Supplied with a timestamp < -1, it should return an error and fail the entire
275+ // mutation chain.
266276TEST (TransactonRollback, ZeroOrNegativeTimestampHandling) {
267277 ::google::bigtable::admin::v2::Table schema;
268278 ::google::bigtable::admin::v2::ColumnFamily column_family;
@@ -294,16 +304,11 @@ TEST(TransactonRollback, ZeroOrNegativeTimestampHandling) {
294304 auto column = status_or.value ();
295305 ASSERT_EQ (1 , column.size ());
296306 for (auto const & cell : column) {
297- ASSERT_GT (cell.first .count (), 0 );
307+ ASSERT_EQ (cell.first .count (), 0 );
298308 ASSERT_EQ (data, cell.second );
299309 }
300310
301- // Test that a SetCell mutation with timestamp set to 0 can be
302- // correctly rolled back. In the following, the first mutation
303- // (timestamp 0) should succeed and the next one should fail. The
304- // condition after that should be that the first one (timestamp 0)
305- // should be rolled back so that a row with row_key_2 key should not
306- // exist when the MutateRow request returns.
311+ // Test that a mutation with timestamp 0 can be rolled back.
307312 v.clear ();
308313 v = {{column_family_name, column_qualifier, 0 , data},
309314 {" non_existent_column_family_name_causes_tx_rollbaclk" , column_qualifier,
@@ -312,6 +317,48 @@ TEST(TransactonRollback, ZeroOrNegativeTimestampHandling) {
312317 status = SetCells (table, table_name, row_key_2, v);
313318 ASSERT_NE (true , status.ok ());
314319 ASSERT_FALSE (HasRow (table, column_family_name, row_key_2).ok ());
320+
321+ // Test that a mutation with timestamp 0 succeeds and stores 0 as
322+ // the timestamp.
323+ v.clear ();
324+ v = {
325+ {column_family_name, column_qualifier, 0 , data},
326+ };
327+ auto const * const row_key_3 = " 2" ;
328+ status = SetCells (table, table_name, row_key_3, v);
329+ ASSERT_STATUS_OK (status);
330+ ASSERT_STATUS_OK (HasCell (table, v[0 ].column_family_name , row_key_3,
331+ v[0 ].column_qualifier , 0 , v[0 ].data ));
332+
333+ // Test that a mutation with timestamp < -1 fails
334+ v.clear ();
335+ v = {
336+ {column_family_name, column_qualifier, -2 , data},
337+ };
338+ auto const * const row_key_4 = " 3" ;
339+ status = SetCells (table, table_name, row_key_4, v);
340+ ASSERT_FALSE (status.ok ());
341+
342+ // Test that a mutation with timestamp -1 suceeds and stores the
343+ // system time.
344+ v.clear ();
345+ v = {
346+ {column_family_name, column_qualifier, -1 , data},
347+ };
348+ auto const * const row_key_5 = " 4" ;
349+ auto system_time_ms_before = std::chrono::duration_cast<std::chrono::milliseconds>(
350+ std::chrono::system_clock::now ().time_since_epoch ());
351+ status = SetCells (table, table_name, row_key_5, v);
352+ ASSERT_STATUS_OK (status);
353+ auto column_or = GetColumn (
354+ table, v[0 ].column_family_name , row_key_5, v[0 ].column_qualifier );
355+ ASSERT_STATUS_OK (column_or.status ());
356+ auto col = column_or.value ();
357+ ASSERT_EQ (col.size (), 1 );
358+ auto cell_it = col.begin ();
359+ ASSERT_NE (cell_it, col.end ());
360+ ASSERT_EQ (cell_it->second , v[0 ].data );
361+ ASSERT_GE (cell_it->first , system_time_ms_before);
315362}
316363
317364// Does the SetCell mutation work to set a cell to a specific value?
0 commit comments