Migrate to coreEvents/debugLogger (#12107)

This commit is contained in:
Tommaso Sciortino
2025-10-27 16:46:35 -07:00
committed by GitHub
parent e9f8ccd51a
commit 85f3a8c210
6 changed files with 173 additions and 218 deletions
+38 -62
View File
@@ -70,7 +70,7 @@ describe('oauth2', () => {
tempHomeDir = fs.mkdtempSync(
path.join(os.tmpdir(), 'gemini-cli-test-home-'),
);
(os.homedir as Mock).mockReturnValue(tempHomeDir);
vi.mocked(os.homedir).mockReturnValue(tempHomeDir);
});
afterEach(() => {
fs.rmSync(tempHomeDir, { recursive: true, force: true });
@@ -102,15 +102,15 @@ describe('oauth2', () => {
credentials: mockTokens,
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
vi.spyOn(crypto, 'randomBytes').mockReturnValue(mockState as never);
(open as Mock).mockImplementation(async () => ({ on: vi.fn() }) as never);
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
// Mock the UserInfo API response
(global.fetch as Mock).mockResolvedValue({
vi.mocked(global.fetch).mockResolvedValue({
ok: true,
json: vi
.fn()
@@ -232,9 +232,7 @@ describe('oauth2', () => {
generateCodeVerifierAsync: mockGenerateCodeVerifierAsync,
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
const mockReadline = {
question: vi.fn((_query, callback) => callback(mockCode)),
@@ -307,7 +305,7 @@ describe('oauth2', () => {
};
// To mock the new OAuth2Client() inside the function
(OAuth2Client as unknown as Mock).mockImplementation(
vi.mocked(OAuth2Client).mockImplementation(
() => mockClient as unknown as OAuth2Client,
);
@@ -387,7 +385,7 @@ describe('oauth2', () => {
getTokenInfo: vi.fn().mockResolvedValue({}),
on: vi.fn(),
};
(OAuth2Client as unknown as Mock).mockImplementation(
vi.mocked(OAuth2Client).mockImplementation(
() => mockClient as unknown as OAuth2Client,
);
@@ -411,7 +409,7 @@ describe('oauth2', () => {
getTokenInfo: vi.fn().mockResolvedValue({}),
on: vi.fn(),
};
(OAuth2Client as unknown as Mock).mockImplementation(
vi.mocked(OAuth2Client).mockImplementation(
() => mockClient as unknown as OAuth2Client,
);
@@ -483,9 +481,7 @@ describe('oauth2', () => {
getAccessToken: mockGetAccessToken,
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
// Mock the UserInfo API response for fetchAndCacheUserInfo
(global.fetch as Mock).mockResolvedValue({
@@ -543,9 +539,7 @@ describe('oauth2', () => {
getTokenInfo: mockGetTokenInfo,
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
// Make it fall through to cached credentials path
const cachedCreds = { refresh_token: 'cached-token' };
@@ -578,9 +572,7 @@ describe('oauth2', () => {
getTokenInfo: mockGetTokenInfo,
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
// Make it fall through to cached credentials path
const cachedCreds = { refresh_token: 'cached-token' };
@@ -609,9 +601,7 @@ describe('oauth2', () => {
generateAuthUrl: vi.fn().mockReturnValue('https://example.com/auth'),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
await expect(
getOauthClient(AuthType.LOGIN_WITH_GOOGLE, mockConfig),
@@ -624,11 +614,9 @@ describe('oauth2', () => {
generateAuthUrl: vi.fn().mockReturnValue(mockAuthUrl),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
(open as Mock).mockImplementation(
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
@@ -663,11 +651,9 @@ describe('oauth2', () => {
generateAuthUrl: vi.fn().mockReturnValue(mockAuthUrl),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
(open as Mock).mockImplementation(
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
@@ -722,11 +708,9 @@ describe('oauth2', () => {
generateAuthUrl: vi.fn().mockReturnValue(mockAuthUrl),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
(open as Mock).mockImplementation(
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
@@ -787,12 +771,10 @@ describe('oauth2', () => {
.mockRejectedValue(new Error('Token exchange failed')),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
vi.spyOn(crypto, 'randomBytes').mockReturnValue(mockState as never);
(open as Mock).mockImplementation(
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
@@ -858,24 +840,22 @@ describe('oauth2', () => {
.mockResolvedValue({ token: 'test-access-token' }),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
vi.spyOn(crypto, 'randomBytes').mockReturnValue(mockState as never);
(open as Mock).mockImplementation(
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
// Mock fetch to fail
(global.fetch as Mock).mockResolvedValue({
vi.mocked(global.fetch).mockResolvedValue({
ok: false,
status: 500,
statusText: 'Internal Server Error',
} as unknown as Response);
const consoleErrorSpy = vi
.spyOn(console, 'error')
const consoleLogSpy = vi
.spyOn(console, 'log')
.mockImplementation(() => {});
let requestCallback!: http.RequestListener;
@@ -894,10 +874,10 @@ describe('oauth2', () => {
close: vi.fn(),
on: vi.fn(),
address: () => ({ port: 3000 }),
};
} as unknown as http.Server;
(http.createServer as Mock).mockImplementation((cb) => {
requestCallback = cb;
return mockHttpServer as unknown as http.Server;
return mockHttpServer;
});
const clientPromise = getOauthClient(
@@ -919,13 +899,13 @@ describe('oauth2', () => {
// Authentication should succeed even if fetchAndCacheUserInfo fails
expect(client).toBe(mockOAuth2Client);
expect(consoleErrorSpy).toHaveBeenCalledWith(
expect(consoleLogSpy).toHaveBeenCalledWith(
'Failed to fetch user info:',
500,
'Internal Server Error',
);
consoleErrorSpy.mockRestore();
consoleLogSpy.mockRestore();
});
it('should handle user code authentication failure with descriptive error', async () => {
@@ -946,9 +926,7 @@ describe('oauth2', () => {
.mockRejectedValue(new Error('Invalid authorization code')),
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
const mockReadline = {
question: vi.fn((_query, callback) => callback('invalid-code')),
@@ -1028,9 +1006,7 @@ describe('oauth2', () => {
getTokenInfo: mockGetTokenInfo,
on: vi.fn(),
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
// Pre-populate credentials to make getOauthClient resolve quickly
const credsPath = path.join(
@@ -1112,12 +1088,12 @@ describe('oauth2', () => {
on: mockOn,
credentials: mockTokens,
} as unknown as OAuth2Client;
(OAuth2Client as unknown as Mock).mockImplementation(
() => mockOAuth2Client,
);
vi.mocked(OAuth2Client).mockImplementation(() => mockOAuth2Client);
vi.spyOn(crypto, 'randomBytes').mockReturnValue(mockState as never);
(open as Mock).mockImplementation(async () => ({ on: vi.fn() }) as never);
vi.mocked(open).mockImplementation(
async () => ({ on: vi.fn() }) as never,
);
(global.fetch as Mock).mockResolvedValue({
ok: true,
@@ -1203,7 +1179,7 @@ describe('oauth2', () => {
on: vi.fn(),
};
(OAuth2Client as unknown as Mock).mockImplementation(
vi.mocked(OAuth2Client).mockImplementation(
() => mockClient as unknown as OAuth2Client,
);
+13 -13
View File
@@ -185,7 +185,7 @@ async function initOauthClient(
for (let i = 0; !success && i < maxRetries; i++) {
success = await authWithUserCode(client);
if (!success) {
console.error(
debugLogger.error(
'\nFailed to authenticate with user code.',
i === maxRetries - 1 ? '' : 'Retrying...\n',
);
@@ -215,17 +215,17 @@ async function initOauthClient(
// in a minimal Docker container), it will emit an unhandled 'error' event,
// causing the entire Node.js process to crash.
childProcess.on('error', (error) => {
console.error(
'Failed to open browser automatically. Please try running again with NO_BROWSER=true set.',
debugLogger.error(
`Failed to open browser with error:`,
getErrorMessage(error),
`\nPlease try running again with NO_BROWSER=true set.`,
);
console.error('Browser error details:', getErrorMessage(error));
});
} catch (err) {
console.error(
'An unexpected error occurred while trying to open the browser:',
debugLogger.error(
`Failed to open browser with error:`,
getErrorMessage(err),
'\nThis might be due to browser compatibility issues or system configuration.',
'\nPlease try running again with NO_BROWSER=true set for manual authentication.',
`\nPlease try running again with NO_BROWSER=true set.`,
);
throw new FatalAuthenticationError(
`Failed to open browser: ${getErrorMessage(err)}`,
@@ -293,7 +293,7 @@ async function authWithUserCode(client: OAuth2Client): Promise<boolean> {
});
if (!code) {
console.error('Authorization code is required.');
debugLogger.error('Authorization code is required.');
return false;
}
@@ -305,7 +305,7 @@ async function authWithUserCode(client: OAuth2Client): Promise<boolean> {
});
client.setCredentials(tokens);
} catch (error) {
console.error(
debugLogger.error(
'Failed to authenticate with authorization code:',
getErrorMessage(error),
);
@@ -528,7 +528,7 @@ export async function clearCachedCredentialFile() {
// Clear the in-memory OAuth client cache to force re-authentication
clearOauthClientCache();
} catch (e) {
console.error('Failed to clear cached credentials:', e);
debugLogger.warn('Failed to clear cached credentials:', e);
}
}
@@ -549,7 +549,7 @@ async function fetchAndCacheUserInfo(client: OAuth2Client): Promise<void> {
);
if (!response.ok) {
console.error(
debugLogger.log(
'Failed to fetch user info:',
response.status,
response.statusText,
@@ -560,7 +560,7 @@ async function fetchAndCacheUserInfo(client: OAuth2Client): Promise<void> {
const userInfo = await response.json();
await userAccountManager.cacheGoogleAccount(userInfo.email);
} catch (error) {
console.error('Error retrieving user info:', error);
debugLogger.log('Error retrieving user info:', error);
}
}