- 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"
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 = {
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();
*/
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");
}
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
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);
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)
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
--- /dev/null
+#!/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
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 ""
}
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 ""
}