3939from google .adk .events .event import Event
4040from google .adk .events .event_actions import EventActions
4141from google .adk .runners import Runner
42- from google .adk .sessions .base_session_service import ListSessionsResponse
42+ from google .adk .sessions .in_memory_session_service import InMemorySessionService
4343from google .adk .sessions .session import Session
44+ from google .adk .sessions .state import State
4445from google .genai import types
4546from pydantic import BaseModel
4647import pytest
@@ -194,98 +195,8 @@ def list_agents(self):
194195
195196@pytest .fixture
196197def mock_session_service ():
197- """Create a mock session service that uses an in-memory dictionary."""
198-
199- # In-memory database to store sessions during testing
200- session_data = {
201- "test_app" : {
202- "test_user" : {
203- "test_session" : {
204- "id" : "test_session" ,
205- "app_name" : "test_app" ,
206- "user_id" : "test_user" ,
207- "events" : [],
208- "state" : {},
209- "created_at" : time .time (),
210- }
211- }
212- }
213- }
214-
215- # Mock session service class that operates on the in-memory database
216- class MockSessionService :
217-
218- async def get_session (self , app_name , user_id , session_id ):
219- """Retrieve a session by ID."""
220- if (
221- app_name in session_data
222- and user_id in session_data [app_name ]
223- and session_id in session_data [app_name ][user_id ]
224- ):
225- return session_data [app_name ][user_id ][session_id ]
226- return None
227-
228- async def create_session (
229- self , app_name , user_id , state = None , session_id = None
230- ):
231- """Create a new session."""
232- if session_id is None :
233- session_id = f"session_{ int (time .time ())} "
234-
235- # Initialize app_name and user_id if they don't exist
236- if app_name not in session_data :
237- session_data [app_name ] = {}
238- if user_id not in session_data [app_name ]:
239- session_data [app_name ][user_id ] = {}
240-
241- # Create the session
242- session = {
243- "id" : session_id ,
244- "app_name" : app_name ,
245- "user_id" : user_id ,
246- "events" : [],
247- "state" : state or {},
248- }
249-
250- session_data [app_name ][user_id ][session_id ] = session
251- return session
252-
253- async def list_sessions (self , app_name , user_id ):
254- """List all sessions for a user."""
255- if app_name not in session_data or user_id not in session_data [app_name ]:
256- return {"sessions" : []}
257-
258- return ListSessionsResponse (
259- sessions = list (session_data [app_name ][user_id ].values ())
260- )
261-
262- async def delete_session (self , app_name , user_id , session_id ):
263- """Delete a session."""
264- if (
265- app_name in session_data
266- and user_id in session_data [app_name ]
267- and session_id in session_data [app_name ][user_id ]
268- ):
269- del session_data [app_name ][user_id ][session_id ]
270-
271- async def append_event (self , session , event ):
272- """Append an event to a session."""
273- # Update session state if event has state_delta
274- if event .actions and event .actions .state_delta :
275- session ["state" ].update (event .actions .state_delta )
276-
277- # Add event to session events
278- session ["events" ].append (event .model_dump ())
279-
280- # Update the session in storage
281- session_data [session ["app_name" ]][session ["user_id" ]][
282- session ["id" ]
283- ] = session
284-
285- return event
286-
287- # Return an instance of our mock service
288- return MockSessionService ()
198+ """Create an in-memory session service instance for testing."""
199+ return InMemorySessionService ()
289200
290201
291202@pytest .fixture
@@ -465,7 +376,7 @@ async def create_test_session(
465376 state = {},
466377 )
467378
468- logger .info (f"Created test session: { session [ 'id' ] } " )
379+ logger .info (f"Created test session: { session . id } " )
469380 return test_session_info
470381
471382
@@ -654,6 +565,22 @@ def test_create_session_with_id(test_app, test_session_info):
654565 logger .info (f"Created session with ID: { data ['id' ]} " )
655566
656567
568+ def test_create_session_with_id_already_exists (test_app , test_session_info ):
569+ """Test creating a session with an ID that already exists."""
570+ session_id = "existing_session_id"
571+ url = f"/apps/{ test_session_info ['app_name' ]} /users/{ test_session_info ['user_id' ]} /sessions/{ session_id } "
572+
573+ # Create the session for the first time
574+ response = test_app .post (url , json = {"state" : {}})
575+ assert response .status_code == 200
576+
577+ # Attempt to create it again
578+ response = test_app .post (url , json = {"state" : {}})
579+ assert response .status_code == 409
580+ assert "Session already exists" in response .json ()["detail" ]
581+ logger .info ("Verified 409 on duplicate session creation." )
582+
583+
657584def test_create_session_without_id (test_app , test_session_info ):
658585 """Test creating a session with a generated ID."""
659586 url = f"/apps/{ test_session_info ['app_name' ]} /users/{ test_session_info ['user_id' ]} /sessions"
@@ -753,9 +680,7 @@ def test_update_session(test_app, create_test_session):
753680 state_patch_events = [
754681 event
755682 for event in events
756- if (
757- event .get ("invocationId" ) or event .get ("invocation_id" , "" )
758- ).startswith ("p-" )
683+ if event .get ("invocationId" , "" ).startswith ("p-" )
759684 ]
760685
761686 assert len (state_patch_events ) == 1 , (
@@ -766,9 +691,9 @@ def test_update_session(test_app, create_test_session):
766691 assert state_patch_event ["author" ] == "user"
767692
768693 # Check for actions in both camelCase and snake_case
769- actions = state_patch_event .get ("actions" ) or state_patch_event . get ( "actions" )
694+ actions = state_patch_event .get ("actions" )
770695 assert actions is not None , f"No actions found in event: { state_patch_event } "
771- state_delta_in_event = actions .get ("state_delta" ) or actions . get ( " stateDelta" )
696+ state_delta_in_event = actions .get ("stateDelta" )
772697 assert state_delta_in_event == state_delta
773698
774699 logger .info ("Session state patched successfully" )
@@ -818,7 +743,7 @@ def test_agent_run(test_app, create_test_session):
818743 )
819744
820745 # Third event should have interrupted flag
821- assert data [2 ]["interrupted" ] == True
746+ assert data [2 ]["interrupted" ] is True
822747
823748 logger .info ("Agent run test completed successfully" )
824749
0 commit comments