summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2011-10-07 17:22:09 +0100
committerRichard Maw <richard.maw@codethink.co.uk>2011-10-10 10:33:12 +0100
commitcdb2882dc33b7bd1ee3fba2190cc17fef324050d (patch)
tree1f06d7dd2c762cf147a7eff3a87473b2968d6edd /tests
parentf083ad60f671c0d058668c64ff2bb9ca8fad6fb2 (diff)
downloadtbdiff-cdb2882dc33b7bd1ee3fba2190cc17fef324050d.tar.gz
Added the ability to test the return code of create and deploy
So expected failures can be made by comparing the return code to the expected Also socket tests have been added, add and diff expect create to fail for now The only sensible operation on sockets is to remove them as they need a program to bind them and that program (or a child) needs to be a server So tbdiff should fail if it has to perform such an act. It may be worth having an option to ignore the change, but for now it's better to fail and let the user know why so they can fix it
Diffstat (limited to 'tests')
-rwxr-xr-xtests/12_socket_remove.sh38
-rwxr-xr-xtests/13_socket_add.sh34
-rwxr-xr-xtests/14_socket_diff.sh38
-rw-r--r--tests/sockbind.c70
-rw-r--r--tests/test_lib.sh61
5 files changed, 228 insertions, 13 deletions
diff --git a/tests/12_socket_remove.sh b/tests/12_socket_remove.sh
new file mode 100755
index 0000000..db44380
--- /dev/null
+++ b/tests/12_socket_remove.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+TEST_ID="12"
+TEST_NAME="Socket device removal"
+
+CREATE=`pwd`/$1
+DEPLOY=`pwd`/$2
+TEST_TOOLS=$3
+
+. ./test_lib.sh
+
+############# Test specific code ############
+# sockets can only be moved, linked or removed by the file system
+# creation is only performed by the program that acts as the server
+# tbdiff won't be doing that so the only sensible operation is removal
+SOCKBIND=`mktemp`
+setup () {
+ # sockbind creates a socket then writes any data written to it to stdout
+ # have to fork it because it will never stop, have to wait for it to
+ # make the socket
+ gcc sockbind.c -o $SOCKBIND 2>/dev/null >/dev/null
+ $SOCKBIND "$ORIGIN/toremove" &
+ SOCKBINDPID=$!
+ until test -S "$ORIGIN/toremove"; do :; done
+ kill $SOCKBINDPID && wait $SOCKBINDPID 2>/dev/null
+ rm -f $SOCKBIND
+}
+
+create_test_return () {
+ test $1 = 0
+}
+
+check_results () {
+ test ! -S "$ORIGIN/toremove"
+}
+
+#############################################
+main $@
diff --git a/tests/13_socket_add.sh b/tests/13_socket_add.sh
new file mode 100755
index 0000000..daa4f8f
--- /dev/null
+++ b/tests/13_socket_add.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+TEST_ID="13"
+TEST_NAME="Socket device addition"
+
+CREATE=`pwd`/$1
+DEPLOY=`pwd`/$2
+TEST_TOOLS=$3
+
+. ./test_lib.sh
+
+############# Test specific code ############
+# sockets can't be added sensibly, test that it hasn't been
+SOCKBIND=`mktemp`
+setup () {
+ gcc sockbind.c -o $SOCKBIND 2>/dev/null >/dev/null
+ $SOCKBIND "$TARGET/toadd" &
+ SOCKBINDPID=$!
+ until test -S "$TARGET/toadd"; do :; done
+ kill $SOCKBINDPID && wait $SOCKBINDPID 2>/dev/null
+ rm -f $SOCKBIND
+}
+
+#tbdiff-create should fail when it would have to add a socket
+create_test_return () {
+ test "$1" != "0"
+}
+
+check_results () {
+ false #test should never reach this
+}
+
+#############################################
+main $@
diff --git a/tests/14_socket_diff.sh b/tests/14_socket_diff.sh
new file mode 100755
index 0000000..9cf9195
--- /dev/null
+++ b/tests/14_socket_diff.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+TEST_ID="14"
+TEST_NAME="Socket device difference"
+
+CREATE=`pwd`/$1
+DEPLOY=`pwd`/$2
+TEST_TOOLS=$3
+
+. ./test_lib.sh
+
+############# Test specific code ############
+# sockets can't be changed sensibly, test that it hasn't been
+
+SOCKBIND=`mktemp`
+setup () {
+ gcc sockbind.c -o $SOCKBIND 2>/dev/null >/dev/null
+ $SOCKBIND "$ORIGIN/tochange" &
+ SOCKBINDPID1=$!
+ $SOCKBIND "$TARGET/tochange" &
+ SOCKBINDPID2=$!
+ until test -S "$TARGET/tochange" -a -S "$ORIGIN/tochange"; do :; done
+ kill $SOCKBINDPID1 $SOCKBINDPID2 &&
+ wait $SOCKBINDPID1 $SOCKBINDPID2 2>/dev/null #surpress terminated output
+ rm -f $SOCKBIND
+}
+
+#tbdiff-create should fail to make a patch if it would have to change a socket
+create_test_return () {
+ test "$1" != 0
+}
+
+check_results () {
+ false #test should never reach this
+}
+
+#############################################
+main $@
diff --git a/tests/sockbind.c b/tests/sockbind.c
new file mode 100644
index 0000000..f98b5ed
--- /dev/null
+++ b/tests/sockbind.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define MAX_CLIENTS 1
+#ifdef DEBUG
+#define DEBUGPRINT(fmt, ...) fprintf(stderr, "DEBUG: %s %s %d: " fmt, \
+ __FILE__, __func__, __LINE__, __VA_ARGS__)
+#else
+#define DEBUGPRINT(...) (void)0
+#endif
+
+int main(int argc, char *argv[]){
+ struct sockaddr_un sock = {
+ .sun_family = AF_UNIX
+ };
+ int sfd;
+ if (argc < 1){
+ fprintf(stderr, "Usage: %s PATH\n", argv[0]);
+ return 1;
+ }
+ strncpy(sock.sun_path, argv[1], sizeof(sock) - offsetof(struct sockaddr_un, sun_path));
+ DEBUGPRINT("%s", "Constructed socket address\n");
+ if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1){
+ perror("socket");
+ return 2;
+ }
+ DEBUGPRINT("Created socket fd=%d\n", sfd);
+ if (bind(sfd, (struct sockaddr*)&sock, sizeof(sock)) == -1){
+ perror("bind");
+ return 3;
+ }
+ if (listen(sfd, MAX_CLIENTS) == -1){
+ perror("listen");
+ return 4;
+ }
+ DEBUGPRINT("Listening to %d clients\n", MAX_CLIENTS);
+ {
+ struct sockaddr_un client_address;
+ socklen_t client_size = sizeof(client_address);
+ int cfd;
+ while ((cfd = accept(sfd, (struct sockaddr*)&client_address,
+ &client_size)) != -1) {
+ char buf[BUFSIZ];
+ ssize_t rdcount = -1;
+ DEBUGPRINT("Listening to client fd=%d\n", cfd);
+ while ((rdcount = read(cfd, buf, sizeof(buf))) > 0) {
+ DEBUGPRINT("Read %zi bytes from client, "
+ "message was:\n%.*s", rdcount,
+ rdcount, buf);
+ write(STDOUT_FILENO, buf, rdcount);
+ }
+ assert(rdcount == 0 || rdcount == -1);
+ if (rdcount == -1) {
+ perror("read");
+ return 5;
+ }
+ DEBUGPRINT("Finished listening to fd=%d\n", cfd);
+ close(cfd);
+ }
+ }
+
+ close(sfd);
+ unlink(argv[1]);
+ return 0;
+}
diff --git a/tests/test_lib.sh b/tests/test_lib.sh
index 4645166..5112cea 100644
--- a/tests/test_lib.sh
+++ b/tests/test_lib.sh
@@ -41,6 +41,46 @@ check_group () {
test $(stat -c %G $1) = $2
}
+#declare -f is faster, but won't work in dash
+is_function () {
+ type $1 2>/dev/null | grep 'function'
+}
+
+#check_command COMMAND_STRING TEST_COMMAND COMMAND_DESCRIPTION
+check_command () {
+ COMMAND_STRING=$1
+ TEST_COMMAND=$2
+ COMMAND_DESCRIPTION="$3"
+ eval $COMMAND_STRING
+ RETVAL=$?
+ if is_function "$TEST_COMMAND"; then #test explicitly checks return
+ if $TEST_COMMAND $RETVAL; then
+ if [ "$RETVAL" != "0" ]; then
+ echo $COMMAND_STRING expected failure in \
+ $COMMAND_DESCRIPTION >&2
+ echo $OK
+ exit 0
+ fi
+ else
+ if [ "$RETVAL" = "0" ]; then
+ echo $COMMAND_STRING Unexpected success in \
+ $COMMAND_DESCRIPTION >&2
+ echo $FAIL
+ cleanup_and_exit
+ else
+ echo $COMMAND_STRING Unexpected failure in \
+ $COMMAND_DESCRIPTION >&2
+ echo $FAIL
+ cleanup_and_exit
+ fi
+ fi
+ elif [ "$RETVAL" != "0" ]; then #return value expected to be 0
+ echo $COMMAND_STRING Unexpected failure $COMMAND_DESCRIPTION >&2
+ echo $FAIL
+ cleanup_and_exit
+ fi
+}
+
start () {
if [ $# -ne 2 ]
then
@@ -88,20 +128,15 @@ main () {
echo $OK
echo "$TEST_ID Performing $TEST_NAME image creation and deployment: "
- CWD=$(pwd)
- $CREATE $IMGFILE $ORIGIN $TARGET && \
- cd $ORIGIN && \
- $DEPLOY $IMGFILE && \
- RETVAL=$?
- cd $CWD
- if test "x$RETVAL" != "x0"
- then
- echo $FAIL
- echo "Could not create and deploy image." 1>&2
- cleanup_and_exit
- fi
- echo $OK
+ CWD=$(pwd) &&
+ check_command "$CREATE $IMGFILE $ORIGIN $TARGET" 'create_test_return' \
+ "$TEST_ID-$TEST_NAME: creating image"
+ cd $ORIGIN &&
+ check_command "$DEPLOY $IMGFILE" 'deploy_test_return' \
+ "$TEST_ID-$TEST_NAME: deploying image"
+
+ cd $CWD
echo -n "$TEST_ID Checking $TEST_NAME results: "
check_results
if test "x$?" != "x0"