Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tweekmonster committed Feb 18, 2016
0 parents commit 1e97840
Show file tree
Hide file tree
Showing 15 changed files with 346 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/example/test/plugins
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sudo: required

services:
- docker

before_install:
- cd example && make setup-test

script:
- cd example && make test
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM alpine:3.3

RUN apk --update add bash
RUN adduser -h /home -s /bin/bash -D -u 8465 vimtest

RUN mkdir -p /vim /vim-build/bin /plugins
RUN chown vimtest:vimtest /home /plugins

ADD scripts/argecho.sh /vim-build/bin/argecho
ADD scripts/install_vim.sh /sbin/install_vim
ADD scripts/run_vim.sh /sbin/run_vim

RUN chmod +x /vim-build/bin/argecho /sbin/install_vim /sbin/run_vim

ADD scripts/rtp.vim /rtp.vim

# The user directory for setup
VOLUME /home

# Your plugin
VOLUME /testplugin

ENTRYPOINT ["/sbin/run_vim"]
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.PHONY: build


build:
docker build -t "tweekmonster/vim-testbed" .
103 changes: 103 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Vim Testbed

Because unit testing a Vim plugin is a pain in the ass.

[vader.vim](https://github.com/junegunn/vader.vim) provides a pretty
straightforward way to test Vim plugins. But, you'll only be testing on the
version of Vim you have installed. Then there's the issue of running automated
tests with Travis-CI where you have to either:

- Build Vim from source which takes an eternity, then run your tests.
- Use the version that came with Ubuntu 12.04 which means you're only testing
your plugin's ability to run on 7.3.429.

With this base image, you can build the versions you need and reuse them in
future tests.


## Usage

The README is a work in progress. Take a look in the `example` directory.

You will need to create your own Dockerfile, build an image, then push it to
your [Docker Hub](https://hub.docker.com/) repository.

### Dockerfile

```Dockerfile
FROM tweekmonster/vim-testbed:latest

RUN install_vim -tag v7.3 -name vim73 -build \
-tag v7.4.052 -name vim74 -build \
-tag master -build
```

The `install_vim` script builds one or more versions of Vim that you would like
to use for testing. Each version should be terminated with a `-build` flag to
tell the script to start a build.

The following flags can be used for each build:

Flag | Description
---- | -----------
`-tag` | The Vim release. It must match the tags on Vim's [releases page](https://github.com/vim/vim/releases).
`-name` | The name to use for the binary's symlink. If omitted, the name will default to `vim-$TAG`.
`-py` | Build with Python 2. Can't be used with `-py3`.
`-py3` | Build with Python 3. Can't be used with `-py`.
`-ruby` | Build with Ruby.
`-lua` | Build with Lua.


### Build

```shell
docker build -t "your/repository" .
```

From here you can run your tests locally (as described below), push it to your
Docker Hub repository, or setup an [automated build](https://docs.docker.com/docker-hub/builds/).

### Run

```shell
docker run -it --rm -v $(PWD):/testplugin -v $(PWD)/test:/home "your/repository" vim74 '+Vader! test/*'
```

The entry point for the container is a script that runs the named Vim version.
In this case `vim74`. Arguments after the name is passed to Vim.

The entry point script prefixes your arguments with `-u /home/vimrc -i NONE`.
They can be overridden with your arguments.


## Setup

The base image is created with automated testing in mind. It is not meant to
be built every time you run tests. An unprivileged user `vimtest` is used to
run Vim to prevent files from being written back to your work directory. This
means that it won't be able to download/install plugins into a mapped volume.

To deal with this, your test `vimrc` could add known paths within the container
to `rtp`, and your `Dockerfile` could install the plugins into that location.

### /rtp.vim

This image provides a helper script that should be sourced at the top of your
vimrc:

```vim
source /rtp.vim
```

It will add `/home/vim` and `/home/vim/after` to the runtime path, and search
for plugins in `/home/plugins`.


### Volumes

Two volumes are provided:

Volume | Description
------ | -----------
/home | The user directory.
/testplugin | The directory for your plugin.
1 change: 1 addition & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/test/plugins
7 changes: 7 additions & 0 deletions example/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM tweekmonster/vim-testbed:latest

RUN install_vim -name vim-precise -tag v7.3.429 -build \
-name vim-trusty -tag v7.4.052 -build \
-name vim-vivid -tag v7.4.488 -build \
-name vim-wily -tag v7.4.712 -build \
-name vim-xenial -tag v7.4.963 -build
16 changes: 16 additions & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PLUGINS = test/plugins
IMAGE = tweekmonster/ubuntu-vims
DOCKER = docker run -it --rm -v $(PWD):/testplugin -v $(PWD)/test:/home "$(IMAGE)"

test-setup:
mkdir -p $(PLUGINS)
cd $(PLUGINS) && git clone https://github.com/junegunn/vader.vim.git

test:
$(DOCKER) vim-precise '+Vader! test/*'
$(DOCKER) vim-trusty '+Vader! test/*'
$(DOCKER) vim-vivid '+Vader! test/*'
$(DOCKER) vim-wily '+Vader! test/*'
$(DOCKER) vim-xenial '+Vader! test/*'

.PHONY: test-setup test
1 change: 1 addition & 0 deletions example/plugin/example.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let g:example_plugin = 1
11 changes: 11 additions & 0 deletions example/test/example.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Given:
hello

Do:
^

Expect:
hello

Execute:
AssertEqual 1, g:example_plugin
17 changes: 17 additions & 0 deletions example/test/vimrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
source /rtp.vim

filetype plugin indent on
syntax on
set nocompatible
set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
set backspace=2
set nofoldenable
set foldmethod=syntax
set foldlevelstart=10
set foldnestmax=10
set ttimeoutlen=0

let mapleader=","
14 changes: 14 additions & 0 deletions scripts/argecho.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

echo "Running as: $(whoami)"

echo
echo "Environment:"
env

echo
echo "Arguments:"
while [ $# -gt 0 ]; do
echo $1
shift
done
117 changes: 117 additions & 0 deletions scripts/install_vim.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#/bin/bash

bail() {
echo $@
exit 1
}


TAG=""
NAME=""
PYTHON=0
RUBY=0
LUA=0

build() {
[ -z $NAME ] && NAME="vim-${TAG}"
[ -z $TAG ] && bail "-tag is required"

VIM_NAME="vim_${TAG}_py${PYTHON}_rb${RUBY}_lua${LUA}"
VIM_PATH="/vim-build/$VIM_NAME"
VIM_BIN="$VIM_PATH/bin/vim"

CONFIG_ARGS="--prefix=$VIM_PATH"

if [ $PYTHON -eq 2 ]; then
CONFIG_ARGS="$CONFIG_ARGS --enable-pythoninterp"
apk add python-dev
fi

if [ $PYTHON -eq 3 ]; then
CONFIG_ARGS="$CONFIG_ARGS --enable-python3interp"
apk add python3-dev
fi

if [ $RUBY -eq 1 ]; then
CONFIG_ARGS="$CONFIG_ARGS --enable-rubyinterp"
apk add ruby-dev
fi

if [ $LUA -eq 1 ]; then
CONFIG_ARGS="$CONFIG_ARGS --enable-luainterp"
apk add lua-dev
fi

cd /vim

BUILD_DIR="vim-${TAG#v}"

apk info -q vim-build > /dev/null || apk add --virtual vim-build make ncurses-dev curl gcc libc-dev

if [ ! -d $BUILD_DIR ]; then
# The git package adds about 200MB+ to the image. So, no cloning.
echo "Downloading $TAG"
curl -sSL "https://github.com/vim/vim/archive/${TAG}.tar.gz" | tar zx
fi

cd $BUILD_DIR
./configure $CONFIG_ARGS || bail "Could not configure"
make CFLAGS="-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2" -j4 || bail "Make failed"
make install || bail "Install failed"

ln -s $VIM_BIN /vim-build/bin/$NAME

# Clean, but don't delete the source in case you want make a different build
# with the same version.
make distclean
}


apk update

while [ $# -gt 0 ]; do
case $1 in
-name)
NAME="$2"
shift
;;
-tag)
TAG="$2"
shift
;;
-py)
PYTHON=2
;;
-py3)
PYTHON=3
;;
-ruby)
RUBY=1
;;
-lua)
LUA=1
;;
-build)
# So here I am thinking that using Alpine was going to give the biggest
# savings in image size. Alpine starts at about 5MB. Built this image,
# and it's about 8MB. Looking good. Install two versions of vanilla
# vim, 300MB wtf!!! Each run of this script without cleaning up created
# a layer with all of the build dependencies. So now, this script
# expects a -build flag to signal the start of a build. This way,
# installing all Vim versions becomes one layer.
# Side note: tried docker-squash and it didn't seem to do anything.
build
NAME=""
TAG=""
PYTHON=0
RUBY=0
LUA=0
;;
esac

shift
done

apk del vim-build
rm -rf /vim/*
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
3 changes: 3 additions & 0 deletions scripts/rtp.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
set rtp=/home/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,/home/vim/after
execute 'set rtp+='.join(filter(split(expand('/home/plugins/*')), 'isdirectory(v:val)'), ',')
set rtp+=/testplugin
17 changes: 17 additions & 0 deletions scripts/run_vim.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

BIN=$1
shift

# Set default vimrc to a visible file
ARGS="-u /home/vimrc -i NONE"

# So we can pass the arguments to Vim as it was passed to this script
while [ $# -gt 0 ]; do
ARGS="$ARGS \"$1\""
shift
done

# Run as the vimtest user. This is not really for security. It is for running
# Vim as a user that's unable to write to your volume.
exec su -l vimtest -c "cd /testplugin && /vim-build/bin/$BIN $ARGS"

0 comments on commit 1e97840

Please sign in to comment.