inmemory_test.go
Overview
The inmemory_test.go file contains comprehensive unit tests for the in-memory implementation of the session management service. This service is responsible for managing user-agent interaction sessions, including session creation, retrieval, listing, deletion, event appending, and state management, all stored transiently in memory.
The tests verify the correctness, consistency, and isolation properties of the in-memory session service, validating that session lifecycle operations and event handling behave as expected. They cover various scenarios including key generation, error handling, event filtering, and state scope separation.
This file exercises the core session management behavior implemented in the in-memory backend, ensuring it meets functional requirements before integration with other system components such as the Agent Execution Runner.
Detailed Explanations of Tests and Functions
Test_databaseService_Create
Tests the Create method of the in-memory session service.
Purpose: Verify that sessions can be created with either a fully specified session key or an auto-generated session ID, and that duplicate creation returns an error.
Parameters: Uses a table-driven test with:
Test Scenarios:
Creating a session with full key provided.
Creating a session with no
SessionID(should generate one).Creating a session that already exists (should error).
Key Assertions:
The returned session's
AppName,UserID, andSessionIDmatch the request.The session state matches the input state.
Errors occur as expected.
Test_databaseService_Delete
Tests the Delete method.
Purpose: Validate that session deletion works correctly, including gracefully handling deletion of non-existent sessions.
Parameters:
name: Test case name.
req: DeleteRequest with session identification.setup: Function returning a
Service.wantErr: Whether deletion should error.
Test Cases:
Successful deletion of an existing session.
Deletion attempt of a non-existent session (should not error).
Test_databaseService_Get
Tests the Get method.
Purpose: Ensures session retrieval returns correct session data and respects filtering conditions.
Parameters:
name: Test case description.
req:GetRequestspecifyingAppName,UserID,SessionID, and optional event filters (NumRecentEvents, After).setup: Setup function preparing the state.
wantResponse: Expected GetResponse containing the session.
wantEvents: Expected events filtered from the session.
wantErr: Expected error occurrence.
Notable Setup Functions:
setupGetRespectsUserID: Creates sessions for multiple users and appends an event to one, testing user isolation.
setupGetWithConfig: Creates a session and appends multiple events for event filtering tests.
Test Scenarios:
Normal session retrieval.
Retrieval of non-existent session (error).
Session retrieval respecting user ID isolation.
Retrieval with no event filters (returns all events).
Retrieval with limited recent events.
Retrieval with event timestamp filtering.
Combined event filters.
Assertions:
Session data matches expected.
Event slices match expected filtered events.
Test_databaseService_List
Tests the List method.
Purpose: Verify correct listing of sessions filtered by user or app.
Parameters:
name: Test case description.
req: ListRequest specifyingAppNameand optionalUserID.setup: Setup function providing service instance.
wantResponse: Expected ListResponse with sessions.
wantErr: Expected error flag.
Test Cases:
List sessions for a specified user.
List sessions for non-existent user (empty result).
List sessions for another user.
List all sessions for an app with no user filter.
Assertions:
Returned sessions match expected, sorted and state-merged.
Test_databaseService_AppendEvent
Tests the AppendEvent method.
Purpose: Validate appending events to sessions updates session state and event history correctly, including handling of special event cases.
Parameters:
name: Test name.
setup: Function returning service.
session: The session to append event onto.event: The event to append.wantStoredSession: Expected session state after append.
wantEventCount: Expected number of stored events.
wantErr: Expected error flag.
Test Scenarios:
Append event to empty session.
Append event to session with existing events.
Append event to non-existent session (should fail).
Append event with embedded bytes content.
Append event with comprehensive metadata fields.
Append partial event (should not persist).
Key Implementation Details:
Partial events are ignored.
State delta extracted from event actions updates app, user, and session states.
Temporary state keys (
temp:prefix) are filtered out before persistence.Timestamp update and stale session validation occur before appending.
Assertions:
Session state after appending matches expected.
Event count in storage matches expected.
Errors occur as expected.
Test_databaseService_StateManagement
Tests nuanced aspects of multi-level session state management and sharing.
Purpose: Verify correct scoping and persistence of state across app, user, and session levels.
Subtests:
app_state_is_shared: Application-scoped state keys (app: prefix) are shared across users and sessions.
user_state_is_user_specific: User-scoped state keys (
user:prefix) are isolated per user but shared across their sessions.session_state_is_not_shared: Session-scoped keys are isolated to the specific session.
temp_state_is_not_persisted: Temporary state keys (
temp:prefix) are filtered out and not persisted in events or session state.
Assertions:
State maps reflect correct isolation or sharing.
Temporary keys are absent from stored events and state.
Utility Functions
serviceDbWithData: Returns a pre-populated in-memory service with multiple sessions and states for testing.
emptyService: Returns a fresh, empty in-memory service instance for isolated tests.
Important Implementation Details and Algorithms
The in-memory service uses composite keys (appName, userID,
sessionID) encoded into strings to store and retrieve sessions efficiently.State is maintained in three separate scopes:
Events appended to sessions carry state deltas. These deltas are extracted and applied to the three state scopes based on key prefixes (app:,
user:, or no prefix).Partial events (indicated by
Partial: true) are not persisted to avoid saving incomplete streaming responses.Temporary state keys prefixed with
temp:are stripped before persistence, ensuring ephemeral data does not pollute stored state.The tests simulate event timestamps and state updates to validate ordering and stale-session protections.
State merging occurs on session retrieval, combining session, user, and app state maps into a unified view.
Interaction With Other Parts of the System
The in-memory session service implements the
Serviceinterface defined in the Session Management topic, allowing it to be used interchangeably with other storage backends such as the database session service.The sessions and events managed here are foundational inputs and outputs for the Agent Execution Runner, enabling multi-turn conversational state and event histories.
Event content, including LLM responses and grounding metadata, can be leveraged by other modules like LLM Integration and Agents and Instruction Template Processing.
Temporary and scoped state handling support dynamic injection and persistence as described in Session State Injection.
The in-memory service provides a rapid, thread-safe backend ideal for testing and transient use cases.
Visual Diagram: Structure of the In-Memory Session Service Testing
flowchart TD
A[Test_databaseService_Create] --> B[Create sessions with/without sessionID]
A --> C[Check duplicate session creation error]
D[Test_databaseService_Delete] --> E[Delete existing session]
D --> F[Delete non-existent session]
G[Test_databaseService_Get] --> H[Retrieve sessions]
G --> I[Filter events by timestamp/count]
G --> J[User ID isolation in retrieval]
K[Test_databaseService_List] --> L[List sessions by user]
K --> M[List all sessions for app]
N[Test_databaseService_AppendEvent] --> O[Append event with full metadata]
N --> P[Ignore partial events]
N --> Q[State delta applied to app/user/session states]
N --> R[Error on non-existent session]
S[Test_databaseService_StateManagement] --> T[App state shared across users]
S --> U[User state isolated by user]
S --> V[Session state isolated by session]
S --> W[Temporary state not persisted]
subgraph SetupFunctions
X[emptyService] --> A
X --> D
X --> G
X --> K
X --> N
Y[serviceDbWithData] --> A
Y --> D
Y --> G
Y --> K
Y --> N
end
This flowchart visualizes the relationships and coverage of the test functions within the file, illustrating how they verify creation, deletion, retrieval, listing, event appending, and state management behaviors of the in-memory session service.
Usage Examples
Creating a Session:
s := emptyService(t) req := &CreateRequest{ AppName: "myApp", UserID: "user123", SessionID: "", State: map[string]any{"key": "value"}, } resp, err := s.Create(t.Context(), req) if err != nil { t.Fatalf("Failed to create session: %v", err) } fmt.Println("Created session ID:", resp.Session.ID())Appending an Event:
event := &Event{ ID: "event1", LLMResponse: model.LLMResponse{ Partial: false, }, Actions: EventActions{ StateDelta: map[string]any{"user:key": "newValue"}, }, } err := s.AppendEvent(t.Context(), resp.Session.(*session), event) if err != nil { t.Fatalf("Failed to append event: %v", err) }Retrieving a Session with Event Filtering:
getReq := &GetRequest{ AppName: "myApp", UserID: "user123", SessionID: resp.Session.ID(), NumRecentEvents: 10, } getResp, err := s.Get(t.Context(), getReq) if err != nil { t.Fatalf("Failed to get session: %v", err) } fmt.Println("Session Events Count:", getResp.Session.Events().Len())
These examples reflect typical usage patterns exercised in the tests.
References
See Session Management for the overall session lifecycle and state management concepts.
See In-Memory Session Service for the implementation details of the in-memory backend tested here.
Related to event structure and state delta handling: Event Conversion and Processing.
Interactions with agent execution: Agent Execution Runner.
State injection and filtering: Session State Injection.