Skip to content

Commit

Permalink
Adding system tests for Table Admin API.
Browse files Browse the repository at this point in the history
We don't explicitly test for

- Table.delete <--> DeleteTable
- Table.list_column_families <--> GetTable

since they are implicitly tested in the other test cases.

We also don't test for

- Table.rename <--> RenameTable
- ColumnFamily.update <--> UpdateColumnFamily

because both of those methods return with the error

> BigtableTableService.{method_name} is not yet implemented

In addition, we noticed that the GC rules in a column family
are not returned when using GetTable.

Also noticed ColumnFamily.__eq__ didn't use gc_rule and that
Table.rename didn't change the locally stored table_id after
success.
  • Loading branch information
dhermes committed Jul 29, 2015
1 parent d252e9c commit 38f9ff7
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
10 changes: 10 additions & 0 deletions gcloud_bigtable/column_family.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ def __eq__(self, other):
if not isinstance(other, self.__class__):
return False
return (other.column_family_id == self.column_family_id and
other.gc_rule == self.gc_rule and
other.table == self.table)

def __ne__(self, other):
Expand Down Expand Up @@ -257,6 +258,15 @@ def create(self, timeout_seconds=None):
def update(self, timeout_seconds=None):
"""Update this column family.
.. note::
The Bigtable Table Admin API currently returns
``BigtableTableService.UpdateColumnFamily is not yet implemented``
when this method is used. It's unclear when this method will
actually be supported by the API.
:type timeout_seconds: integer
:param timeout_seconds: Number of seconds for request time-out.
If not passed, defaults to value set on
Expand Down
11 changes: 11 additions & 0 deletions gcloud_bigtable/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ def rename(self, new_table_id, timeout_seconds=None):
This cannot be used to move tables between clusters,
zones, or projects.
.. note::
The Bigtable Table Admin API currently returns
``BigtableTableService.RenameTable is not yet implemented``
when this method is used. It's unclear when this method will
actually be supported by the API.
:type new_table_id: string
:param new_table_id: The new name table ID.
Expand All @@ -201,6 +210,8 @@ def rename(self, new_table_id, timeout_seconds=None):
# We expect a `._generated.empty_pb2.Empty`
response.result()

self.table_id = new_table_id

def delete(self, timeout_seconds=None):
"""Delete this table.
Expand Down
3 changes: 3 additions & 0 deletions gcloud_bigtable/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,20 @@ def test_rename(self):
# We must create the cluster with the client passed in
# and then the table with that cluster.
TEST_CASE = self
TABLE_CREATED = []
timeout_seconds = 97

def result_method(client):
cluster = client.cluster(ZONE, CLUSTER_ID)
table = TEST_CASE._makeOne(TABLE_ID, cluster)
TABLE_CREATED.append(table)
return table.rename(new_table_id, timeout_seconds=timeout_seconds)

self._grpc_client_test_helper('RenameTable', result_method,
request_pb, response_pb, expected_result,
PROJECT_ID,
timeout_seconds=timeout_seconds)
self.assertEqual(TABLE_CREATED[0].table_id, new_table_id)

def test_delete(self):
from gcloud_bigtable._generated import (
Expand Down
87 changes: 87 additions & 0 deletions system_tests/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
TEST_ZONE = 'us-central1-c'
TEST_CLUSTER_ID = 'gcloud-python'
TEST_SERVE_NODES = 3
TEST_TABLE_ID = 'gcloud-python-test-table'
EXPECTED_ZONES = (
'asia-east1-b',
'europe-west1-c',
Expand Down Expand Up @@ -134,3 +135,89 @@ def test_update(self):
# We want to make sure the operation completes.
time.sleep(2)
self.assertTrue(CLUSTER.operation_finished())


class TestTableAdminAPI(unittest2.TestCase):

@classmethod
def setUpClass(self):
self._table = CLUSTER.table(TEST_TABLE_ID)
self._table.create()

@classmethod
def tearDownClass(self):
self._table.delete()

def setUp(self):
self.tables_to_delete = []

def tearDown(self):
for table in self.tables_to_delete:
table.delete()

def test_list_tables(self):
# Since `CLUSTER` is newly created in `setUpModule`, the table
# created in `setUpClass` here will be the only one.
tables = CLUSTER.list_tables()
self.assertEqual(tables, [self._table])

def test_create_table(self):
temp_table_id = 'foo-bar-baz-table'
temp_table = CLUSTER.table(temp_table_id)
temp_table.create()
self.tables_to_delete.append(temp_table)

# First, create a sorted version of our expected result.
expected_tables = sorted([temp_table, self._table],
key=lambda value: value.name)

# Then query for the tables in the cluster and sort them by
# name as well.
tables = CLUSTER.list_tables()
sorted_tables = sorted(tables, key=lambda value: value.name)
self.assertEqual(sorted_tables, expected_tables)

def test_create_column_family(self):
from gcloud_bigtable.column_family import GarbageCollectionRule
temp_table_id = 'foo-bar-baz-table'
temp_table = CLUSTER.table(temp_table_id)
temp_table.create()
self.tables_to_delete.append(temp_table)

self.assertEqual(temp_table.list_column_families(), {})
column_family_id = u'my-column'
gc_rule = GarbageCollectionRule(max_num_versions=1)
column_family = temp_table.column_family(column_family_id,
gc_rule=gc_rule)
column_family.create()

col_fams = temp_table.list_column_families()

self.assertEqual(len(col_fams), 1)
retrieved_col_fam = col_fams[column_family_id]
self.assertTrue(retrieved_col_fam.table is column_family.table)
self.assertEqual(retrieved_col_fam.column_family_id,
column_family.column_family_id)
# Due to a quirk / bug in the API, the retrieved column family
# does not include the GC rule.
self.assertNotEqual(retrieved_col_fam.gc_rule, column_family.table)
self.assertEqual(retrieved_col_fam.gc_rule, None)

def test_delete_column_family(self):
temp_table_id = 'foo-bar-baz-table'
temp_table = CLUSTER.table(temp_table_id)
temp_table.create()
self.tables_to_delete.append(temp_table)

self.assertEqual(temp_table.list_column_families(), {})
column_family_id = u'my-column'
column_family = temp_table.column_family(column_family_id)
column_family.create()

# Make sure the family is there before deleting it.
col_fams = temp_table.list_column_families()
self.assertEqual(list(col_fams.keys()), [column_family_id])

column_family.delete()
# Make sure we have successfully deleted it.
self.assertEqual(temp_table.list_column_families(), {})

0 comments on commit 38f9ff7

Please sign in to comment.