From 4f65a7654253e965fdbd0d3ac724b2751aea3751 Mon Sep 17 00:00:00 2001 From: Holger Rapp Date: Fri, 3 Jul 2015 21:52:50 +0200 Subject: [PATCH] Fix testing and test against more scenarios. Before this, we only ever ran against system python preinstalled on travis (i.e. 2.7 and 3.2). This change makes sure that Vim is always build and run against the correct python version in the virtual env. Also adds mercurial (HEAD) Vim as a testing target. This patch took me forever to get right. At least 2 months and ~200 travis runs of trial and error - there is just too much finicky going on with the many virtual envs on travis, Vims strange build system that does not use python-config and LD_LIBRARY_PATH loading. En plus, the debugging insights one can glance from travis runs are rather limited. Detailed changes: - Uses less sudo and only outside of scripts. - Build correct version of Vim against correct version of Python. This needs some LD_LIBRARY_PATH magic to make sure that Vim finds the correct Python libraries at runtime. - Removes dirty hack that overwrote /usr/bin/vim with the correct Vim version to run. The test_all.py script now takes the Vim binary as a parameter. --- .travis.yml | 20 +++++++++--- install_vim.sh | 71 ------------------------------------------- test/vim_interface.py | 24 +++++---------- test_all.py | 4 ++- travis_install.sh | 67 ++++++++++++++++++++++++++++++++++++++++ travis_test.sh | 27 ++++++++++++++++ 6 files changed, 121 insertions(+), 92 deletions(-) delete mode 100755 install_vim.sh create mode 100644 travis_install.sh create mode 100644 travis_test.sh diff --git a/.travis.yml b/.travis.yml index 9505329..85051a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,26 @@ language: python python: - 2.7 + - 3.2 - 3.3 - 3.4 env: - VIM_VERSION="74" + - VIM_VERSION="mercurial" + # - VIM_VERSION="NEOVIM" -install: sudo ./install_vim.sh "${VIM_VERSION}" "$(python --version 2>&1)" +matrix: + allow_failures: + # TODO(sirver): Neovim does not play well with our testing right now. + - env: VIM_VERSION="NEOVIM" -before_script: - - tmux new -d -s vim +install: + # Some of these commands fail transiently. We keep retrying them until they succeed. + - until sudo add-apt-repository ppa:kalakris/tmux -y; do sleep 10; done + - until sudo add-apt-repository ppa:neovim-ppa/unstable -y; do sleep 10; done + - until sudo apt-get update -qq; do sleep 10; done + - until sudo apt-get install -qq -y --force-yes tmux xclip gdb neovim mercurial; do sleep 10; done + - ./travis_install.sh -script: ./test_all.py -v --plugins --session vim +script: + - ./travis_test.sh diff --git a/install_vim.sh b/install_vim.sh deleted file mode 100755 index ffccac5..0000000 --- a/install_vim.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash - -# Installs a known version of vim in the travis test runner. -set -ex - -VIM_VERSION=$1; shift -PYTHON_VERSION=$1; shift - -build_vanilla_vim () { - URL=$1; shift; - - mkdir vim_build - pushd vim_build - - curl $URL -o vim.tar.bz2 - tar xjf vim.tar.bz2 - cd vim${VIM_VERSION} - - PYTHON_BUILD_CONFIG="" - if [[ $PYTHON_VERSION =~ "Python 2." ]]; then - PYTHON_BUILD_CONFIG="--enable-pythoninterp" - else - PYTHON_BUILD_CONFIG="--enable-python3interp" - fi - ./configure \ - --prefix=${HOME} \ - --disable-nls \ - --disable-sysmouse \ - --disable-gpm \ - --enable-gui=no \ - --enable-multibyte \ - --with-features=huge \ - --with-tlib=ncurses \ - --without-x \ - ${PYTHON_BUILD_CONFIG} - - make install - popd - - rm -rf vim_build -} - -repeat_transiently_failing_command () { - COMMAND=$1; shift - - set +e - until ${COMMAND}; do - sleep 10 - done - set -e -} - -# Install tmux (> 1.8) and vim. -repeat_transiently_failing_command "add-apt-repository ppa:kalakris/tmux -y" -repeat_transiently_failing_command "apt-get update -qq" -repeat_transiently_failing_command "apt-get install -qq -y tmux" - -if [[ $VIM_VERSION == "74" ]]; then - build_vanilla_vim ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2 -else - echo "Unknown VIM_VERSION: $VIM_VERSION" - exit 1 -fi - -# Dirty hack, since PATH seems to be ignored. -ln -sf /home/travis/bin/vim /usr/bin/vim - -vim --version - -# Clone the dependent plugins we want to use. -./test_all.py --clone-plugins diff --git a/test/vim_interface.py b/test/vim_interface.py index 8e3da81..f9046fe 100644 --- a/test/vim_interface.py +++ b/test/vim_interface.py @@ -9,7 +9,7 @@ import textwrap import time from test.constant import (ARR_D, ARR_L, ARR_R, ARR_U, BS, ESC, PYTHON3, - SEQUENCES) + SEQUENCES) def wait_until_file_exists(file_path, times=None, interval=0.01): @@ -88,8 +88,9 @@ class TempFileManager(object): class VimInterface(TempFileManager): - def __init__(self, name=''): + def __init__(self, vim_executable, name): TempFileManager.__init__(self, name) + self._vim_executable = vim_executable def get_buffer_data(self): buffer_path = self.unique_name_temp(prefix='buffer_') @@ -121,7 +122,7 @@ class VimInterface(TempFileManager): textwrap.dedent(os.linesep.join(config + post_config) + '\n')) # Note the space to exclude it from shell history. - self.send(""" vim -u %s\r\n""" % config_path) + self.send(""" %s -u %s\r\n""" % (self._vim_executable, config_path)) wait_until_file_exists(done_file) self._vim_pid = int(open(pid_file, 'r').read()) @@ -133,8 +134,8 @@ class VimInterface(TempFileManager): class VimInterfaceTmux(VimInterface): - def __init__(self, session): - VimInterface.__init__(self, 'Tmux') + def __init__(self, vim_executable, session): + VimInterface.__init__(self, vim_executable, 'Tmux') self.session = session self._check_version() @@ -181,7 +182,6 @@ class VimInterfaceWindows(VimInterface): ] def __init__(self): - self.seq_buf = [] # import windows specific modules import win32com.client import win32gui @@ -209,15 +209,7 @@ class VimInterfaceWindows(VimInterface): return keys def send(self, keys): - self.seq_buf.append(keys) - seq = ''.join(self.seq_buf) - - for f in SEQUENCES: - if f.startswith(seq) and f != seq: - return - self.seq_buf = [] - - seq = self.convert_keys(seq) + keys = self.convert_keys(keys) if not self.is_focused(): time.sleep(2) @@ -226,4 +218,4 @@ class VimInterfaceWindows(VimInterface): # This is the only way I can find to stop test execution raise KeyboardInterrupt('Failed to focus GVIM') - self.shell.SendKeys(seq) + self.shell.SendKeys(keys) diff --git a/test_all.py b/test_all.py index 1ddf51a..9ace0f4 100755 --- a/test_all.py +++ b/test_all.py @@ -100,6 +100,8 @@ if __name__ == '__main__': 'multiplexer and race conditions in writing to the file system.') p.add_option('-x', '--exitfirst', dest='exitfirst', action='store_true', help='exit instantly on first error or failed test.') + p.add_option('--vim', dest='vim', type=str, default="vim", + help='executable to run when launching vim.') o, args = p.parse_args() return o, args @@ -118,7 +120,7 @@ if __name__ == '__main__': all_test_suites = unittest.defaultTestLoader.discover(start_dir='test') - vim = VimInterfaceTmux(options.session) + vim = VimInterfaceTmux(options.vim, options.session) if not options.clone_plugins and platform.system() == 'Windows': raise RuntimeError( 'TODO: TestSuite is broken under windows. Volunteers wanted!.') diff --git a/travis_install.sh b/travis_install.sh new file mode 100644 index 0000000..2287075 --- /dev/null +++ b/travis_install.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Installs a known version of vim in the travis test runner. + +set -ex + +PYTHON="python${TRAVIS_PYTHON_VERSION}" + +build_vanilla_vim () { + mkdir ~/vim_build + pushd ~/vim_build + + if [[ $VIM_VERSION == "74" ]]; then + until curl ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2 -o vim.tar.bz2; do sleep 10; done + tar xjf vim.tar.bz2 + cd vim${VIM_VERSION} + elif [[ $VIM_VERSION == "mercurial" ]]; then + hg clone https://vim.googlecode.com/hg/ vim + cd vim + fi + + local PYTHON_CONFIG_DIR=$(dirname $(find $($PYTHON-config --prefix)/lib -iname 'config.c') | grep $TRAVIS_PYTHON_VERSION) + local PYTHON_BUILD_CONFIG="" + if [[ $TRAVIS_PYTHON_VERSION =~ ^2\. ]]; then + PYTHON_BUILD_CONFIG="--enable-pythoninterp --with-python-config-dir=${PYTHON_CONFIG_DIR}" + else + PYTHON_BUILD_CONFIG="--enable-python3interp --with-python3-config-dir=${PYTHON_CONFIG_DIR}" + fi + export LDFLAGS="$($PYTHON-config --ldflags) -L$($PYTHON-config --prefix)/lib" + export CFLAGS="$($PYTHON-config --cflags)" + + # This is needed so that vim finds the shared libraries it was build against + # - they are not on the regular path. + export LD_LIBRARY_PATH="$($PYTHON-config --prefix)/lib" + + echo $LDFLAGS + echo $CFLAGS + ./configure \ + --prefix=${HOME} \ + --disable-nls \ + --disable-sysmouse \ + --disable-gpm \ + --enable-gui=no \ + --enable-multibyte \ + --with-features=huge \ + --with-tlib=ncurses \ + --without-x \ + ${PYTHON_BUILD_CONFIG} || cat $(find . -name 'config.log') + + make install + popd + + rm -rf vim_build +} + +if [[ $VIM_VERSION = "74" || $VIM_VERSION = "mercurial" ]]; then + build_vanilla_vim +elif [[ $VIM_VERSION == "NEOVIM" ]]; then + pip install neovim +else + echo "Unknown VIM_VERSION: $VIM_VERSION" + exit 1 +fi + +# Clone the dependent plugins we want to use. +PYTHON_CMD="$(which $PYTHON)" +$PYTHON_CMD ./test_all.py --clone-plugins diff --git a/travis_test.sh b/travis_test.sh new file mode 100644 index 0000000..47fee9f --- /dev/null +++ b/travis_test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -ex + +VIM="${HOME}/bin/vim" +PYTHON="python${TRAVIS_PYTHON_VERSION}" +PYTHON_CMD="$(which ${PYTHON})" + +# This is needed so that vim finds the shared libraries it was build against - +# they are not on the regular path. +export LD_LIBRARY_PATH="$($PYTHON-config --prefix)/lib" + +if [[ $TRAVIS_PYTHON_VERSION =~ ^2\. ]]; then + PY_IN_VIM="py" +else + PY_IN_VIM="py3" +fi + +echo "Using python from: $PYTHON_CMD Version: $($PYTHON_CMD --version 2>&1)" +echo "Using vim from: $VIM. Version: $($VIMn)" + +printf "${PY_IN_VIM} import sys;print(sys.version);\nquit" | $VIM -e -V9myVimLog +cat myVimLog + +tmux new -d -s vim + +$PYTHON_CMD ./test_all.py -v --plugins --session vim --vim $VIM