Skip to content

Commit

Permalink
Adding ability to convert a garbage collection rule to protobuf.
Browse files Browse the repository at this point in the history
  • Loading branch information
dhermes committed Jul 28, 2015
1 parent d0a91f9 commit e77f994
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 0 deletions.
27 changes: 27 additions & 0 deletions gcloud_bigtable/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from gcloud_bigtable._generated import (
bigtable_cluster_service_messages_pb2 as messages_pb2)
from gcloud_bigtable._generated import bigtable_cluster_data_pb2 as data_pb2
from gcloud_bigtable._generated import duration_pb2


_TYPE_URL_BASE = 'type.googleapis.com/google.bigtable.'
Expand Down Expand Up @@ -115,3 +116,29 @@ def _parse_pb_any_to_native(any_val, expected_type=None):
expected_type, any_val.type_url))
container_class = _TYPE_URL_MAP[any_val.type_url]
return container_class.FromString(any_val.value)


def _timedelta_to_duration_pb(timedelta_val):
"""Convert a Python timedelta object to a duration protobuf.
.. note::
The Python timedelta has a granularity of microseconds while
the protobuf duration type has a duration of nanoseconds.
:type timedelta_val: :class:`datetime.timedelta`
:param timedelta_val: A timedelta object.
:rtype: :class:`duration_pb2.Duration`
:returns: A duration object equivalent to the time delta.
"""
seconds_decimal = timedelta_val.total_seconds()
# Truncate the parts other than the integer.
seconds = int(seconds_decimal)
if seconds_decimal < 0:
signed_micros = timedelta_val.microseconds - 10**6
else:
signed_micros = timedelta_val.microseconds
# Convert nanoseconds to microseconds.
nanos = 1000 * signed_micros
return duration_pb2.Duration(seconds=seconds, nanos=nanos)
15 changes: 15 additions & 0 deletions gcloud_bigtable/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
"""User friendly container for Google Cloud Bigtable Table."""


from gcloud_bigtable._generated import bigtable_table_data_pb2 as data_pb2
from gcloud_bigtable._generated import (
bigtable_table_service_messages_pb2 as messages_pb2)
from gcloud_bigtable._generated import bigtable_table_service_pb2
from gcloud_bigtable._helpers import _timedelta_to_duration_pb
from gcloud_bigtable.connection import TIMEOUT_SECONDS
from gcloud_bigtable.connection import make_stub

Expand Down Expand Up @@ -63,6 +65,19 @@ def __init__(self, max_num_versions=None, max_age=None):
self.max_num_versions = max_num_versions
self.max_age = max_age

def to_pb(self):
"""Converts the :class:`GarbageCollectionRule` to a protobuf.
:rtype: :class:`data_pb2.GcRule`
:returns: The convert current object.
"""
gc_rule_kwargs = {}
if self.max_num_versions is not None:
gc_rule_kwargs['max_num_versions'] = self.max_num_versions
if self.max_age is not None:
gc_rule_kwargs['max_age'] = _timedelta_to_duration_pb(self.max_age)
return data_pb2.GcRule(**gc_rule_kwargs)


class Table(object):
"""Representation of a Google Cloud Bigtable Table.
Expand Down
45 changes: 45 additions & 0 deletions gcloud_bigtable/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,48 @@ def test_disagreeing_type_url(self):
with _Monkey(MUT, _TYPE_URL_MAP=fake_type_url_map):
with self.assertRaises(ValueError):
self._callFUT(any_val, expected_type=type_url1)


class Test__timedelta_to_duration_pb(unittest2.TestCase):

def _callFUT(self, timedelta_val):
from gcloud_bigtable._helpers import _timedelta_to_duration_pb
return _timedelta_to_duration_pb(timedelta_val)

def test_it(self):
import datetime
from gcloud_bigtable._generated import duration_pb2

seconds = microseconds = 1
timedelta_val = datetime.timedelta(seconds=seconds,
microseconds=microseconds)
result = self._callFUT(timedelta_val)
self.assertTrue(isinstance(result, duration_pb2.Duration))
self.assertEqual(result.seconds, seconds)
self.assertEqual(result.nanos, 1000 * microseconds)

def test_with_negative_microseconds(self):
import datetime
from gcloud_bigtable._generated import duration_pb2

seconds = 1
microseconds = -5
timedelta_val = datetime.timedelta(seconds=seconds,
microseconds=microseconds)
result = self._callFUT(timedelta_val)
self.assertTrue(isinstance(result, duration_pb2.Duration))
self.assertEqual(result.seconds, seconds - 1)
self.assertEqual(result.nanos, 10**9 + 1000 * microseconds)

def test_with_negative_seconds(self):
import datetime
from gcloud_bigtable._generated import duration_pb2

seconds = -1
microseconds = 5
timedelta_val = datetime.timedelta(seconds=seconds,
microseconds=microseconds)
result = self._callFUT(timedelta_val)
self.assertTrue(isinstance(result, duration_pb2.Duration))
self.assertEqual(result.seconds, seconds + 1)
self.assertEqual(result.nanos, -(10**9 - 1000 * microseconds))
28 changes: 28 additions & 0 deletions gcloud_bigtable/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,34 @@ def test_constructor_failure(self):
with self.assertRaises(ValueError):
self._makeOne(max_num_versions=1, max_age=object())

def test_to_pb_no_value(self):
from gcloud_bigtable._generated import (
bigtable_table_data_pb2 as data_pb2)
gc_rule = self._makeOne()
pb_val = gc_rule.to_pb()
self.assertEqual(pb_val, data_pb2.GcRule())

def test_to_pb_with_max_num_versions(self):
from gcloud_bigtable._generated import (
bigtable_table_data_pb2 as data_pb2)
max_num_versions = 1337
gc_rule = self._makeOne(max_num_versions=max_num_versions)
pb_val = gc_rule.to_pb()
self.assertEqual(pb_val,
data_pb2.GcRule(max_num_versions=max_num_versions))

def test_to_pb_with_max_age(self):
import datetime
from gcloud_bigtable._generated import (
bigtable_table_data_pb2 as data_pb2)
from gcloud_bigtable._generated import duration_pb2

max_age = datetime.timedelta(seconds=1)
duration = duration_pb2.Duration(seconds=1)
gc_rule = self._makeOne(max_age=max_age)
pb_val = gc_rule.to_pb()
self.assertEqual(pb_val, data_pb2.GcRule(max_age=duration))


class TestTable(GRPCMockTestMixin):

Expand Down

0 comments on commit e77f994

Please sign in to comment.