From 129744692c3a327908cd3d29b30665194ddee0c9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 18 Sep 2018 15:28:48 +0200 Subject: [PATCH] tests: Wait for the server to start The previous timeout of 500 ms was not enough on slower machines or while running the tests under valgrind. On much faster machines the sleep() was bringing unnecessary overhead. This method opens simple connection to the server verifying it is ready to accept the connection from the test for 5 seconds. It the server does not start until then, it fails the tests during initialization, rather than leaving the cases to run against missing server. Signed-off-by: Jakub Jelen Reviewed-by: Andreas Schneider (cherry picked from commit c15ad753a7083e3886891f0a1db7cd809ad23582) --- tests/CMakeLists.txt | 8 ++++++ tests/ssh_ping.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ tests/torture.c | 26 +++++++++++++++-- 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 tests/ssh_ping.c diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3fb68738..ca9f89c5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,6 +31,9 @@ add_library(${TORTURE_LIBRARY} torture_pki.c torture_cmocka.c) target_link_libraries(${TORTURE_LIBRARY} ${TORTURE_LINK_LIBRARIES}) +target_compile_options(${TORTURE_LIBRARY} PRIVATE + -DSSH_PING_EXECUTABLE="${CMAKE_CURRENT_BINARY_DIR}/ssh_ping" +) if (ARGP_LIBRARY) target_link_libraries(${TORTURE_LIBRARY} @@ -87,6 +90,11 @@ if (CLIENT_TESTING) chroot_wrapper ) + # ssh_ping + add_executable(ssh_ping ssh_ping.c) + target_compile_options(ssh_ping PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + target_link_libraries(ssh_ping ${LIBSSH_SHARED_LIBRARY}) + # homedir will be used in passwd set(HOMEDIR ${CMAKE_CURRENT_BINARY_DIR}/home) diff --git a/tests/ssh_ping.c b/tests/ssh_ping.c new file mode 100644 index 00000000..c9b5dad5 --- /dev/null +++ b/tests/ssh_ping.c @@ -0,0 +1,67 @@ +/* ssh_ping.c */ +/* +Copyright 2018 Red Hat, Inc + +Author: Jakub Jelen + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +The goal is to show the API in action. It's not a reference on how terminal +clients must be made or how a client should react. +*/ + +#include +#include +#include + +int main(int argc, char **argv) +{ + const char *banner = NULL; + ssh_session session = NULL; + int rc = 1; + + if (argc < 1 || argv[1] == NULL) { + fprintf(stderr, "Error: Need an argument (hostname)\n"); + goto out; + } + + session = ssh_new(); + if (session == NULL) { + goto out; + } + + rc = ssh_options_set(session, SSH_OPTIONS_HOST, argv[1]); + if (rc < 0) { + goto out; + } + + /* The automatic username is not available under uid wrapper */ + rc = ssh_options_set(session, SSH_OPTIONS_USER, "ping"); + if (rc < 0) { + goto out; + } + + rc = ssh_connect(session); + if (rc != SSH_OK) { + fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session)); + goto out; + } + + banner = ssh_get_serverbanner(session); + if (banner == NULL) { + fprintf(stderr, "Did not receive SSH banner\n"); + goto out; + } + + printf("%s", banner); + rc = 0; + +out: + ssh_free(session); + return rc; +} + diff --git a/tests/torture.c b/tests/torture.c index 95da3c67..23b1d1fd 100644 --- a/tests/torture.c +++ b/tests/torture.c @@ -42,6 +42,7 @@ #include "torture.h" #include "torture_key.h" +#include "libssh/misc.h" /* for pattern matching */ #include "match.c" @@ -696,6 +697,24 @@ static void torture_setup_create_sshd_config(void **state) torture_write_file(s->srv_config, sshd_config); } +static int torture_wait_for_daemon(unsigned int seconds) +{ + struct ssh_timestamp start; + int rc; + + ssh_timestamp_init(&start); + + while (!ssh_timeout_elapsed(&start, seconds * 1000)) { + rc = system(SSH_PING_EXECUTABLE " " TORTURE_SSH_SERVER); + if (rc == 0) { + return 0; + } + /* Wait 200 ms before retrying */ + usleep(200 * 1000); + } + return 1; +} + void torture_setup_sshd_server(void **state) { struct torture_state *s; @@ -718,11 +737,12 @@ void torture_setup_sshd_server(void **state) rc = system(sshd_start_cmd); assert_return_code(rc, errno); - /* Give the process 500ms time to initialize and start */ - usleep(500 * 1000); - setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "21", 1); unsetenv("PAM_WRAPPER"); + + /* Wait until the sshd is ready to accept connections */ + rc = torture_wait_for_daemon(5); + assert_int_equal(rc, 0); } void torture_teardown_socket_dir(void **state)