@@ -24,28 +24,50 @@ def _get_target_class():
2424
2525 return Transaction
2626
27- def _get_options_class (self , ** kw ):
27+ def _make_one (self , client , ** kw ):
28+ return self ._get_target_class ()(client , ** kw )
29+
30+ def _make_options (self , read_only = False , previous_transaction = None ):
2831 from google .cloud .datastore_v1 .types import TransactionOptions
2932
30- return TransactionOptions
33+ kw = {}
3134
32- def _make_one ( self , client , ** kw ) :
33- return self . _get_target_class ()( client , ** kw )
35+ if read_only :
36+ kw [ "read_only" ] = TransactionOptions . ReadOnly ( )
3437
35- def _make_options (self , ** kw ):
36- return self ._get_options_class ()(** kw )
38+ return TransactionOptions (** kw )
3739
3840 def test_ctor_defaults (self ):
3941 project = "PROJECT"
4042 client = _Client (project )
43+
4144 xact = self ._make_one (client )
45+
4246 self .assertEqual (xact .project , project )
4347 self .assertIs (xact ._client , client )
4448 self .assertIsNone (xact .id )
4549 self .assertEqual (xact ._status , self ._get_target_class ()._INITIAL )
4650 self .assertEqual (xact ._mutations , [])
4751 self .assertEqual (len (xact ._partial_key_entities ), 0 )
4852
53+ def test_constructor_read_only (self ):
54+ project = "PROJECT"
55+ id_ = 850302
56+ ds_api = _make_datastore_api (xact = id_ )
57+ client = _Client (project , datastore_api = ds_api )
58+ options = self ._make_options (read_only = True )
59+
60+ xact = self ._make_one (client , read_only = True )
61+
62+ self .assertEqual (xact ._options , options )
63+
64+ def _make_begin_request (self , project , read_only = False ):
65+ expected_options = self ._make_options (read_only = read_only )
66+ return {
67+ "project_id" : project ,
68+ "transaction_options" : expected_options ,
69+ }
70+
4971 def test_current (self ):
5072 from google .cloud .datastore_v1 .types import datastore as datastore_pb2
5173
@@ -57,24 +79,34 @@ def test_current(self):
5779 xact2 = self ._make_one (client )
5880 self .assertIsNone (xact1 .current ())
5981 self .assertIsNone (xact2 .current ())
82+
6083 with xact1 :
6184 self .assertIs (xact1 .current (), xact1 )
6285 self .assertIs (xact2 .current (), xact1 )
86+
6387 with _NoCommitBatch (client ):
6488 self .assertIsNone (xact1 .current ())
6589 self .assertIsNone (xact2 .current ())
90+
6691 with xact2 :
6792 self .assertIs (xact1 .current (), xact2 )
6893 self .assertIs (xact2 .current (), xact2 )
94+
6995 with _NoCommitBatch (client ):
7096 self .assertIsNone (xact1 .current ())
7197 self .assertIsNone (xact2 .current ())
98+
7299 self .assertIs (xact1 .current (), xact1 )
73100 self .assertIs (xact2 .current (), xact1 )
101+
74102 self .assertIsNone (xact1 .current ())
75103 self .assertIsNone (xact2 .current ())
76104
77- ds_api .rollback .assert_not_called ()
105+ begin_txn = ds_api .begin_transaction
106+ self .assertEqual (begin_txn .call_count , 2 )
107+ expected_request = self ._make_begin_request (project )
108+ begin_txn .assert_called_with (request = expected_request )
109+
78110 commit_method = ds_api .commit
79111 self .assertEqual (commit_method .call_count , 2 )
80112 mode = datastore_pb2 .CommitRequest .Mode .TRANSACTIONAL
@@ -87,21 +119,35 @@ def test_current(self):
87119 }
88120 )
89121
90- begin_txn = ds_api .begin_transaction
91- self .assertEqual (begin_txn .call_count , 2 )
92- begin_txn .assert_called_with (request = {"project_id" : project })
122+ ds_api .rollback .assert_not_called ()
93123
94124 def test_begin (self ):
95125 project = "PROJECT"
96126 id_ = 889
97127 ds_api = _make_datastore_api (xact_id = id_ )
98128 client = _Client (project , datastore_api = ds_api )
99129 xact = self ._make_one (client )
130+
100131 xact .begin ()
132+
101133 self .assertEqual (xact .id , id_ )
102- ds_api .begin_transaction .assert_called_once_with (
103- request = {"project_id" : project }
104- )
134+
135+ expected_request = self ._make_begin_request (project )
136+ ds_api .begin_transaction .assert_called_once_with (request = expected_request )
137+
138+ def test_begin_w_readonly (self ):
139+ project = "PROJECT"
140+ id_ = 889
141+ ds_api = _make_datastore_api (xact_id = id_ )
142+ client = _Client (project , datastore_api = ds_api )
143+ xact = self ._make_one (client , read_only = True )
144+
145+ xact .begin ()
146+
147+ self .assertEqual (xact .id , id_ )
148+
149+ expected_request = self ._make_begin_request (project , read_only = True )
150+ ds_api .begin_transaction .assert_called_once_with (request = expected_request )
105151
106152 def test_begin_w_retry_w_timeout (self ):
107153 project = "PROJECT"
@@ -116,8 +162,10 @@ def test_begin_w_retry_w_timeout(self):
116162 xact .begin (retry = retry , timeout = timeout )
117163
118164 self .assertEqual (xact .id , id_ )
165+
166+ expected_request = self ._make_begin_request (project )
119167 ds_api .begin_transaction .assert_called_once_with (
120- request = { "project_id" : project } , retry = retry , timeout = timeout
168+ request = expected_request , retry = retry , timeout = timeout ,
121169 )
122170
123171 def test_begin_tombstoned (self ):
@@ -126,19 +174,23 @@ def test_begin_tombstoned(self):
126174 ds_api = _make_datastore_api (xact_id = id_ )
127175 client = _Client (project , datastore_api = ds_api )
128176 xact = self ._make_one (client )
177+
129178 xact .begin ()
179+
130180 self .assertEqual (xact .id , id_ )
131- ds_api . begin_transaction . assert_called_once_with (
132- request = { "project_id" : project }
133- )
181+
182+ expected_request = self . _make_begin_request ( project )
183+ ds_api . begin_transaction . assert_called_once_with ( request = expected_request )
134184
135185 xact .rollback ()
186+
136187 client ._datastore_api .rollback .assert_called_once_with (
137188 request = {"project_id" : project , "transaction" : id_ }
138189 )
139190 self .assertIsNone (xact .id )
140191
141- self .assertRaises (ValueError , xact .begin )
192+ with self .assertRaises (ValueError ):
193+ xact .begin ()
142194
143195 def test_begin_w_begin_transaction_failure (self ):
144196 project = "PROJECT"
@@ -152,9 +204,9 @@ def test_begin_w_begin_transaction_failure(self):
152204 xact .begin ()
153205
154206 self .assertIsNone (xact .id )
155- ds_api . begin_transaction . assert_called_once_with (
156- request = { "project_id" : project }
157- )
207+
208+ expected_request = self . _make_begin_request ( project )
209+ ds_api . begin_transaction . assert_called_once_with ( request = expected_request )
158210
159211 def test_rollback (self ):
160212 project = "PROJECT"
@@ -256,11 +308,14 @@ def test_context_manager_no_raise(self):
256308 ds_api = _make_datastore_api (xact_id = id_ )
257309 client = _Client (project , datastore_api = ds_api )
258310 xact = self ._make_one (client )
311+
259312 with xact :
260- self .assertEqual (xact .id , id_ )
261- ds_api .begin_transaction .assert_called_once_with (
262- request = {"project_id" : project }
263- )
313+ self .assertEqual (xact .id , id_ ) # only set between begin / commit
314+
315+ self .assertIsNone (xact .id )
316+
317+ expected_request = self ._make_begin_request (project )
318+ ds_api .begin_transaction .assert_called_once_with (request = expected_request )
264319
265320 mode = datastore_pb2 .CommitRequest .Mode .TRANSACTIONAL
266321 client ._datastore_api .commit .assert_called_once_with (
@@ -272,9 +327,6 @@ def test_context_manager_no_raise(self):
272327 },
273328 )
274329
275- self .assertIsNone (xact .id )
276- self .assertEqual (ds_api .begin_transaction .call_count , 1 )
277-
278330 def test_context_manager_w_raise (self ):
279331 class Foo (Exception ):
280332 pass
@@ -288,29 +340,20 @@ class Foo(Exception):
288340 try :
289341 with xact :
290342 self .assertEqual (xact .id , id_ )
291- ds_api .begin_transaction .assert_called_once_with (
292- request = {"project_id" : project }
293- )
294343 raise Foo ()
295344 except Foo :
296- self .assertIsNone (xact .id )
297- client ._datastore_api .rollback .assert_called_once_with (
298- request = {"project_id" : project , "transaction" : id_ }
299- )
345+ pass
300346
301- client ._datastore_api .commit .assert_not_called ()
302347 self .assertIsNone (xact .id )
303- self .assertEqual (ds_api .begin_transaction .call_count , 1 )
304348
305- def test_constructor_read_only (self ):
306- project = "PROJECT"
307- id_ = 850302
308- ds_api = _make_datastore_api (xact = id_ )
309- client = _Client (project , datastore_api = ds_api )
310- read_only = self ._get_options_class ().ReadOnly ()
311- options = self ._make_options (read_only = read_only )
312- xact = self ._make_one (client , read_only = True )
313- self .assertEqual (xact ._options , options )
349+ expected_request = self ._make_begin_request (project )
350+ ds_api .begin_transaction .assert_called_once_with (request = expected_request )
351+
352+ client ._datastore_api .commit .assert_not_called ()
353+
354+ client ._datastore_api .rollback .assert_called_once_with (
355+ request = {"project_id" : project , "transaction" : id_ }
356+ )
314357
315358 def test_put_read_only (self ):
316359 project = "PROJECT"
0 commit comments