Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix debug response, rearrange tests #165879

Merged
merged 2 commits into from Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
114 changes: 56 additions & 58 deletions src/vs/workbench/contrib/debug/browser/rawDebugSession.ts
Expand Up @@ -621,73 +621,71 @@ export class RawDebugSession implements IDisposable {

const safeSendResponse = (response: DebugProtocol.Response) => this.debugAdapter && this.debugAdapter.sendResponse(response);

switch (request.command) {
case 'launchVSCode':
try {
let result = await this.launchVsCode(<ILaunchVSCodeArguments>request.arguments);
if (!result.success) {
const showResult = await this.dialogSerivce.show(Severity.Warning, nls.localize('canNotStart', "The debugger needs to open a new tab or window for the debuggee but the browser prevented this. You must give permission to continue."),
[nls.localize('continue', "Continue"), nls.localize('cancel', "Cancel")], { cancelId: 1 });
if (showResult.choice === 0) {
result = await this.launchVsCode(<ILaunchVSCodeArguments>request.arguments);
} else {
response.success = false;
safeSendResponse(response);
await this.shutdown();
}
if (request.command === 'launchVSCode') {
try {
let result = await this.launchVsCode(<ILaunchVSCodeArguments>request.arguments);
if (!result.success) {
const showResult = await this.dialogSerivce.show(Severity.Warning, nls.localize('canNotStart', "The debugger needs to open a new tab or window for the debuggee but the browser prevented this. You must give permission to continue."),
[nls.localize('continue', "Continue"), nls.localize('cancel', "Cancel")], { cancelId: 1 });
if (showResult.choice === 0) {
result = await this.launchVsCode(<ILaunchVSCodeArguments>request.arguments);
} else {
response.success = false;
safeSendResponse(response);
await this.shutdown();
}
response.body = {
rendererDebugPort: result.rendererDebugPort,
};
safeSendResponse(response);
} catch (err) {
response.success = false;
response.message = err.message;
safeSendResponse(response);
}
break;
case 'runInTerminal':
try {
const shellProcessId = await this.dbgr.runInTerminal(request.arguments as DebugProtocol.RunInTerminalRequestArguments, this.sessionId);
const resp = response as DebugProtocol.RunInTerminalResponse;
resp.body = {};
if (typeof shellProcessId === 'number') {
resp.body.shellProcessId = shellProcessId;
}
safeSendResponse(resp);
} catch (err) {
response.success = false;
response.message = err.message;
safeSendResponse(response);
response.body = {
rendererDebugPort: result.rendererDebugPort,
};
safeSendResponse(response);
} catch (err) {
response.success = false;
response.message = err.message;
safeSendResponse(response);
}
} else if (request.command === 'runInTerminal') {
try {
const shellProcessId = await this.dbgr.runInTerminal(request.arguments as DebugProtocol.RunInTerminalRequestArguments, this.sessionId);
const resp = response as DebugProtocol.RunInTerminalResponse;
resp.body = {};
if (typeof shellProcessId === 'number') {
resp.body.shellProcessId = shellProcessId;
}
break;
case 'startDebugging':
try {
const args = (request.arguments as DebugProtocol.StartDebuggingRequestArguments);
const config: IConfig = {
...args.configuration,
...{
request: args.request,
type: this.dbgr.type,
name: this.name
}
};
const success = await this.dbgr.startDebugging(config, this.sessionId);
if (!success) {
response.success = false;
response.message = 'Failed to start debugging';
safeSendResponse(response);
safeSendResponse(resp);
} catch (err) {
response.success = false;
response.message = err.message;
safeSendResponse(response);
}
} else if (request.command === 'startDebugging') {
try {
const args = (request.arguments as DebugProtocol.StartDebuggingRequestArguments);
const config: IConfig = {
...args.configuration,
...{
request: args.request,
type: this.dbgr.type,
name: this.name
}
} catch (err) {
};
const success = await this.dbgr.startDebugging(config, this.sessionId);
if (success) {
safeSendResponse(response);
} else {
response.success = false;
response.message = err.message;
response.message = 'Failed to start debugging';
safeSendResponse(response);
}
default:
} catch (err) {
response.success = false;
response.message = `unknown request '${request.command}'`;
response.message = err.message;
safeSendResponse(response);
break;
}
} else {
response.success = false;
response.message = `unknown request '${request.command}'`;
safeSendResponse(response);
}
}

Expand Down
Expand Up @@ -15,8 +15,9 @@ import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callS
import { isStatusbarInDebugMode } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider';
import { State } from 'vs/workbench/contrib/debug/common/debug';
import { isWindows } from 'vs/base/common/platform';
import { MockSession, createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';
const $ = dom.$;

suite('Debug - Base Debug View', () => {
Expand Down
Expand Up @@ -15,10 +15,11 @@ import { OverviewRulerLane } from 'vs/editor/common/model';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { createTextModel } from 'vs/editor/test/common/testTextModel';
import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
import { createMockDebugModel, MockDebugService } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { ILanguageService } from 'vs/editor/common/languages/language';
import { LanguageService } from 'vs/editor/common/services/languageService';
import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';
import { MockDebugService } from 'vs/workbench/contrib/debug/test/common/mockDebug';

function addBreakpointsAndCheckEvents(model: DebugModel, uri: uri, data: IBreakpointData[]): void {
let eventCount = 0;
Expand Down
17 changes: 9 additions & 8 deletions src/vs/workbench/contrib/debug/test/browser/callStack.test.ts
Expand Up @@ -6,7 +6,7 @@
import * as assert from 'assert';
import { DebugModel, StackFrame, Thread } from 'vs/workbench/contrib/debug/common/debugModel';
import * as sinon from 'sinon';
import { MockRawSession, createMockDebugModel, mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { createMockDebugModel, mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import { DebugSession } from 'vs/workbench/contrib/debug/browser/debugSession';
import { Range } from 'vs/editor/common/core/range';
Expand All @@ -20,6 +20,7 @@ import { debugStackframe, debugStackframeFocused } from 'vs/workbench/contrib/de
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { MockRawSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';

const mockWorkspaceContextService = {
getWorkspace: () => {
Expand Down Expand Up @@ -67,11 +68,11 @@ function createTwoStackFrames(session: DebugSession): { firstStackFrame: StackFr

suite('Debug - CallStack', () => {
let model: DebugModel;
let rawSession: MockRawSession;
let mockRawSession: MockRawSession;

setup(() => {
model = createMockDebugModel();
rawSession = new MockRawSession();
mockRawSession = new MockRawSession();
});

// Threads
Expand Down Expand Up @@ -109,7 +110,7 @@ suite('Debug - CallStack', () => {
const session = createTestSession(model);
model.addSession(session);

session['raw'] = <any>rawSession;
session['raw'] = <any>mockRawSession;

model.rawUpdate({
sessionId: session.getId(),
Expand Down Expand Up @@ -189,7 +190,7 @@ suite('Debug - CallStack', () => {
const session = createTestSession(model);
model.addSession(session);

session['raw'] = <any>rawSession;
session['raw'] = <any>mockRawSession;

// Stopped event with all threads stopped
model.rawUpdate({
Expand Down Expand Up @@ -232,7 +233,7 @@ suite('Debug - CallStack', () => {
});

test('threads multiple without allThreadsStopped', async () => {
const sessionStub = sinon.spy(rawSession, 'stackTrace');
const sessionStub = sinon.spy(mockRawSession, 'stackTrace');

const stoppedThreadId = 1;
const stoppedThreadName = 'stoppedThread';
Expand All @@ -242,7 +243,7 @@ suite('Debug - CallStack', () => {
const session = createTestSession(model);
model.addSession(session);

session['raw'] = <any>rawSession;
session['raw'] = <any>mockRawSession;

// Add the threads
model.rawUpdate({
Expand Down Expand Up @@ -435,7 +436,7 @@ suite('Debug - CallStack', () => {
model.addSession(runningSession);
model.addSession(session);

session['raw'] = <any>rawSession;
session['raw'] = <any>mockRawSession;

model.rawUpdate({
sessionId: session.getId(),
Expand Down
Expand Up @@ -15,9 +15,9 @@ import { TestThemeService, TestColorTheme } from 'vs/platform/theme/test/common/
import { ansiColorMap } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
import { DebugModel } from 'vs/workbench/contrib/debug/common/debugModel';
import { DebugSession } from 'vs/workbench/contrib/debug/browser/debugSession';
import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';

suite('Debug - ANSI Handling', () => {

Expand Down
Expand Up @@ -9,7 +9,7 @@ import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callS
import { StackFrame, Thread, Scope, Variable } from 'vs/workbench/contrib/debug/common/debugModel';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import type { IScope, IExpression } from 'vs/workbench/contrib/debug/common/debug';
import { createMockDebugModel, mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { createMockDebugModel, mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';

suite('Debug - Hover', () => {
test('find expression in stack frame', async () => {
Expand Down
Expand Up @@ -9,7 +9,7 @@ import { Emitter } from 'vs/base/common/event';
import { mockObject, MockObject } from 'vs/base/test/common/mock';
import { MemoryRangeType } from 'vs/workbench/contrib/debug/common/debug';
import { MemoryRegion } from 'vs/workbench/contrib/debug/common/debugModel';
import { MockSession } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';

suite('Debug - Memory', () => {
const dapResponseCommon = {
Expand Down
Expand Up @@ -7,7 +7,7 @@ import * as assert from 'assert';
import { URI as uri } from 'vs/base/common/uri';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import { isWindows } from 'vs/base/common/platform';
import { mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';

suite('Debug - Source', () => {

Expand Down
Expand Up @@ -6,9 +6,10 @@
import * as assert from 'assert';
import { ViewModel } from 'vs/workbench/contrib/debug/common/debugViewModel';
import { StackFrame, Expression, Thread } from 'vs/workbench/contrib/debug/common/debugModel';
import { MockSession, mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { mockUriIdentityService } from 'vs/workbench/contrib/debug/test/browser/mockDebugModel';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import { MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';

suite('Debug - View Model', () => {
let model: ViewModel;
Expand Down
16 changes: 16 additions & 0 deletions src/vs/workbench/contrib/debug/test/browser/mockDebugModel.ts
@@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService';
import { DebugModel } from 'vs/workbench/contrib/debug/common/debugModel';
import { MockDebugStorage } from 'vs/workbench/contrib/debug/test/common/mockDebug';
import { TestFileService } from 'vs/workbench/test/browser/workbenchTestServices';

const fileService = new TestFileService();
export const mockUriIdentityService = new UriIdentityService(fileService);

export function createMockDebugModel(): DebugModel {
return new DebugModel(new MockDebugStorage(), <any>{ isDirty: (e: any) => false }, mockUriIdentityService);
}
86 changes: 49 additions & 37 deletions src/vs/workbench/contrib/debug/test/browser/rawDebugSession.test.ts
Expand Up @@ -4,49 +4,61 @@
*--------------------------------------------------------------------------------------------*/

import * as assert from 'assert';
import { MockDebugAdapter } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
import { timeout } from 'vs/base/common/async';
import { mock, mockObject } from 'vs/base/test/common/mock';
import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { RawDebugSession } from 'vs/workbench/contrib/debug/browser/rawDebugSession';
import { IDebugger } from 'vs/workbench/contrib/debug/common/debug';
import { MockDebugAdapter } from 'vs/workbench/contrib/debug/test/common/mockDebug';

suite('Debug - AbstractDebugAdapter', () => {
suite('event ordering', () => {
let adapter: MockDebugAdapter;
let output: string[];
setup(() => {
adapter = new MockDebugAdapter();
output = [];
adapter.onEvent(ev => {
output.push((ev as DebugProtocol.OutputEvent).body.output);
Promise.resolve().then(() => output.push('--end microtask--'));
});
suite('RawDebugSession', () => {
function createTestObjects() {
const debugAdapter = new MockDebugAdapter();
const dbgr = mockObject<IDebugger>()({
type: 'mock-debug'
});

const evaluate = async (expression: string) => {
await new Promise(resolve => adapter.sendRequest('evaluate', { expression }, resolve));
output.push(`=${expression}`);
Promise.resolve().then(() => output.push('--end microtask--'));
};
new RawDebugSession(
debugAdapter,
dbgr as any as IDebugger,
'sessionId',
'name',
new (mock<IExtensionHostDebugService>()),
new (mock<IOpenerService>()),
new (mock<INotificationService>()),
new (mock<IDialogService>()));
return { debugAdapter, dbgr };
}

test('inserts task boundary before response', async () => {
await evaluate('before.foo');
await timeout(0);
test('handles startDebugging request success', async () => {
const { debugAdapter, dbgr } = createTestObjects();
dbgr.startDebugging.returns(Promise.resolve(true));

assert.deepStrictEqual(output, ['before.foo', '--end microtask--', '=before.foo', '--end microtask--']);
});

test('inserts task boundary after response', async () => {
await evaluate('after.foo');
await timeout(0);

assert.deepStrictEqual(output, ['=after.foo', '--end microtask--', 'after.foo', '--end microtask--']);
});
debugAdapter.sendRequestBody('startDebugging', {
request: 'launch',
configuration: {
type: 'some-other-type'
}
} as DebugProtocol.StartDebuggingRequestArguments);
const response = await debugAdapter.waitForResponseFromClient('startDebugging');
assert.strictEqual(response.command, 'startDebugging');
assert.strictEqual(response.success, true);
});

test('does not insert boundaries between events', async () => {
adapter.sendEventBody('output', { output: 'a' });
adapter.sendEventBody('output', { output: 'b' });
adapter.sendEventBody('output', { output: 'c' });
await timeout(0);
test('handles startDebugging request failure', async () => {
const { debugAdapter, dbgr } = createTestObjects();
dbgr.startDebugging.returns(Promise.resolve(false));

assert.deepStrictEqual(output, ['a', 'b', 'c', '--end microtask--', '--end microtask--', '--end microtask--']);
});
debugAdapter.sendRequestBody('startDebugging', {
request: 'launch',
configuration: {
type: 'some-other-type'
}
} as DebugProtocol.StartDebuggingRequestArguments);
const response = await debugAdapter.waitForResponseFromClient('startDebugging');
assert.strictEqual(response.command, 'startDebugging');
assert.strictEqual(response.success, false);
});
});