Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Add basic sharness tests #504

Merged
merged 12 commits into from
Oct 16, 2016
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ script:
- npm run lint
- npm test
- npm run coverage

- make test

before_script:
- export DISPLAY=:99.0
Expand Down
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
all: help

test: test_expensive

test_short: test_sharness_short

test_expensive: test_sharness_expensive

test_sharness_short:
$(MAKE) -j1 -C test/sharness/

test_sharness_expensive:
TEST_EXPENSIVE=1 $(MAKE) -j1 -C test/sharness/

help:
@echo 'TESTING TARGETS:'
@echo ''
@echo ' test - Run expensive tests'
@echo ' test_short - Run short tests and sharness tests'
@echo ' test_expensive - Run a few extras'
@echo ' test_sharness_short'
@echo ' test_sharness_expensive'
@echo ''
1 change: 1 addition & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin/
107 changes: 107 additions & 0 deletions test/ipfs-test-lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Generic test functions for ipfs cli tests

# Quote arguments for sh eval
shellquote() {
_space=''
for _arg
do
# On Mac OS, sed adds a newline character.
# With a printf wrapper the extra newline is removed.
printf "$_space'%s'" "$(printf "%s" "$_arg" | sed -e "s/'/'\\\\''/g;")"
_space=' '
done
printf '\n'
}

# Echo the args, run the cmd, and then also fail,
# making sure a test case fails.
test_fsh() {
echo "> $@"
eval $(shellquote "$@")
echo ""
false
}

# Same as sharness' test_cmp but using test_fsh (to see the output).
# We have to do it twice, so the first diff output doesn't show unless it's
# broken.
test_cmp() {
diff -q "$@" >/dev/null || test_fsh diff -u "$@"
}

# Same as test_cmp above, but we sort files before comparing them.
test_sort_cmp() {
sort "$1" >"$1_sorted" &&
sort "$2" >"$2_sorted" &&
test_cmp "$1_sorted" "$2_sorted"
}

# Same as test_cmp above, but we standardize directory
# separators before comparing the files.
test_path_cmp() {
sed -e "s/\\\\/\//g" "$1" >"$1_std" &&
sed -e "s/\\\\/\//g" "$2" >"$2_std" &&
test_cmp "$1_std" "$2_std"
}

# Docker

# This takes a Dockerfile, and a build context directory
docker_build() {
docker build --rm -f "$1" "$2"
}

# This takes an image as argument and writes a docker ID on stdout
docker_run() {
docker run -d "$1"
}

# This takes a docker ID and a command as arguments
docker_exec() {
if test "$CIRCLE" = 1
then
sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' $1)" -- /bin/bash -c "$2"
else
docker exec -t "$1" /bin/bash -c "$2"
fi
}

# This takes a docker ID as argument
docker_stop() {
docker stop "$1"
}

# Test whether all the expected lines are included in a file. The file
# can have extra lines.
#
# $1 - Path to file with expected lines.
# $2 - Path to file with actual output.
#
# Examples
#
# test_expect_success 'foo says hello' '
# echo hello >expected &&
# foo >actual &&
# test_cmp expected actual
# '
#
# Returns the exit code of the command set by TEST_CMP.
test_includes_lines() {
sort "$1" >"$1_sorted" &&
sort "$2" >"$2_sorted" &&
comm -2 -3 "$1_sorted" "$2_sorted" >"$2_missing" &&
[ ! -s "$2_missing" ] || test_fsh comm -2 -3 "$1_sorted" "$2_sorted"
}

# Depending on GNU seq availability is not nice.
# Git also has test_seq but it uses Perl.
test_seq() {
test "$1" -le "$2" || return
i="$1"
j="$2"
while test "$i" -le "$j"
do
echo "$i"
i=$(expr "$i" + 1)
done
}
4 changes: 4 additions & 0 deletions test/sharness/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
!/lib/
lib/sharness/
test-results/
trash directory.*.sh/
53 changes: 53 additions & 0 deletions test/sharness/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Run sharness tests
#
# Copyright (c) 2016 Christian Couder
# MIT Licensed; see the LICENSE file in this repository.
#
# NOTE: run with TEST_VERBOSE=1 for verbose sharness tests.

T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
LIBDIR = lib
SHARNESSDIR = sharness
AGGREGATE = $(LIBDIR)/$(SHARNESSDIR)/aggregate-results.sh


BINS = ../bin/ipfs

all: aggregate

help:
@echo "- use 'make' or 'make all' to run all the tests"
@echo "- use 'make deps' to create an 'ipfs' executable in ../bin"
@echo "- to run tests manually, make sure to include ../bin in your PATH"

clean: clean-test-results
@echo "*** $@ ***"
-rm -rf ../bin/ipfs

clean-test-results:
@echo "*** $@ ***"
-rm -rf test-results

$(T): clean-test-results deps
@echo "*** $@ ***"
./$@

aggregate: clean-test-results $(T)
@echo "*** $@ ***"
ls test-results/t*-*.sh.*.counts | $(AGGREGATE)

deps: sharness $(BINS) curl

sharness:
@echo "*** checking $@ ***"
lib/install-sharness.sh

../bin/ipfs:
mkdir -p ../bin
cd ../bin && ln -s ../../src/cli/bin.js ipfs

curl:
@which curl >/dev/null || (echo "Please install curl!" && false)

.PHONY: all help clean clean-test-results $(T) aggregate deps sharness

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we bring the Makefile to the root, so we can run it on CI by adding a line with make to:

https://github.com/ipfs/js-ipfs/blob/master/.travis.yml#L14

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In go-ipfs there is also a Makefile at the root, but it is different.
You use make test at the root and make when you are in test/sharness.
I can do something like that but it could go into another PR I think as it is related to the whole project.

Copy link
Member

@daviddias daviddias Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chriscool what I'm looking for is to be able to add these sharness tests to CI before this merge. Can we get that added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, with the last commit I added you can just run make test at the root.
I will add that to the '.travis.yml'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added that and it works.

60 changes: 60 additions & 0 deletions test/sharness/lib/install-sharness.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/sh
# install-sharness.sh
#
# Copyright (c) 2014 Juan Batiz-Benet
# Copyright (c) 2015 Christian Couder
# MIT Licensed; see the LICENSE file in this repository.
#
# This script checks that Sharness is installed in:
#
# $(pwd)/$clonedir/$sharnessdir/
#
# where $clonedir and $sharnessdir are configured below.
#
# If Sharness is not installed, this script will clone it
# from $urlprefix (defined below).
#
# If Sharness is not uptodate with $version (defined below),
# this script will fetch and will update the installed
# version to $version.
#

# settings
version=ecba410b0b58400dd6517cfa6594fdac243d9056
urlprefix=https://github.com/chriscool/sharness.git
clonedir=lib
sharnessdir=sharness

if test -f "$clonedir/$sharnessdir/SHARNESS_VERSION_$version"
then
# There is the right version file. Great, we are done!
exit 0
fi

die() {
echo >&2 "$@"
exit 1
}

checkout_version() {
git checkout "$version" || die "Could not checkout '$version'"
rm -f SHARNESS_VERSION_* || die "Could not remove 'SHARNESS_VERSION_*'"
touch "SHARNESS_VERSION_$version" || die "Could not create 'SHARNESS_VERSION_$version'"
echo "Sharness version $version is checked out!"
}

if test -d "$clonedir/$sharnessdir/.git"
then
# We need to update sharness!
cd "$clonedir/$sharnessdir" || die "Could not cd into '$clonedir/$sharnessdir' directory"
git fetch || die "Could not fetch to update sharness"
else
# We need to clone sharness!
mkdir -p "$clonedir" || die "Could not create '$clonedir' directory"
cd "$clonedir" || die "Could not cd into '$clonedir' directory"

git clone "$urlprefix" || die "Could not clone '$urlprefix'"
cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory"
fi

checkout_version
39 changes: 39 additions & 0 deletions test/sharness/lib/iptb-lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# iptb test framework
#
# Copyright (c) 2014, 2016 Jeromy Johnson, Christian Couder
# MIT Licensed; see the LICENSE file in this repository.

export IPTB_ROOT="$(pwd)/.iptb"

ipfsi() {
dir="$1"
shift
IPFS_PATH="$IPTB_ROOT/$dir" ipfs "$@"
}

check_has_connection() {
node="$1"
ipfsi "$node" swarm peers >"swarm_peers_$node" &&
grep "ipfs" "swarm_peers_$node" >/dev/null
}

startup_cluster() {
num_nodes="$1"
bound=$(expr "$num_nodes" - 1)

test_expect_success "start up nodes" '
iptb start
'

test_expect_success "connect nodes to eachother" '
iptb connect [1-$bound] 0
'

for i in $(test_seq 0 "$bound")
do
test_expect_success "node $i is connected" '
check_has_connection "$i" ||
test_fsh cat "swarm_peers_$i"
'
done
}
7 changes: 7 additions & 0 deletions test/sharness/lib/test-lib-hashes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# this file defines several useful hashes used across the test codebase.
# thus they can be defined + changed in one place

HASH_WELCOME_DOCS="QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"
HASH_GATEWAY_ASSETS="QmXB7PLRWH6bCiwrGh2MrBBjNkLv3mY3JdYXCikYZSwLED"
HASH_HELP_PAGE="QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7"
HASH_EMPTY_DIR="QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently, these change often (//cc @lgierth) how does go-ipfs handle it? Changing it manually everytime?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't change so often, so I think manually is fine for now.
Last time they changed was in January.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We update them manually here every time we update them in go-ipfs

Loading