@@ -233,6 +233,7 @@ def test_create(self):
233233
234234 # Create response_pb
235235 op_id = 5678
236+ op_begin = object ()
236237 op_name = ('operations/projects/%s/zones/%s/clusters/%s/'
237238 'operations/%d' % (project , zone , cluster_id , op_id ))
238239 current_op = operations_pb2 .Operation (name = op_name )
@@ -244,14 +245,22 @@ def test_create(self):
244245 # Create expected_result.
245246 expected_result = None # create() has no return value.
246247
247- # Perform the method and check the result .
248+ # Create the mocks .
248249 prep_create_called = []
249250
250251 def mock_prep_create_req (cluster ):
251252 prep_create_called .append (cluster )
252253 return request_pb
253254
254- with _Monkey (MUT , _prepare_create_request = mock_prep_create_req ):
255+ process_operation_called = []
256+
257+ def mock_process_operation (operation_pb ):
258+ process_operation_called .append (operation_pb )
259+ return (op_id , op_begin )
260+
261+ # Perform the method and check the result.
262+ with _Monkey (MUT , _prepare_create_request = mock_prep_create_req ,
263+ _process_operation = mock_process_operation ):
255264 result = cluster .create ()
256265
257266 self .assertEqual (result , expected_result )
@@ -260,8 +269,11 @@ def mock_prep_create_req(cluster):
260269 (request_pb , timeout_seconds ),
261270 {},
262271 )])
263- self .assertEqual (cluster ._operation , current_op )
272+ self .assertEqual (cluster ._operation_type , 'create' )
273+ self .assertEqual (cluster ._operation_id , op_id )
274+ self .assertTrue (cluster ._operation_begin is op_begin )
264275 self .assertEqual (prep_create_called , [cluster ])
276+ self .assertEqual (process_operation_called , [current_op ])
265277
266278 def test_delete (self ):
267279 from gcloud .bigtable ._generated import (
@@ -357,6 +369,172 @@ def test_it(self):
357369 self .assertEqual (request_pb .cluster .serve_nodes , serve_nodes )
358370
359371
372+ class Test__pb_timestamp_to_datetime (unittest2 .TestCase ):
373+
374+ def _callFUT (self , timestamp ):
375+ from gcloud .bigtable .cluster import _pb_timestamp_to_datetime
376+ return _pb_timestamp_to_datetime (timestamp )
377+
378+ def test_it (self ):
379+ import datetime
380+ from gcloud ._helpers import UTC
381+ from gcloud .bigtable ._generated .timestamp_pb2 import Timestamp
382+
383+ # Epoch is midnight on January 1, 1970 ...
384+ dt_stamp = datetime .datetime (1970 , month = 1 , day = 1 , hour = 0 ,
385+ minute = 1 , second = 1 , microsecond = 1234 ,
386+ tzinfo = UTC )
387+ # ... so 1 minute and 1 second after is 61 seconds and 1234
388+ # microseconds is 1234000 nanoseconds.
389+ timestamp = Timestamp (seconds = 61 , nanos = 1234000 )
390+ self .assertEqual (self ._callFUT (timestamp ), dt_stamp )
391+
392+
393+ class Test__parse_pb_any_to_native (unittest2 .TestCase ):
394+
395+ def _callFUT (self , any_val , expected_type = None ):
396+ from gcloud .bigtable .cluster import _parse_pb_any_to_native
397+ return _parse_pb_any_to_native (any_val , expected_type = expected_type )
398+
399+ def test_with_known_type_url (self ):
400+ from gcloud ._testing import _Monkey
401+ from gcloud .bigtable ._generated import any_pb2
402+ from gcloud .bigtable ._generated import bigtable_data_pb2 as data_pb2
403+ from gcloud .bigtable import cluster as MUT
404+
405+ type_url = 'type.googleapis.com/' + data_pb2 ._CELL .full_name
406+ fake_type_url_map = {type_url : data_pb2 .Cell }
407+
408+ cell = data_pb2 .Cell (
409+ timestamp_micros = 0 ,
410+ value = b'foobar' ,
411+ )
412+ any_val = any_pb2 .Any (
413+ type_url = type_url ,
414+ value = cell .SerializeToString (),
415+ )
416+ with _Monkey (MUT , _TYPE_URL_MAP = fake_type_url_map ):
417+ result = self ._callFUT (any_val )
418+
419+ self .assertEqual (result , cell )
420+
421+ def test_with_create_cluster_metadata (self ):
422+ from gcloud .bigtable ._generated import any_pb2
423+ from gcloud .bigtable ._generated import (
424+ bigtable_cluster_data_pb2 as data_pb2 )
425+ from gcloud .bigtable ._generated import (
426+ bigtable_cluster_service_messages_pb2 as messages_pb2 )
427+ from gcloud .bigtable ._generated .timestamp_pb2 import Timestamp
428+
429+ type_url = ('type.googleapis.com/' +
430+ messages_pb2 ._CREATECLUSTERMETADATA .full_name )
431+ metadata = messages_pb2 .CreateClusterMetadata (
432+ request_time = Timestamp (seconds = 1 , nanos = 1234 ),
433+ finish_time = Timestamp (seconds = 10 , nanos = 891011 ),
434+ original_request = messages_pb2 .CreateClusterRequest (
435+ name = 'foo' ,
436+ cluster_id = 'bar' ,
437+ cluster = data_pb2 .Cluster (
438+ display_name = 'quux' ,
439+ serve_nodes = 1337 ,
440+ ),
441+ ),
442+ )
443+
444+ any_val = any_pb2 .Any (
445+ type_url = type_url ,
446+ value = metadata .SerializeToString (),
447+ )
448+ result = self ._callFUT (any_val )
449+ self .assertEqual (result , metadata )
450+
451+ def test_unknown_type_url (self ):
452+ from gcloud ._testing import _Monkey
453+ from gcloud .bigtable ._generated import any_pb2
454+ from gcloud .bigtable import cluster as MUT
455+
456+ fake_type_url_map = {}
457+ any_val = any_pb2 .Any ()
458+ with _Monkey (MUT , _TYPE_URL_MAP = fake_type_url_map ):
459+ with self .assertRaises (KeyError ):
460+ self ._callFUT (any_val )
461+
462+ def test_disagreeing_type_url (self ):
463+ from gcloud ._testing import _Monkey
464+ from gcloud .bigtable ._generated import any_pb2
465+ from gcloud .bigtable import cluster as MUT
466+
467+ type_url1 = 'foo'
468+ type_url2 = 'bar'
469+ fake_type_url_map = {type_url1 : None }
470+ any_val = any_pb2 .Any (type_url = type_url2 )
471+ with _Monkey (MUT , _TYPE_URL_MAP = fake_type_url_map ):
472+ with self .assertRaises (ValueError ):
473+ self ._callFUT (any_val , expected_type = type_url1 )
474+
475+
476+ class Test__process_operation (unittest2 .TestCase ):
477+
478+ def _callFUT (self , operation_pb ):
479+ from gcloud .bigtable .cluster import _process_operation
480+ return _process_operation (operation_pb )
481+
482+ def test_it (self ):
483+ from gcloud ._testing import _Monkey
484+ from gcloud .bigtable ._generated import (
485+ bigtable_cluster_service_messages_pb2 as messages_pb2 )
486+ from gcloud .bigtable ._generated import operations_pb2
487+ from gcloud .bigtable import cluster as MUT
488+
489+ project = 'PROJECT'
490+ zone = 'zone'
491+ cluster_id = 'cluster-id'
492+ expected_operation_id = 234
493+ operation_name = ('operations/projects/%s/zones/%s/clusters/%s/'
494+ 'operations/%d' % (project , zone , cluster_id ,
495+ expected_operation_id ))
496+
497+ current_op = operations_pb2 .Operation (name = operation_name )
498+
499+ # Create mocks.
500+ request_metadata = messages_pb2 .CreateClusterMetadata ()
501+ parse_pb_any_called = []
502+
503+ def mock_parse_pb_any_to_native (any_val , expected_type = None ):
504+ parse_pb_any_called .append ((any_val , expected_type ))
505+ return request_metadata
506+
507+ expected_operation_begin = object ()
508+ ts_to_dt_called = []
509+
510+ def mock_pb_timestamp_to_datetime (timestamp ):
511+ ts_to_dt_called .append (timestamp )
512+ return expected_operation_begin
513+
514+ # Exectute method with mocks in place.
515+ with _Monkey (MUT , _parse_pb_any_to_native = mock_parse_pb_any_to_native ,
516+ _pb_timestamp_to_datetime = mock_pb_timestamp_to_datetime ):
517+ operation_id , operation_begin = self ._callFUT (current_op )
518+
519+ # Check outputs.
520+ self .assertEqual (operation_id , expected_operation_id )
521+ self .assertTrue (operation_begin is expected_operation_begin )
522+
523+ # Check mocks were used correctly.
524+ self .assertEqual (parse_pb_any_called , [(current_op .metadata , None )])
525+ self .assertEqual (ts_to_dt_called , [request_metadata .request_time ])
526+
527+ def test_op_name_parsing_failure (self ):
528+ from gcloud .bigtable ._generated import (
529+ bigtable_cluster_data_pb2 as data_pb2 )
530+ from gcloud .bigtable ._generated import operations_pb2
531+
532+ current_op = operations_pb2 .Operation (name = 'invalid' )
533+ cluster = data_pb2 .Cluster (current_operation = current_op )
534+ with self .assertRaises (ValueError ):
535+ self ._callFUT (cluster )
536+
537+
360538class _Client (object ):
361539
362540 def __init__ (self , project , timeout_seconds = None ):
0 commit comments