Skip to content

Commit

Permalink
test(transport): high-traffic RPC
Browse files Browse the repository at this point in the history
Problem:
In
vscode-neovim/vscode-neovim#2184 (comment)
it was reported that "Github Copilot Chat opens MANY buffers while
writing code, and that somehow breaks the vscode-neovim extension".

Solution:
- Add test coverage for high amounts of RPC traffic.
- TODO: this doesn't cover complex scenarios such as a looping
  `OptionSet` handler.
  • Loading branch information
justinmk committed Oct 17, 2024
1 parent 3775c8d commit 3ce33d9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/neovim/src/api/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export class BaseApi extends EventEmitter {
});
}

/** Sends a request to Nvim (the peer). */
request(name: string, args: any[] = []): Promise<any> {
return this.asyncRequest(name, args);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/neovim/src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class NeovimClient extends Neovim {
return this.attachedBuffers.has(key);
}

/** Handles incoming request (from the peer). */
handleRequest(
method: string,
args: VimValue[],
Expand All @@ -85,6 +86,7 @@ export class NeovimClient extends Neovim {
}
}

/** Publishes to (local) subscribers of this `EventEmitter`. */
emitNotification(method: string, args: any[]) {
if (method.endsWith('_event')) {
if (!method.startsWith('nvim_buf_')) {
Expand Down Expand Up @@ -114,6 +116,7 @@ export class NeovimClient extends Neovim {
}
}

/** Handles incoming notification (from the peer). */
handleNotification(method: string, args: VimValue[], ...restArgs: any[]) {
this.logger.info('handleNotification: %s', method);
// If neovim API is not generated yet then queue up requests
Expand Down
51 changes: 39 additions & 12 deletions packages/neovim/src/attach/attach.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,33 @@ describe('Nvim API', () => {
let proc: ReturnType<typeof testUtil.startNvim>[0];
let nvim: ReturnType<typeof testUtil.startNvim>[1];

/** Incoming requests (from Nvim). */
const requests: { method: string; args: number[] }[] = [];
/** Incoming notifications (from Nvim). */
const notifications: { method: string; args: number[] }[] = [];

before(async () => {
[proc, nvim] = testUtil.startNvim();
});

after(() => {
testUtil.stopNvim();
});

let requests: { method: string; args: number[] }[];
let notifications: { method: string; args: number[] }[];

before(async () => {
// Incoming requests (from Nvim).
nvim.on('request', (method, args, resp) => {
requests.push({ method, args });
resp.send(`received ${method}(${args})`);
});

// Incoming notifications (from Nvim).
nvim.on('notification', (method, args) => {
notifications.push({ method, args });
});
});

after(() => {
testUtil.stopNvim();
});

beforeEach(() => {
requests = [];
notifications = [];
requests.length = 0;
notifications.length = 0;
});

it('failure modes', async () => {
Expand Down Expand Up @@ -101,6 +104,30 @@ describe('Nvim API', () => {
testUtil.stopNvim(nvim2);
});

it('noisy RPC traffic', async () => {
let requestCount = 0;
const oldRequest = nvim.request;
nvim.request = function (
this: any,
name: string,
args: any[] = []
): Promise<any> {
requestCount = requestCount + 1;
return oldRequest.call(this, name, args);
};

for (let i = 0; i < 99; i = i + 1) {
nvim.command('noswapfile edit test-node-client.lua');
nvim.command('bwipeout!');
}

expect(requestCount).toEqual(99 * 2);
// Still alive?
expect(await nvim.eval('1+1')).toEqual(2);

nvim.request = oldRequest;
});

it('can send requests and receive response', async () => {
const result = await nvim.eval('{"k1": "v1", "k2": 2}');
expect(result).toEqual({ k1: 'v1', k2: 2 });
Expand Down Expand Up @@ -149,7 +176,7 @@ describe('Nvim API', () => {
end: -1,
strictIndexing: true,
});
expect(lines).toEqual([]);
expect(lines).toEqual(['']);

buf.setLines(['line1', 'line2'], { start: 0, end: 1 });
const newLines = await buf.getLines({
Expand Down

0 comments on commit 3ce33d9

Please sign in to comment.