Skip to content

Adding system tests for HappyBase Table.put() and delete(). #1608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 16, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions system_tests/bigtable_happybase.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,197 @@ def test_scan_timestamp(self):
])


class TestTable_put(BaseTableTest):

def test_put(self):
value1 = 'value1'
value2 = 'value2'
row1_data = {COL1: value1, COL2: value2}

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)
Config.TABLE.put(ROW_KEY1, row1_data)

row1 = Config.TABLE.row(ROW_KEY1)
self.assertEqual(row1, row1_data)

# Check again, but this time with timestamps.
row1 = Config.TABLE.row(ROW_KEY1, include_timestamp=True)
timestamp1 = row1[COL1][1]
timestamp2 = row1[COL2][1]
self.assertEqual(timestamp1, timestamp2)

row1_data_with_timestamps = {COL1: (value1, timestamp1),
COL2: (value2, timestamp2)}
self.assertEqual(row1, row1_data_with_timestamps)

def test_put_with_timestamp(self):
value1 = 'value1'
value2 = 'value2'
row1_data = {COL1: value1, COL2: value2}
ts = NOW_MILLIS

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)
Config.TABLE.put(ROW_KEY1, row1_data, timestamp=ts)

# Check again, but this time with timestamps.
row1 = Config.TABLE.row(ROW_KEY1, include_timestamp=True)
row1_data_with_timestamps = {COL1: (value1, ts),
COL2: (value2, ts)}
self.assertEqual(row1, row1_data_with_timestamps)


class TestTable_delete(BaseTableTest):

def test_delete(self):
table = Config.TABLE
value1 = 'value1'
value2 = 'value2'
row1_data = {COL1: value1, COL2: value2}

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

table.put(ROW_KEY1, row1_data)

row1 = table.row(ROW_KEY1)
self.assertEqual(row1, row1_data)

table.delete(ROW_KEY1)
row1_after = table.row(ROW_KEY1)
self.assertEqual(row1_after, {})

def test_delete_with_columns(self):
table = Config.TABLE
value1 = 'value1'
value2 = 'value2'
row1_data = {COL1: value1, COL2: value2}

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)
table.put(ROW_KEY1, row1_data)

row1 = table.row(ROW_KEY1)
self.assertEqual(row1, row1_data)

table.delete(ROW_KEY1, columns=[COL1])
row1_after = table.row(ROW_KEY1)
self.assertEqual(row1_after, {COL2: value2})

def test_delete_with_column_family(self):
table = Config.TABLE
value1 = 'value1'
value2 = 'value2'
value3 = 'value3'
row1_data = {COL1: value1, COL2: value2, COL4: value3}

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)
table.put(ROW_KEY1, row1_data)

row1 = table.row(ROW_KEY1)
self.assertEqual(row1, row1_data)

table.delete(ROW_KEY1, columns=[COL_FAM1])
row1_after = table.row(ROW_KEY1)
self.assertEqual(row1_after, {COL4: value3})

def test_delete_with_columns_family_overlap(self):
table = Config.TABLE
value1 = 'value1'
value2 = 'value2'
row1_data = {COL1: value1, COL2: value2}

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)

# First go-around, use [COL_FAM1, COL1]
table.put(ROW_KEY1, row1_data)
row1 = table.row(ROW_KEY1)
self.assertEqual(row1, row1_data)

table.delete(ROW_KEY1, columns=[COL_FAM1, COL1])
row1_after = table.row(ROW_KEY1)
self.assertEqual(row1_after, {})

# Second go-around, use [COL1, COL_FAM1]
table.put(ROW_KEY1, row1_data)
row1 = table.row(ROW_KEY1)
self.assertEqual(row1, row1_data)

table.delete(ROW_KEY1, columns=[COL1, COL_FAM1])
row1_after = table.row(ROW_KEY1)
self.assertEqual(row1_after, {})

def test_delete_with_timestamp(self):
table = Config.TABLE
value1 = 'value1'
value2 = 'value2'

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)
table.put(ROW_KEY1, {COL1: value1})
table.put(ROW_KEY1, {COL2: value2})

row1 = table.row(ROW_KEY1, include_timestamp=True)
ts1 = row1[COL1][1]
ts2 = row1[COL2][1]

self.assertTrue(ts1 < ts2)

# NOTE: The Cloud Bigtable "Mutation.DeleteFromRow" mutation does
# not support timestamps. Even attempting to send one
# conditionally(via CheckAndMutateRowRequest) deletes the
# entire row.
# NOTE: Cloud Bigtable deletes **ALSO** use an inclusive timestamp
# at the endpoint, but only because we fake this when
# creating Batch._delete_range.

This comment was marked as spam.

This comment was marked as spam.

table.delete(ROW_KEY1, columns=[COL1, COL2], timestamp=ts1 - 1)
row1_after_early_delete = table.row(ROW_KEY1, include_timestamp=True)
self.assertEqual(row1_after_early_delete, row1)

# NOTE: Cloud Bigtable deletes **ALSO** use an inclusive timestamp
# at the endpoint, but only because we fake this when
# creating Batch._delete_range.
table.delete(ROW_KEY1, columns=[COL1, COL2], timestamp=ts1)
row1_after_incl_delete = table.row(ROW_KEY1, include_timestamp=True)
self.assertEqual(row1_after_incl_delete, {COL2: (value2, ts2)})

def test_delete_with_columns_and_timestamp(self):
table = Config.TABLE
value1 = 'value1'
value2 = 'value2'

# Need to clean-up row1 after.
self.rows_to_delete.append(ROW_KEY1)
table.put(ROW_KEY1, {COL1: value1})
table.put(ROW_KEY1, {COL2: value2})

row1 = table.row(ROW_KEY1, include_timestamp=True)
ts1 = row1[COL1][1]
ts2 = row1[COL2][1]

# Delete with conditions that have no matches.
table.delete(ROW_KEY1, timestamp=ts1, columns=[COL2])
row1_after_delete = table.row(ROW_KEY1, include_timestamp=True)
# NOTE: COL2 is still present since it occurs after ts1 and
# COL1 is still present since it is not in `columns`.
self.assertEqual(row1_after_delete, row1)

# Delete with conditions that have no matches.
# NOTE: Cloud Bigtable can't use a timestamp with column families
# since "Mutation.DeleteFromFamily" does not include a
# timestamp range.
# NOTE: Cloud Bigtable deletes **ALSO** use an inclusive timestamp
# at the endpoint, but only because we fake this when
# creating Batch._delete_range.
table.delete(ROW_KEY1, timestamp=ts1, columns=[COL1, COL2])
row1_delete_fam = table.row(ROW_KEY1, include_timestamp=True)
# NOTE: COL2 is still present since it occurs after ts1 and
# COL1 is still present since it is not in `columns`.
self.assertEqual(row1_delete_fam, {COL2: (value2, ts2)})


class TestTableCounterMethods(BaseTableTest):

def test_counter_get(self):
Expand Down