diff --git a/Makefile b/Makefile
index cffa22908..fb13ae4d7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,33 @@
-.PHONY: clean all test
+.PHONY: clean all test release debug
 
-FLAGS=
-#FLAGS+=-race
+GOFLAGS=
+#GOFLAGS+=-race
 
-test:
+all: release test
+
+release:
 	for dir in cmd/* ; do \
-		(cd "$$dir"; go build $(FLAGS)) \
+		test -f "$$dir/Makefile" && \
+		(GOFLAGS="$(GOFLAGS)" make -C "$$dir") \
 	done
-	test/run.sh cmd/restic/restic cmd/dirdiff/dirdiff
+
+debug:
+	for dir in cmd/* ; do \
+		test -f "$$dir/Makefile" && \
+		(GOFLAGS="$(GOFLAGS)" make -C "$$dir" debug) \
+	done
+
+test: release debug
+	go test -v ./...
+	test/run.sh cmd/restic:cmd/dirdiff
+
+test-%: test/test-%.sh
+	echo $*
+	test/run.sh cmd/restic:cmd/dirdiff "test/$@.sh"
 
 clean:
 	go clean
 	for dir in cmd/* ; do \
-		(cd "$$dir"; go clean) \
+		test -f "$$dir/Makefile" && \
+		(make -C "$$dir" clean) \
 	done
diff --git a/cmd/restic/Makefile b/cmd/restic/Makefile
index 6e39fff41..7294860e6 100644
--- a/cmd/restic/Makefile
+++ b/cmd/restic/Makefile
@@ -4,18 +4,23 @@ VERSION ?= "unknown version"
 LDFLAGS = -X main.version $(VERSION)
 TAGS =
 
-.PHONY: all clean debug
+.PHONY: all both clean debug
 
 # include config file if it exists
 -include $(CURDIR)/config.mk
 
 all: restic
 
-restic: $(wildcard *.go) $(wildcard ../../*.go) $(wildcard ../../*/*.go)
-	go build $(TAGS) -ldflags "$(LDFLAGS)"
+both: restic restic.debug
 
-debug: TAGS=-tags "debug debug_cmd"
-debug: restic
+debug:  restic.debug
+
+restic: $(wildcard *.go) $(wildcard ../../*.go) $(wildcard ../../*/*.go)
+	go build -tags "$(TAGS)" $(GOFLAGS) -ldflags "$(LDFLAGS)"
+
+restic.debug: $(wildcard *.go) $(wildcard ../../*.go) $(wildcard ../../*/*.go)
+	go build -o restic.debug -tags "debug" $(GOFLAGS) -ldflags "$(LDFLAGS)"
 
 clean:
 	go clean
+	rm -f restic restic.debug
diff --git a/key_int_test.go b/key_int_test.go
index 1298ccc32..db62a86a3 100644
--- a/key_int_test.go
+++ b/key_int_test.go
@@ -79,3 +79,7 @@ func TestCrypto(t *testing.T) {
 		}
 	}
 }
+
+func TestHmac(t *testing.T) {
+
+}
diff --git a/test/run.sh b/test/run.sh
index 697a3895f..d5084d4bf 100755
--- a/test/run.sh
+++ b/test/run.sh
@@ -2,16 +2,14 @@
 
 set -e
 
-export restic="${1:-restic}"; shift
-export dirdiff="${1:-dirdiff}"; shift
 export dir=$(dirname "$0")
 export fake_data_file="${dir}/fake-data.tar.gz"
 
 prepare() {
     export BASE="$(mktemp --tmpdir --directory restic-testsuite-XXXXXX)"
     export RESTIC_REPOSITORY="${BASE}/restic-backup"
-    export DATADIR="${BASE}/fake-data"
     export RESTIC_PASSWORD="foobar"
+    export DATADIR="${BASE}/fake-data"
     debug "repository is at ${RESTIC_REPOSITORY}"
 
     mkdir -p "$DATADIR"
@@ -31,14 +29,6 @@ cleanup() {
     unset RESTIC_REPOSITORY
 }
 
-restic() {
-    "${restic}" "$@"
-}
-
-dirdiff() {
-    "${dirdiff}" "$@"
-}
-
 msg() {
     printf "%s: %s\n" "$(basename "$0" .sh)" "$*"
 }
@@ -70,11 +60,16 @@ run() {
     fi
 }
 
-export -f restic dirdiff prepare cleanup msg debug pass err fail run
+export -f prepare cleanup msg debug pass err fail run
 
-if [ ! -x "$restic" ]; then
-    fail restic binary not found!
-fi
+# first argument is restic path
+export PATH="$1:$PATH"; shift
+
+which restic || fail "restic binary not found!"
+which dirdiff || fail "dirdiff binary not found!"
+
+debug "restic path: $(which restic)"
+debug "dirdiff path: $(which dirdiff)"
 
 if [ "$#" -gt 0 ]; then
     testfiles="$1"
@@ -88,7 +83,11 @@ failed=""
 for testfile in "${testfiles[@]}"; do
     current=$(basename "${testfile}" .sh)
 
-    if bash "${testfile}"; then
+    if [ "$DEBUG" = "1" ]; then
+        OPTS="-v"
+    fi
+
+    if bash $OPTS "${testfile}"; then
         pass "${current} pass"
     else
         err "${current} failed!"