]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/t0004'
authorAndre Noll <maan@systemlinux.org>
Sun, 6 Nov 2011 11:06:25 +0000 (12:06 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 6 Nov 2011 11:07:47 +0000 (12:07 +0100)
NEWS
server.c
signal.c
signal.h
t/makefile.test
t/t0001-oggdec-correctness.sh
t/t0004-server.sh [new file with mode: 0755]
t/test-lib.sh

diff --git a/NEWS b/NEWS
index 3a7027298f5a20ee00793554b2be89a997f331c3..f50ffa3bc633ee62add70d02549f04f941e91c5c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@
        - cleanup of the internal uptime API.
        - para_server prefaults the mmapped audio file to avoid
          delays on slow media.
+       - A new test for the test-suite that exercises the
+         communication between  para_server and para_audiod.
 
 --------------------------------------
 0.4.8 (2011-08-19) "nested assignment"
index 120fea258a64fdd1bf91e1436f22ee5d7e00a7c0..0cfac60722d825fddb4714dfba651eb8265e770a 100644 (file)
--- a/server.c
+++ b/server.c
@@ -466,12 +466,6 @@ static int init_afs(int argc, char **argv)
        return afs_server_socket[0];
 }
 
-__noreturn static void tmp_sigchld_handler(__a_unused int s)
-{
-       PARA_EMERG_LOG("caught early SIGCHLD\n");
-       exit(EXIT_FAILURE);
-}
-
 static void server_init(int argc, char **argv)
 {
        struct server_cmdline_parser_params params = {
@@ -497,6 +491,7 @@ static void server_init(int argc, char **argv)
        gettimeofday(now, NULL);
        set_server_start_time(now);
        init_user_list(user_list_file);
+       init_server_command_task(argc, argv);
        /* become daemon */
        if (conf.daemon_given)
                daemonize();
@@ -512,17 +507,18 @@ static void server_init(int argc, char **argv)
         */
        para_sigaction(SIGUSR1, SIG_IGN);
        /*
-        * We have to install a SIGCHLD handler before the afs process is being
-        * forked off. Otherwise, para_server does not notice if afs dies before
-        * the SIGCHLD handler has been installed by init_signal_task() below.
+        * We have to block SIGCHLD before the afs process is being forked off.
+        * Otherwise, para_server does not notice if afs dies before the
+        * SIGCHLD handler has been installed for the parent process by
+        * init_signal_task() below.
         */
-       para_sigaction(SIGCHLD, tmp_sigchld_handler);
+       para_block_signal(SIGCHLD);
        PARA_NOTICE_LOG("initializing the audio file selector\n");
        afs_socket = init_afs(argc, argv);
        init_signal_task();
+       para_unblock_signal(SIGCHLD);
        PARA_NOTICE_LOG("initializing virtual streaming system\n");
        init_vss_task(afs_socket);
-       init_server_command_task(argc, argv);
        PARA_NOTICE_LOG("server init complete\n");
 }
 
index f02c453a04a02e5d3e1c8a9c791aba8275a60671..aa63c8b5461a9627c021a514b83b7c8ee1067067 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -147,10 +147,50 @@ void para_install_sighandler(int sig)
        para_sigaction(sig, &generic_signal_handler);
 }
 
+/**
+ * Block a signal for the caller.
+ *
+ * \param sig The signal to block.
+ *
+ * This sets the given signal in the current signal mask of the calling process
+ * to prevent this signal from delivery.
+ *
+ * \sa \ref para_unblock_signal(), sigprocmask(2), sigaddset(3).
+ */
+void para_block_signal(int sig)
+{
+       sigset_t set;
+
+       PARA_DEBUG_LOG("blocking signal %d\n", sig);
+       sigemptyset(&set);
+       sigaddset(&set, sig);
+       sigprocmask(SIG_BLOCK, &set, NULL);
+}
+
+/**
+ * Unblock a signal.
+ *
+ * \param sig The signal to unblock.
+ *
+ * This function removes the given signal from the current set of blocked
+ * signals.
+ *
+ * \sa \ref para_block_signal(), sigprocmask(2), sigaddset(3).
+ */
+void para_unblock_signal(int sig)
+{
+       sigset_t set;
+
+       PARA_DEBUG_LOG("unblocking signal %d\n", sig);
+       sigemptyset(&set);
+       sigaddset(&set, sig);
+       sigprocmask(SIG_UNBLOCK, &set, NULL);
+}
+
 /**
  * Return the number of the next pending signal.
  *
- * \param rfds Th fd_set containing the signal pipe.
+ * \param rfds The fd_set containing the signal pipe.
  *
  * \return On success, the number of the received signal is returned. If there
  * is no signal currently pending, the function returns zero. On read errors
index 799c317fd6114046334c8577fabbe767e20eea94..266b3aba4df97de8c4ecafbaaa03065840f99f01 100644 (file)
--- a/signal.h
+++ b/signal.h
@@ -22,3 +22,5 @@ void para_install_sighandler(int);
 int para_reap_child(pid_t *pid);
 int para_next_signal(fd_set *rfds);
 void para_signal_shutdown(void);
+void para_block_signal(int sig);
+void para_unblock_signal(int sig);
index d4aedf8035b1645da0b0fcb532e814d5d7ef10d6..4bbc5d72edb0adfd2b997d667bac2d67de2f72b6 100644 (file)
@@ -15,7 +15,7 @@ ifdef V
        endif
 endif
 
-tests := $(wildcard $(test_dir)/t[0-9][0-9][0-9][0-9]-*.sh)
+tests := $(sort $(wildcard $(test_dir)/t[0-9][0-9][0-9][0-9]-*.sh))
 
 test: $(tests)
 
index 01260e5cae1c52551cb83c7bb53b9412c82bcb67..554dfdf85dd654ef81c3114a847102ede377e6bc 100755 (executable)
@@ -11,7 +11,7 @@ implementation.'
 test_require_objects "oggdec_filter"
 missing_objects="$result"
 
-test_require_executables "oggdec"
+test_require_executables oggdec sha1sum
 missing_executables="$result"
 
 get_audio_file_paths ogg
diff --git a/t/t0004-server.sh b/t/t0004-server.sh
new file mode 100755 (executable)
index 0000000..c79ea24
--- /dev/null
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+
+test_description='Check if server command socket works.
+
+A new ssh key pair is generated, para_server is started and some commands are
+sent to the server by executing para_client. This is an implicit check of the
+crypto functions.
+'
+
+. ${0%/*}/test-lib.sh
+
+loglevel=debug
+port=2991
+stream_port=8001
+# need absolute paths here because server cds to / in daemon mode
+db=$(pwd)/db
+sock=$(pwd)/sock
+user_list=ul
+privkey=key
+pubkey=$privkey.pub
+serverlog=server.log
+
+get_audio_file_paths ogg
+oggs="$result"
+
+declare -a commands=() cmdline=() required_objects=() good=() bad=()
+i=0
+commands[$i]="help"
+cmdline[$i]="help"
+good[$i]='help server  ----'
+
+let i++
+commands[$i]="init"
+cmdline[$i]="init"
+good[$i]='^successfully'
+bad[$i]='!^successfully'
+
+let i++
+commands[$i]="add_ogg"
+required_objects[$i]='ogg_afh'
+cmdline[$i]="add $oggs"
+bad[$i]='.'
+
+let i++
+commands[$i]="ls_ogg"
+required_objects[$i]='ogg_afh'
+cmdline[$i]="ls -lv -p $oggs"
+good[$i]='^path:'
+
+let i++
+commands[$i]="term"
+cmdline[$i]="term"
+bad[$i]='.'
+
+test_require_objects "server"
+missing_objects="$result"
+test_require_executables "ssh-keygen"
+missing_executables="$result"
+
+ssh-keygen -q -t rsa -b 2048 -N "" -f $privkey
+key_gen_result=$?
+
+read &>/dev/null < /dev/tcp/localhost/$port
+check_port_result=$?
+
+cat > $user_list << EOF
+user $LOGNAME $pubkey AFS_READ,AFS_WRITE,VSS_READ,VSS_WRITE
+EOF
+
+# para_server sends this signal to all processes in the current process group.
+trap "" SIGUSR1
+
+$PARA_SERVER \
+       --logfile "$serverlog" \
+       --config_file /dev/null \
+       --daemon \
+       --loglevel $loglevel \
+       --port $port \
+       --afs_database_dir "$db" \
+       --afs_socket "$sock" \
+       --user_list "$user_list" \
+       --http_port "$stream_port" \
+       --dccp_port "$stream_port"
+
+for ((i=0; i < ${#commands[@]}; i++)); do
+       command=${commands[$i]}
+       if [[ -n "$missing_objects" ]]; then
+               test_skip "$command" "missing object(s): $missing_objects"
+               continue
+       fi
+       if [[ -n "$missing_executables" ]]; then
+               test_skip "$command" \
+                       "missing executables(s): $missing_executables"
+               continue
+       fi
+       if (($key_gen_result != 0)); then
+               test_skip "$command" "ssh-keygen failed"
+               continue
+       fi
+       if (($check_port_result == 0)); then
+               test_skip "$command" "port $port already in use"
+               continue
+       fi
+       if [[ -n "${required_objects[$i]}" ]]; then
+               test_require_objects "${required_objects[$i]}"
+               if [[ -n "$result" ]]; then
+                       test_skip "$command" "requires object $result"
+                       continue
+               fi
+       fi
+       test_expect_success "$command" "
+       $PARA_CLIENT \
+               --loglevel $loglevel \
+               --server_port $port \
+               --key_file $privkey \
+               --config_file /dev/null \
+               -- \
+               ${cmdline[$i]} > $command.out &&
+               { [[ -z \"${good[$i]}\" ]] || grep \"${good[$i]}\"; } < $command.out &&
+               { [[ -z \"${bad[$i]}\" ]]  || ! grep \"${bad[$i]}\"; } < $command.out
+       "
+done
+
+trap SIGUSR1 # reset to the value it had upon entrance to the shell
+test_done
index b7d675ea0def671529e13732c52143bb22290288..f1bb8cf65b66ff3890659f2b6009bae08d3cbd77 100644 (file)
@@ -162,7 +162,7 @@ test_duration()
 test_expect_success()
 {
        (($# != 2)) && error "bug: not 2 parameters to test_expect_success()"
-       say >&3 "expecting success: $2"
+       echo >&3 "expecting success: $2"
        _test_run "$1" "$2" "success"
        echo >&3 ""
 }
@@ -170,7 +170,7 @@ test_expect_success()
 test_expect_failure()
 {
        (($# != 2)) && error "bug: not 2 parameters to test_expect_failure()"
-       say >&3 "expecting failure: $2"
+       echo >&3 "expecting failure: $2"
        _test_run "$1" "$2" "failure"
        echo >&3 ""
 }