@@ -45,6 +45,12 @@ def failed(self, event):
4545 if not event .command_name .startswith ('sasl' ):
4646 super (SessionTestListener , self ).failed (event )
4747
48+ def first_command_started (self ):
49+ assert len (self .results ['started' ]) >= 1 , (
50+ "No command-started events" )
51+
52+ return self .results ['started' ][0 ]
53+
4854
4955def session_ids (client ):
5056 return [s .session_id for s in client ._topology ._session_pool ]
@@ -122,16 +128,63 @@ def _test_ops(self, client, *ops, **kwargs):
122128 @client_context .require_auth
123129 @ignore_deprecations
124130 def test_session_authenticate_multiple (self ):
131+ listener = SessionTestListener ()
125132 # Logged in as root.
126- client = rs_or_single_client ()
127- client .pymongo_test . add_user ( 'second-user' , 'pass' )
128- self . addCleanup ( client . pymongo_test . remove_user , 'second-user' )
129-
130- client . pymongo_test .authenticate ('second-user' , 'pass' )
133+ client = rs_or_single_client (event_listeners = [ listener ] )
134+ db = client .pymongo_test
135+ db . add_user ( 'second-user' , 'pass ' )
136+ self . addCleanup ( db . remove_user , 'second-user' )
137+ db .authenticate ('second-user' , 'pass' )
131138
132139 with self .assertRaises (InvalidOperation ):
133140 client .start_session ()
134141
142+ # No implicit sessions.
143+ listener .results .clear ()
144+ db .collection .find_one ()
145+ event = listener .first_command_started ()
146+ self .assertNotIn (
147+ 'lsid' , event .command ,
148+ "find_one with multi-auth shouldn't have sent lsid with %s" % (
149+ event .command_name ))
150+
151+ # Changing auth invalidates the session. Start as root.
152+ client = rs_or_single_client (event_listeners = [listener ])
153+ db = client .pymongo_test
154+ db .collection .insert_many ([{} for _ in range (10 )])
155+ self .addCleanup (db .collection .drop )
156+ with client .start_session () as s :
157+ listener .results .clear ()
158+ cursor = db .collection .find (session = s ).batch_size (2 )
159+ next (cursor )
160+ event = listener .first_command_started ()
161+ self .assertEqual (event .command_name , 'find' )
162+ self .assertEqual (
163+ s .session_id , event .command .get ('lsid' ),
164+ "find sent wrong lsid with %s" % (event .command_name ,))
165+
166+ client .admin .logout ()
167+ db .authenticate ('second-user' , 'pass' )
168+
169+ err = 'start_session was called while authenticated with' \
170+ ' different credentials'
171+
172+ with self .assertRaisesRegex (InvalidOperation , err ):
173+ # Auth has changed between find and getMore.
174+ list (cursor )
175+
176+ with self .assertRaisesRegex (InvalidOperation , err ):
177+ db .collection .bulk_write ([InsertOne ({})], session = s )
178+
179+ with self .assertRaisesRegex (InvalidOperation , err ):
180+ db .collection_names (session = s )
181+
182+ with self .assertRaisesRegex (InvalidOperation , err ):
183+ db .collection .find_one (session = s )
184+
185+ with self .assertRaisesRegex (InvalidOperation , err ):
186+ list (db .collection .aggregate ([], session = s ))
187+
135188 def test_pool_lifo (self ):
136189 # "Pool is LIFO" test from Driver Sessions Spec.
137190 a = self .client .start_session ()
@@ -380,8 +433,7 @@ def test_cursor(self):
380433 for name , f in ops :
381434 listener .results .clear ()
382435 f (session = None )
383- self .assertGreaterEqual (len (listener .results ['started' ]), 1 )
384- event0 = listener .results ['started' ][0 ]
436+ event0 = listener .first_command_started ()
385437 self .assertTrue (
386438 'lsid' in event0 .command ,
387439 "%s sent no lsid with %s" % (
@@ -573,8 +625,7 @@ def test_aggregate_error(self):
573625 with self .assertRaises (OperationFailure ):
574626 coll .aggregate ([{'$badOperation' : {'bar' : 1 }}])
575627
576- self .assertEqual (len (listener .results ['started' ]), 1 )
577- event = listener .results ['started' ][0 ]
628+ event = listener .first_command_started ()
578629 self .assertEqual (event .command_name , 'aggregate' )
579630 lsid = event .command ['lsid' ]
580631 # Session was returned to pool despite error.
0 commit comments