The server on failure can just disconnect the client or report the error. The error report can be done using new protocol 2 or just a number (like protocol 1). Detect the failure report to make possible to check it. Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> --- server/tests/test-sasl.c | 111 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 24 deletions(-) diff --git a/server/tests/test-sasl.c b/server/tests/test-sasl.c index 50d2c756..cb5fd877 100644 --- a/server/tests/test-sasl.c +++ b/server/tests/test-sasl.c @@ -405,13 +405,24 @@ typedef enum { STEP_READ_START, STEP_WRITE_STEP_LEN, STEP_WRITE_STEP, + STEP_READ_STEP_LEN, + STEP_READ_STEP, STEP_NEVER, } ClientEmulationSteps; +typedef enum { + FAILURE_OK, + FAILURE_UNKNOWN, + FAILURE_DISCONNECT, + FAILURE_MAGIC, + FAILURE_AUTH, +} FailureType; + typedef struct { const char *mechname; int mechlen; bool success; + FailureType failure_type; ClientEmulationSteps last_step; unsigned flags; int line; @@ -421,28 +432,30 @@ static char long_mechname[128]; static TestData tests_data[] = { // these should just succeed #define TEST_SUCCESS(mech) \ - { mech, -1, true, STEP_NEVER, FLAG_NONE, __LINE__ }, + { mech, -1, true, FAILURE_OK, STEP_NEVER, FLAG_NONE, __LINE__ }, TEST_SUCCESS("ONE") TEST_SUCCESS("TWO") TEST_SUCCESS("THREE") // these test bad mech names #define TEST_BAD_NAME(mech, len) \ - { mech, len, false, STEP_NEVER, FLAG_NONE, __LINE__ }, + { mech, len, false, FAILURE_MAGIC, STEP_NEVER, FLAG_NONE, __LINE__ }, +#define TEST_BAD_NAME_LEN(mech, len) \ + { mech, len, false, FAILURE_DISCONNECT, STEP_NEVER, FLAG_NONE, __LINE__ }, TEST_BAD_NAME("ON", -1) TEST_BAD_NAME("NE", -1) TEST_BAD_NAME("THRE", -1) TEST_BAD_NAME("HREE", -1) TEST_BAD_NAME("ON\x00", 3) TEST_BAD_NAME("O\x00\x00", 3) - TEST_BAD_NAME("", -1) + TEST_BAD_NAME_LEN("", -1) TEST_BAD_NAME(long_mechname, 100) - TEST_BAD_NAME(long_mechname, 101) + TEST_BAD_NAME_LEN(long_mechname, 101) TEST_BAD_NAME("ONE,TWO", -1) // stop before filling everything #define TEST_EARLY_STOP(step) \ - { "ONE", -1, false, step, FLAG_NONE, __LINE__}, + { "ONE", -1, false, FAILURE_UNKNOWN, step, FLAG_NONE, __LINE__}, TEST_EARLY_STOP(STEP_READ_MECHLIST_LEN) TEST_EARLY_STOP(STEP_READ_MECHLIST) TEST_EARLY_STOP(STEP_WRITE_MECHNAME_LEN) @@ -451,21 +464,23 @@ static TestData tests_data[] = { TEST_EARLY_STOP(STEP_WRITE_START) TEST_EARLY_STOP(STEP_WRITE_STEP_LEN) -#define TEST_FLAGS(result, flags) \ - { "ONE", -1, result, STEP_NEVER, flags, __LINE__}, - TEST_FLAGS(false, FLAG_LOW_SSF) - TEST_FLAGS(false, FLAG_START_OK|FLAG_LOW_SSF) - TEST_FLAGS(true, FLAG_START_OK) - TEST_FLAGS(true, FLAG_SERVER_NULL_START) - TEST_FLAGS(true, FLAG_SERVER_NULL_STEP) - TEST_FLAGS(true, FLAG_CLIENT_NULL_START) - TEST_FLAGS(true, FLAG_CLIENT_NULL_STEP) - TEST_FLAGS(false, FLAG_SERVER_BIG_START) - TEST_FLAGS(false, FLAG_SERVER_BIG_STEP) - TEST_FLAGS(false, FLAG_CLIENT_BIG_START) - TEST_FLAGS(false, FLAG_CLIENT_BIG_STEP) - TEST_FLAGS(false, FLAG_START_ERROR) - TEST_FLAGS(false, FLAG_STEP_ERROR) +#define TEST_FLAGS_OK(flags) \ + { "ONE", -1, true, FAILURE_OK, STEP_NEVER, flags, __LINE__}, +#define TEST_FLAGS_KO(failure, flags) \ + { "ONE", -1, false, failure, STEP_NEVER, flags, __LINE__}, + TEST_FLAGS_KO(FAILURE_OK, FLAG_LOW_SSF) + TEST_FLAGS_KO(FAILURE_OK, FLAG_START_OK|FLAG_LOW_SSF) + TEST_FLAGS_OK(FLAG_START_OK) + TEST_FLAGS_OK(FLAG_SERVER_NULL_START) + TEST_FLAGS_OK(FLAG_SERVER_NULL_STEP) + TEST_FLAGS_OK(FLAG_CLIENT_NULL_START) + TEST_FLAGS_OK(FLAG_CLIENT_NULL_STEP) + TEST_FLAGS_KO(FAILURE_DISCONNECT, FLAG_SERVER_BIG_START) + TEST_FLAGS_KO(FAILURE_DISCONNECT, FLAG_SERVER_BIG_STEP) + TEST_FLAGS_KO(FAILURE_MAGIC, FLAG_CLIENT_BIG_START) + TEST_FLAGS_KO(FAILURE_DISCONNECT, FLAG_CLIENT_BIG_STEP) + TEST_FLAGS_KO(FAILURE_DISCONNECT, FLAG_START_ERROR) + TEST_FLAGS_KO(FAILURE_DISCONNECT, FLAG_STEP_ERROR) }; static void * @@ -473,6 +488,7 @@ client_emulator(void *arg) { const TestData *data = &tests_data[test_num]; int sock = GPOINTER_TO_INT(arg); + FailureType result = FAILURE_UNKNOWN; #define STOP_AT(step) if (data->last_step == STEP_ ## step) { break; } @@ -535,16 +551,33 @@ client_emulator(void *arg) uint32_t datalen; if (read_u32_err(sock, &datalen) != sizeof(datalen)) { + result = FAILURE_DISCONNECT; break; } STOP_AT(READ_START_LEN); if (datalen == GUINT32_FROM_LE(SPICE_MAGIC)) { + result = FAILURE_MAGIC; break; } g_assert_cmpint(datalen, <=, sizeof(buf)); read_all(sock, buf, datalen); STOP_AT(READ_START); + uint8_t is_ok; + read_all(sock, &is_ok, sizeof(is_ok)); + if (is_ok) { + // is_ok should be 0 or 1 + g_assert_cmpint(is_ok, ==, 1); + uint32_t step_result; + read_u32(sock, &step_result); + if (!step_result) { + result = FAILURE_AUTH; + break; + } + result = FAILURE_OK; + break; + } + get_step_out(&out, &outlen, "STEP", FLAG_CLIENT_NULL_STEP, FLAG_CLIENT_BIG_STEP); write_u32(sock, out ? outlen : 0); STOP_AT(WRITE_STEP_LEN); @@ -556,6 +589,34 @@ client_emulator(void *arg) } } STOP_AT(WRITE_STEP); + + if (read_u32_err(sock, &datalen) != sizeof(datalen)) { + result = FAILURE_DISCONNECT; + break; + } + STOP_AT(READ_STEP_LEN); + if (datalen == GUINT32_FROM_LE(SPICE_MAGIC)) { + result = FAILURE_MAGIC; + break; + } + g_assert_cmpint(datalen, <=, sizeof(buf)); + read_all(sock, buf, datalen); + STOP_AT(READ_STEP); + + read_all(sock, &is_ok, sizeof(is_ok)); + if (is_ok) { + // is_ok should be 0 or 1 + g_assert_cmpint(is_ok, ==, 1); + uint32_t step_result; + read_u32(sock, &step_result); + if (!step_result) { + result = FAILURE_AUTH; + break; + } + result = FAILURE_OK; + break; + } + } while(0); shutdown(sock, SHUT_RDWR); @@ -563,7 +624,7 @@ client_emulator(void *arg) idle_add(idle_end_test, NULL); - return NULL; + return GINT_TO_POINTER(result); } static pthread_t @@ -598,7 +659,7 @@ idle_end_test(void *arg) } static void -check_test_results(void) +check_test_results(FailureType res) { const TestData *data = &tests_data[test_num]; if (data->success) { @@ -608,6 +669,7 @@ check_test_results(void) g_assert(mechlist_called); g_assert(!encode_called); + g_assert_cmpint(res, ==, data->failure_type); } static void @@ -621,9 +683,10 @@ sasl_mechs(void) pthread_t thread = setup_thread(); alarm(4); basic_event_loop_mainloop(); - g_assert_cmpint(pthread_join(thread, NULL), ==, 0); + void *thread_ret = NULL; + g_assert_cmpint(pthread_join(thread, &thread_ret), ==, 0); alarm(0); - check_test_results(); + check_test_results((FailureType)GPOINTER_TO_INT(thread_ret)); reset_test(); } -- 2.14.3 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel