From 117d3db6d794b3b4547f1feb9742c9ab0c6b35c8 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Tue, 4 Nov 2014 15:48:18 -0300 Subject: test: Simplify/fix options_spec.lua The options_spec.lua suite has one purpose: Check if the :options commands will throw any exception(:options is implemented by $VIMRUNTIME/optwin.vim). For this it is best to use the `vim_command` API function since it will automatically catch exceptions and forward them via msgpack-rpc. Also, the option window seems to affect other tests, so call `restart` in the teardown hook. --- test/functional/legacy/options_spec.lua | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'test') diff --git a/test/functional/legacy/options_spec.lua b/test/functional/legacy/options_spec.lua index fcc39434ff..983d168609 100644 --- a/test/functional/legacy/options_spec.lua +++ b/test/functional/legacy/options_spec.lua @@ -1,20 +1,14 @@ --- Test for ":options". +-- Test if ":options" throws any exception. The options window seems to mess +-- other tests, so restart nvim in the teardown hook local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert -local execute, expect = helpers.execute, helpers.expect +local restart, command, clear = helpers.restart, helpers.command, helpers.clear describe('options', function() setup(clear) + teardown(restart) it('is working', function() - insert('result') - - execute("let caught = 'ok'") - execute('try', 'options', 'catch', 'let caught = v:throwpoint . "\n" . v:exception', 'endtry') - execute('buf 1') - execute('$put =caught') - - expect("result\nok") + command('options') end) end) -- cgit From d83868fe9071af1b4866594eac12f7aa0fa71b53 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Wed, 5 Nov 2014 13:55:53 -0300 Subject: channel: Delay notifications to avoid client race conditions It is currently possible for a client to send a response that doesn't match the current server->client request(at the top of the stack). This commit fixes that by delaying notifications to until the first `channel_send_call` invocation returns. Also remove the "call stack" size check, vim will already break if the call stack goes too deep. --- test/functional/api/server_requests_spec.lua | 56 +++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index b6f56a868c..916bdfd9f0 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -2,8 +2,10 @@ -- `rpcnotify`, to evaluate `rpcrequest` calls we need the client event loop to -- be running. local helpers = require('test.functional.helpers') -local clear, nvim, eval, eq, run, stop = helpers.clear, helpers.nvim, - helpers.eval, helpers.eq, helpers.run, helpers.stop +local clear, nvim, eval = helpers.clear, helpers.nvim, helpers.eval +local eq, run, stop = helpers.eq, helpers.run, helpers.stop +local restart = helpers.restart + describe('server -> client', function() @@ -13,6 +15,7 @@ describe('server -> client', function() clear() cid = nvim('get_api_info')[1] end) + teardown(restart) describe('simple call', function() it('works', function() @@ -65,4 +68,53 @@ describe('server -> client', function() run(on_request, nil, on_setup) end) end) + + describe('requests and notifications interleaved', function() + -- This tests that the following scenario won't happen: + -- + -- server->client [request ] (1) + -- client->server [request ] (2) triggered by (1) + -- server->client [notification] (3) triggered by (2) + -- server->client [response ] (4) response to (2) + -- client->server [request ] (4) triggered by (3) + -- server->client [request ] (5) triggered by (4) + -- client->server [response ] (6) response to (1) + -- + -- If the above scenario ever happens, the client connection will be closed + -- because (6) is returned after request (5) is sent, and nvim + -- only deals with one server->client request at a time. (In other words, + -- the client cannot send a response to a request that is not at the top + -- of nvim's request stack). + -- + -- But above scenario shoudn't happen by the way notifications are dealt in + -- Nvim: they are only sent after there are no pending server->client + -- request(the request stack fully unwinds). So (3) is only sent after the + -- client returns (6). + it('works', function() + local expected = 300 + local notified = 0 + local function on_setup() + eq('notified!', eval('rpcrequest('..cid..', "notify")')) + end + + local function on_request(method, args) + eq('notify', method) + eq(1, eval('rpcnotify('..cid..', "notification")')) + return 'notified!' + end + + local function on_notification(method, args) + eq('notification', method) + if notified == expected then + stop() + return + end + notified = notified + 1 + eq('notified', eval('rpcrequest('..cid..', "notify")')) + end + + run(on_request, on_notification, on_setup) + eq(expected, notified) + end) + end) end) -- cgit