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

Tracking coverage with vimrunner #51

Open
blueyed opened this issue Oct 9, 2017 · 5 comments
Open

Tracking coverage with vimrunner #51

blueyed opened this issue Oct 9, 2017 · 5 comments

Comments

@blueyed
Copy link

blueyed commented Oct 9, 2017

I am trying to track coverage with vimrunner (via https://github.com/Vimjas/covimerage/), but the problem appears to be that it spawns a gvim instance without waiting for it.

My current attempt is to have a gvim wrapper, which I inject into the $PATH (it would be good to explicitly provide the executable btw):

#!/bin/sh

# echo "$@" >> /tmp/1l
# echo "$1" >> /tmp/1l

if [ "$1" = "--noplugin" ]; then
    echo "Running covimerage run /usr/bin/gvim $*" > /tmp/1l
    exec 1>>/tmp/1l
    exec 2>>/tmp/1l
    echo "running" >> /tmp/1l
    covimerage -vv run --profile-file /tmp/foo.profile --source "$PWD" /usr/bin/gvim -f "$@"
else
    exec /usr/bin/gvim "$@"
fi

I've tried using & and wait here, but this script is already affected by the PTY.spawn.

Any hints?

@AndrewRadev
Copy link
Owner

AndrewRadev commented Oct 10, 2017

I'll have to look into covimerage and how it works, and experiment a bit maybe. For now, I could at least give you some things to try.

For starters:

(it would be good to explicitly provide the executable btw)

It's actually possible. Here's the implementation of the Vimrunner.start_gvim method:

def self.start_gvim(&blk)
Server.new(:executable => Platform.gvim).start(&blk)
end

Basically, there's a Server, which connects to the Vim instance, and holds pids and such, and a Client, which provides wrappers around common commands. The server's start method returns a Client. You could, theoretically, run your script without PATH manipulations by:

vim = Server.new(executable: "/path/to/my-gvim").start

You could also create an existing Vim instance, and then connect to it, as long as you spawn a Vim with a particular servername. Take a look at the documentation for connect: http://www.rubydoc.info/gems/vimrunner/0.3.4/Vimrunner. Maybe you could spawn your instance, prepare it however you like, and then run Vimrunner with it?

@blueyed
Copy link
Author

blueyed commented Oct 10, 2017

Thanks!

As for executable, I am using this:

vim = Vimrunner::Server.new(:executable => Dir.getwd + "/bin/gvim").start()

This is for a Vim plugin, which has some spec helpers already (https://github.com/Vimjas/vim-python-pep8-indent/blob/master/spec/spec_helper.rb), and I can use an env var for this then.

Some findings:
even when using the "TERM" signal instead of "KILL" to kill the vimrunner server (using Process.kill("TERM", @pid)), it will result in:

Vim: Caught deadly signal HUP
Vim: Finished.

This is the case for both using xvfb-run or without (i.e. gvim being visible).
This results in covimerage (which runs rspec) to being killed directly.

I have moved/commented the @r.close and @w.close for this, otherwise the SIGHUP is send before it seems (which makes sense since the pty hung up).

When using Process.wait(@pid) and manually killing the visible gvim, I get the SIGTERM, and covimerage can handle that, i.e. proceed.

covimerage uses Python's subprocess.call.

One easy fix for this is to use remote_expr("VimrunnerEvaluateCommandOutput('quitall!')") (or a simpler version of it) in kill, then wait for the process (possibly with some timeout), falling back to TERM (instead of KILL).

blueyed added a commit to blueyed/vimrunner that referenced this issue Jul 21, 2018
The previous method of closing input/output unconditionally will cause
Vim to end with SIGHUP, which causes a wrapping process using Python's
`subprocess` module to abort:

    10342      0.000166 write(1, "Vim: Finished.\r\n", 16) = -1 EIO (Input/output error)
    10342      0.000169 rt_sigaction(SIGHUP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ff4714958f0}, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_REST>
    10342      0.000122 rt_sigprocmask(SIG_UNBLOCK, [HUP], [HUP], 8) = 0
    10342      0.000081 getpid()            = 10342
    10342      0.000058 kill(10342, SIGHUP) = 0
    10342      0.000103 --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=10342, si_uid=1000} ---

Using `:quitall!` and waiting for Vim to finish is cleaner.

This also uses SIGTERM instead of SIGKILL.

Fixes AndrewRadev#51.
@blueyed
Copy link
Author

blueyed commented Jul 21, 2018

Using Server.connect is a good method.
I've created #52 nonethess to improve the kill behavior.

@blueyed
Copy link
Author

blueyed commented Jul 21, 2018

Hmm, the problem seems to be rather that the SIGHUP is not forwarded to Vim by covimerage.

blueyed added a commit to blueyed/covimerage that referenced this issue Jul 21, 2018
This is necessary to quit Vim in case input/output is closed.

Ref: AndrewRadev/vimrunner#51 (comment)
blueyed added a commit to blueyed/covimerage that referenced this issue Jul 21, 2018
This is necessary to quit Vim in case input/output is closed.

Ref: AndrewRadev/vimrunner#51 (comment)
blueyed added a commit to blueyed/covimerage that referenced this issue Jul 21, 2018
This is necessary to quit Vim in case input/output is closed.

Ref: AndrewRadev/vimrunner#51 (comment)
blueyed added a commit to Vimjas/covimerage that referenced this issue Jul 21, 2018
This is necessary to quit Vim in case input/output is closed.

Ref: AndrewRadev/vimrunner#51 (comment)
@blueyed
Copy link
Author

blueyed commented Jul 21, 2018

Using connect requires to overwrite kill though, since it might fail with @r being nil otherwise:

  config.start_vim do
    vim = Vimrunner.connect(ENV['PYTHON_PEP8_INDENT_TEST_VIM_SERVERNAME'])
    def vim.kill
      normal(":quitall!<CR>")
    end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants