Skip to content

Commit aaec17b

Browse files
Fix E2E sqlite test session_id recording and Windows flaky test
Go/Python/Rust: Fix E2E stub providers to record actual session ID from stored state instead of hardcoded strings, so filterCalls assertions match the real session. Node.js: Move SQLite database Map to describe scope so it survives handler re-creation. The factory-scoped closure variable caused each handler invocation to create a fresh :memory: database, losing previously inserted data. This caused intermittent failures on Windows where the CLI re-creates the handler between tool calls. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d5a3b91 commit aaec17b

4 files changed

Lines changed: 16 additions & 9 deletions

File tree

go/internal/e2e/session_fs_sqlite_e2e_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func (p *inMemorySqliteProvider) SqliteQuery(queryType rpc.SessionFsSqliteQueryT
200200
defer p.mu.Unlock()
201201
p.hadQuery = true
202202
*p.sqliteCalls = append(*p.sqliteCalls, sqliteCall{
203-
SessionID: "stub",
203+
SessionID: p.sessionID,
204204
QueryType: string(queryType),
205205
Query: query,
206206
})

nodejs/test/e2e/session_fs_sqlite.e2e.test.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ describe("Session Fs SQLite", async () => {
4040
const provider = new MemoryProvider();
4141
/** Track which queries were received, per session */
4242
const sqliteCalls: { sessionId: string; queryType: string; query: string }[] = [];
43+
/** Per-session SQLite databases, keyed by session ID.
44+
* Stored at describe scope so the database survives if the CLI
45+
* re-creates the handler (e.g., on reconnect). */
46+
const sessionDbs = new Map<string, DatabaseSync>();
4347

4448
const createSessionFsHandler = (session: CopilotSession) =>
45-
createTestSessionFsHandlerWithSqlite(session, provider, sqliteCalls);
49+
createTestSessionFsHandlerWithSqlite(session, provider, sqliteCalls, sessionDbs);
4650

4751
// Helpers to build session-namespaced paths for direct provider assertions
4852
const p = (sessionId: string, path: string) =>
@@ -139,17 +143,17 @@ describe("Session Fs SQLite", async () => {
139143
function createTestSessionFsHandlerWithSqlite(
140144
session: CopilotSession,
141145
provider: VirtualProvider,
142-
sqliteCalls: { sessionId: string; queryType: string; query: string }[]
146+
sqliteCalls: { sessionId: string; queryType: string; query: string }[],
147+
sessionDbs: Map<string, DatabaseSync>
143148
): SessionFsProvider {
144149
const sp = (path: string) => `/${session.sessionId}${path.startsWith("/") ? path : "/" + path}`;
145150

146-
// Per-session SQLite database (in-memory)
147-
let db: DatabaseSync | undefined;
148-
149151
function getOrCreateDb(): DatabaseSync {
152+
let db = sessionDbs.get(session.sessionId);
150153
if (!db) {
151154
db = new DatabaseSync(":memory:");
152155
db.exec("PRAGMA busy_timeout = 5000");
156+
sessionDbs.set(session.sessionId, db);
153157
}
154158
return db;
155159
}
@@ -246,7 +250,7 @@ function createTestSessionFsHandlerWithSqlite(
246250
}
247251
},
248252
async exists(): Promise<boolean> {
249-
return db !== undefined;
253+
return sessionDbs.has(session.sessionId);
250254
},
251255
},
252256
};

python/e2e/test_session_fs_sqlite_e2e.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ async def sqlite_query(
154154
) -> SessionFsSqliteQueryResult:
155155
self._sqlite_calls.append(
156156
{
157+
"sessionId": self._session_id,
157158
"queryType": query_type.value,
158159
"query": query,
159160
}

rust/tests/e2e/session_fs_sqlite.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,19 @@ struct SqliteCall {
1919
}
2020

2121
struct InMemorySqliteProvider {
22+
session_id: String,
2223
files: Mutex<HashMap<String, String>>,
2324
dirs: Mutex<std::collections::HashSet<String>>,
2425
db: Mutex<Option<Connection>>,
2526
sqlite_calls: Arc<Mutex<Vec<SqliteCall>>>,
2627
}
2728

2829
impl InMemorySqliteProvider {
29-
fn new(_session_id: &str, calls: Arc<Mutex<Vec<SqliteCall>>>) -> Self {
30+
fn new(session_id: &str, calls: Arc<Mutex<Vec<SqliteCall>>>) -> Self {
3031
let mut dirs = std::collections::HashSet::new();
3132
dirs.insert("/".to_string());
3233
Self {
34+
session_id: session_id.to_string(),
3335
files: Mutex::new(HashMap::new()),
3436
dirs: Mutex::new(dirs),
3537
db: Mutex::new(None),
@@ -222,7 +224,7 @@ impl SessionFsSqliteProvider for InMemorySqliteProvider {
222224
SessionFsSqliteQueryType::Unknown => "unknown",
223225
};
224226
self.sqlite_calls.lock().unwrap().push(SqliteCall {
225-
session_id: "session".to_string(),
227+
session_id: self.session_id.clone(),
226228
query_type: qt_str.to_string(),
227229
query: query.to_string(),
228230
});

0 commit comments

Comments
 (0)