mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Co-authored-by: Taylor Mullen <ntaylormullen@google.com> Co-authored-by: Arya Gummadi <aryagummadi@google.com>
This commit is contained in:
@@ -83,7 +83,7 @@ vi.mock('@google/gemini-cli-core', async () => {
|
|||||||
return {
|
return {
|
||||||
...actualServer,
|
...actualServer,
|
||||||
IdeClient: {
|
IdeClient: {
|
||||||
getInstance: vi.fn().mockReturnValue({
|
getInstance: vi.fn().mockResolvedValue({
|
||||||
getConnectionStatus: vi.fn(),
|
getConnectionStatus: vi.fn(),
|
||||||
initialize: vi.fn(),
|
initialize: vi.fn(),
|
||||||
shutdown: vi.fn(),
|
shutdown: vi.fn(),
|
||||||
|
|||||||
@@ -100,6 +100,16 @@ vi.mock('../services/gitService.js', () => {
|
|||||||
return { GitService: GitServiceMock };
|
return { GitService: GitServiceMock };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vi.mock('../ide/ide-client.js', () => ({
|
||||||
|
IdeClient: {
|
||||||
|
getInstance: vi.fn().mockResolvedValue({
|
||||||
|
getConnectionStatus: vi.fn(),
|
||||||
|
initialize: vi.fn(),
|
||||||
|
shutdown: vi.fn(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
describe('Server Config (config.ts)', () => {
|
describe('Server Config (config.ts)', () => {
|
||||||
const MODEL = 'gemini-pro';
|
const MODEL = 'gemini-pro';
|
||||||
const SANDBOX: SandboxConfig = {
|
const SANDBOX: SandboxConfig = {
|
||||||
|
|||||||
@@ -66,13 +66,34 @@ describe('getIdeProcessInfo', () => {
|
|||||||
it('should traverse up and find the great-grandchild of the root process', async () => {
|
it('should traverse up and find the great-grandchild of the root process', async () => {
|
||||||
(os.platform as Mock).mockReturnValue('win32');
|
(os.platform as Mock).mockReturnValue('win32');
|
||||||
const processInfoMap = new Map([
|
const processInfoMap = new Map([
|
||||||
[1000, { stdout: 'ParentProcessId=900\r\nCommandLine=node.exe\r\n' }],
|
[
|
||||||
|
1000,
|
||||||
|
{
|
||||||
|
stdout:
|
||||||
|
'{"Name":"node.exe","ParentProcessId":900,"CommandLine":"node.exe"}',
|
||||||
|
},
|
||||||
|
],
|
||||||
[
|
[
|
||||||
900,
|
900,
|
||||||
{ stdout: 'ParentProcessId=800\r\nCommandLine=powershell.exe\r\n' },
|
{
|
||||||
|
stdout:
|
||||||
|
'{"Name":"powershell.exe","ParentProcessId":800,"CommandLine":"powershell.exe"}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
800,
|
||||||
|
{
|
||||||
|
stdout:
|
||||||
|
'{"Name":"code.exe","ParentProcessId":700,"CommandLine":"code.exe"}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
700,
|
||||||
|
{
|
||||||
|
stdout:
|
||||||
|
'{"Name":"wininit.exe","ParentProcessId":0,"CommandLine":"wininit.exe"}',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
[800, { stdout: 'ParentProcessId=700\r\nCommandLine=code.exe\r\n' }],
|
|
||||||
[700, { stdout: 'ParentProcessId=0\r\nCommandLine=wininit.exe\r\n' }],
|
|
||||||
]);
|
]);
|
||||||
mockedExec.mockImplementation((command: string) => {
|
mockedExec.mockImplementation((command: string) => {
|
||||||
const pidMatch = command.match(/ProcessId=(\d+)/);
|
const pidMatch = command.match(/ProcessId=(\d+)/);
|
||||||
@@ -86,5 +107,90 @@ describe('getIdeProcessInfo', () => {
|
|||||||
const result = await getIdeProcessInfo();
|
const result = await getIdeProcessInfo();
|
||||||
expect(result).toEqual({ pid: 900, command: 'powershell.exe' });
|
expect(result).toEqual({ pid: 900, command: 'powershell.exe' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle non-existent process gracefully', async () => {
|
||||||
|
(os.platform as Mock).mockReturnValue('win32');
|
||||||
|
mockedExec
|
||||||
|
.mockResolvedValueOnce({ stdout: '' }) // Non-existent PID returns empty due to -ErrorAction SilentlyContinue
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
stdout:
|
||||||
|
'{"Name":"fallback.exe","ParentProcessId":0,"CommandLine":"fallback.exe"}',
|
||||||
|
}); // Fallback call
|
||||||
|
|
||||||
|
const result = await getIdeProcessInfo();
|
||||||
|
expect(result).toEqual({ pid: 1000, command: 'fallback.exe' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle malformed JSON output gracefully', async () => {
|
||||||
|
(os.platform as Mock).mockReturnValue('win32');
|
||||||
|
mockedExec
|
||||||
|
.mockResolvedValueOnce({ stdout: '{"invalid":json}' }) // Malformed JSON
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
stdout:
|
||||||
|
'{"Name":"fallback.exe","ParentProcessId":0,"CommandLine":"fallback.exe"}',
|
||||||
|
}); // Fallback call
|
||||||
|
|
||||||
|
const result = await getIdeProcessInfo();
|
||||||
|
expect(result).toEqual({ pid: 1000, command: 'fallback.exe' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle PowerShell errors without crashing the process chain', async () => {
|
||||||
|
(os.platform as Mock).mockReturnValue('win32');
|
||||||
|
const processInfoMap = new Map([
|
||||||
|
[1000, { stdout: '' }], // First process doesn't exist (empty due to -ErrorAction)
|
||||||
|
[
|
||||||
|
1001,
|
||||||
|
{
|
||||||
|
stdout:
|
||||||
|
'{"Name":"parent.exe","ParentProcessId":800,"CommandLine":"parent.exe"}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
800,
|
||||||
|
{
|
||||||
|
stdout:
|
||||||
|
'{"Name":"ide.exe","ParentProcessId":0,"CommandLine":"ide.exe"}',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Mock the process.pid to test traversal with missing processes
|
||||||
|
Object.defineProperty(process, 'pid', {
|
||||||
|
value: 1001,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
mockedExec.mockImplementation((command: string) => {
|
||||||
|
const pidMatch = command.match(/ProcessId=(\d+)/);
|
||||||
|
if (pidMatch) {
|
||||||
|
const pid = parseInt(pidMatch[1], 10);
|
||||||
|
return Promise.resolve(processInfoMap.get(pid) || { stdout: '' });
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error('Invalid command for mock'));
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await getIdeProcessInfo();
|
||||||
|
// Should return the current process command since traversal continues despite missing processes
|
||||||
|
expect(result).toEqual({ pid: 1001, command: 'parent.exe' });
|
||||||
|
|
||||||
|
// Reset process.pid
|
||||||
|
Object.defineProperty(process, 'pid', {
|
||||||
|
value: 1000,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle partial JSON data with defaults', async () => {
|
||||||
|
(os.platform as Mock).mockReturnValue('win32');
|
||||||
|
mockedExec
|
||||||
|
.mockResolvedValueOnce({ stdout: '{"Name":"partial.exe"}' }) // Missing ParentProcessId, defaults to 0
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
stdout:
|
||||||
|
'{"Name":"root.exe","ParentProcessId":0,"CommandLine":"root.exe"}',
|
||||||
|
}); // Get grandparent info
|
||||||
|
|
||||||
|
const result = await getIdeProcessInfo();
|
||||||
|
expect(result).toEqual({ pid: 1000, command: 'root.exe' });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,15 +26,24 @@ async function getProcessInfo(pid: number): Promise<{
|
|||||||
}> {
|
}> {
|
||||||
const platform = os.platform();
|
const platform = os.platform();
|
||||||
if (platform === 'win32') {
|
if (platform === 'win32') {
|
||||||
const command = `wmic process where "ProcessId=${pid}" get Name,ParentProcessId,CommandLine /value`;
|
const powershellCommand = [
|
||||||
const { stdout } = await execAsync(command);
|
'$p = Get-CimInstance Win32_Process',
|
||||||
const nameMatch = stdout.match(/Name=([^\n]*)/);
|
`-Filter 'ProcessId=${pid}'`,
|
||||||
const processName = nameMatch ? nameMatch[1].trim() : '';
|
'-ErrorAction SilentlyContinue;',
|
||||||
const ppidMatch = stdout.match(/ParentProcessId=(\d+)/);
|
'if ($p) {',
|
||||||
const parentPid = ppidMatch ? parseInt(ppidMatch[1], 10) : 0;
|
'@{Name=$p.Name;ParentProcessId=$p.ParentProcessId;CommandLine=$p.CommandLine}',
|
||||||
const commandLineMatch = stdout.match(/CommandLine=([^\n]*)/);
|
'| ConvertTo-Json',
|
||||||
const commandLine = commandLineMatch ? commandLineMatch[1].trim() : '';
|
'}',
|
||||||
return { parentPid, name: processName, command: commandLine };
|
].join(' ');
|
||||||
|
const { stdout } = await execAsync(`powershell "${powershellCommand}"`);
|
||||||
|
const output = stdout.trim();
|
||||||
|
if (!output) return { parentPid: 0, name: '', command: '' };
|
||||||
|
const {
|
||||||
|
Name = '',
|
||||||
|
ParentProcessId = 0,
|
||||||
|
CommandLine = '',
|
||||||
|
} = JSON.parse(output);
|
||||||
|
return { parentPid: ParentProcessId, name: Name, command: CommandLine };
|
||||||
} else {
|
} else {
|
||||||
const command = `ps -o ppid=,command= -p ${pid}`;
|
const command = `ps -o ppid=,command= -p ${pid}`;
|
||||||
const { stdout } = await execAsync(command);
|
const { stdout } = await execAsync(command);
|
||||||
|
|||||||
Reference in New Issue
Block a user