Skip to content

Commit 70226a3

Browse files
Roytakmichalvasko
authored andcommitted
test_ch UPDATE add ch thread del while sess
1 parent c2cce42 commit 70226a3

1 file changed

Lines changed: 181 additions & 4 deletions

File tree

tests/test_ch.c

Lines changed: 181 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@
2929

3030
struct test_ch_data {
3131
struct lyd_node *tree;
32+
pthread_barrier_t *barrier2;
3233
};
3334

3435
char buffer[512];
3536
char expected[512];
3637

37-
int TEST_PORT = 10050, TEST_PORT_2 = 10051;
38-
const char *TEST_PORT_STR = "10050", *TEST_PORT_2_STR = "10051";
38+
int TEST_PORT = 10050, TEST_PORT_2 = 10051, TEST_PORT_3 = 10052, TEST_PORT_4 = 10053;
39+
const char *TEST_PORT_STR = "10050", *TEST_PORT_2_STR = "10051", *TEST_PORT_3_STR = "10052", *TEST_PORT_4_STR = "10053";
3940

4041
static void
4142
test_msg_callback(const struct nc_session *session, NC_VERB_LEVEL level, const char *msg)
@@ -169,6 +170,10 @@ test_nc_ch_free_test_data(void *test_data)
169170

170171
test_ch_data = test_data;
171172
lyd_free_tree(test_ch_data->tree);
173+
if (test_ch_data->barrier2) {
174+
pthread_barrier_destroy(test_ch_data->barrier2);
175+
free(test_ch_data->barrier2);
176+
}
172177
free(test_ch_data);
173178
}
174179

@@ -382,16 +387,188 @@ setup_tls(void **state)
382387
return 0;
383388
}
384389

390+
/*
391+
* Test: Delete CH client while session is established
392+
* Verifies that deleting a CH client from config properly signals the thread to stop,
393+
* even when the session is in RUNNING state.
394+
*/
395+
static int session_established_flag = 0;
396+
397+
static int
398+
ch_new_session_set_flag_cb(const char *client_name, struct nc_session *new_session, void *user_data)
399+
{
400+
int ret = 0;
401+
struct nc_pollsession *ps = (struct nc_pollsession *)user_data;
402+
403+
(void) client_name;
404+
405+
ret = nc_ps_add_session(ps, new_session);
406+
assert_int_equal(ret, 0);
407+
408+
session_established_flag = 1;
409+
return 0;
410+
}
411+
412+
static void *
413+
server_thread_delete_while_session(void *arg)
414+
{
415+
int ret;
416+
struct nc_pollsession *ps;
417+
struct ln2_test_ctx *test_ctx = arg;
418+
struct test_ch_data *test_data = test_ctx->test_data;
419+
420+
nc_set_print_clb_session(test_msg_callback);
421+
buffer[0] = '\0';
422+
strcpy(expected, "thread exit");
423+
424+
ps = nc_ps_new();
425+
assert_non_null(ps);
426+
427+
pthread_barrier_wait(&test_ctx->barrier);
428+
429+
ret = nc_connect_ch_client_dispatch("ch_delete_test", ch_session_acquire_ctx_cb,
430+
ch_session_release_ctx_cb, test_ctx, ch_new_session_set_flag_cb, ps);
431+
assert_int_equal(ret, 0);
432+
433+
while (!session_established_flag) {
434+
usleep(10000);
435+
}
436+
437+
do {
438+
ret = nc_ps_poll(ps, NC_PS_POLL_TIMEOUT, NULL);
439+
if (ret & (NC_PSPOLL_TIMEOUT | NC_PSPOLL_NOSESSIONS)) {
440+
usleep(500);
441+
}
442+
} while (ret & NC_PSPOLL_RPC);
443+
444+
ret = nc_server_config_setup_data(test_data->tree);
445+
assert_int_equal(ret, 0);
446+
447+
do {
448+
usleep(5000);
449+
} while (!strlen(buffer));
450+
451+
assert_true(strlen(buffer) > 0);
452+
453+
pthread_barrier_wait(test_data->barrier2);
454+
455+
nc_ps_clear(ps, 1, NULL);
456+
nc_ps_free(ps);
457+
458+
return NULL;
459+
}
460+
461+
static void *
462+
client_thread_delete_while_session(void *arg)
463+
{
464+
int ret;
465+
struct nc_session *session = NULL;
466+
struct ln2_test_ctx *test_ctx = arg;
467+
struct test_ch_data *test_data = test_ctx->test_data;
468+
469+
nc_client_ssh_ch_set_knownhosts_mode(NC_SSH_KNOWNHOSTS_SKIP);
470+
ret = nc_client_set_schema_searchpath(MODULES_DIR);
471+
assert_int_equal(ret, 0);
472+
ret = nc_client_ssh_ch_set_username("test_ch_delete");
473+
assert_int_equal(ret, 0);
474+
ret = nc_client_ssh_ch_add_keypair(TESTS_DIR "/data/id_ed25519.pub", TESTS_DIR "/data/id_ed25519");
475+
assert_int_equal(ret, 0);
476+
ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", TEST_PORT_3);
477+
assert_int_equal(ret, 0);
478+
479+
pthread_barrier_wait(&test_ctx->barrier);
480+
481+
ret = nc_accept_callhome(NC_ACCEPT_TIMEOUT, NULL, &session);
482+
assert_int_equal(ret, 1);
483+
484+
/* wait until the server deletes the client */
485+
pthread_barrier_wait(test_data->barrier2);
486+
487+
ret = nc_client_ssh_ch_del_bind("127.0.0.1", TEST_PORT_3);
488+
assert_int_equal(ret, 0);
489+
490+
nc_session_free(session, NULL);
491+
return NULL;
492+
}
493+
494+
static int
495+
setup_delete_while_session(void **state)
496+
{
497+
int ret;
498+
struct lyd_node *tree = NULL;
499+
struct ln2_test_ctx *test_ctx;
500+
struct test_ch_data *test_data;
501+
502+
ret = ln2_glob_test_setup(&test_ctx);
503+
assert_int_equal(ret, 0);
504+
505+
test_data = calloc(1, sizeof *test_data);
506+
assert_non_null(test_data);
507+
test_data->barrier2 = calloc(1, sizeof(pthread_barrier_t));
508+
assert_non_null(test_data->barrier2);
509+
pthread_barrier_init(test_data->barrier2, NULL, 2);
510+
511+
test_ctx->test_data = test_data;
512+
test_ctx->free_test_data = test_nc_ch_free_test_data;
513+
*state = test_ctx;
514+
515+
session_established_flag = 0;
516+
517+
ret = nc_server_config_add_ch_address_port(test_ctx->ctx, "ch_delete_test", "endpt", NC_TI_SSH,
518+
"127.0.0.1", TEST_PORT_3_STR, &tree);
519+
assert_int_equal(ret, 0);
520+
521+
ret = nc_server_config_add_ch_persistent(test_ctx->ctx, "ch_delete_test", &tree);
522+
assert_int_equal(ret, 0);
523+
524+
ret = nc_server_config_add_ch_ssh_hostkey(test_ctx->ctx, "ch_delete_test", "endpt", "hostkey",
525+
TESTS_DIR "/data/key_ecdsa", NULL, &tree);
526+
assert_int_equal(ret, 0);
527+
528+
ret = nc_server_config_add_ch_ssh_user_pubkey(test_ctx->ctx, "ch_delete_test", "endpt", "test_ch_delete",
529+
"pubkey", TESTS_DIR "/data/id_ed25519.pub", &tree);
530+
assert_int_equal(ret, 0);
531+
532+
ret = nc_server_config_setup_data(tree);
533+
assert_int_equal(ret, 0);
534+
535+
ret = nc_server_config_del_ch_client("ch_delete_test", &tree);
536+
assert_int_equal(ret, 0);
537+
538+
test_data->tree = tree;
539+
return 0;
540+
}
541+
542+
static void
543+
test_nc_ch_delete_client_while_session(void **state)
544+
{
545+
int ret, i;
546+
pthread_t tids[2];
547+
548+
assert_non_null(state);
549+
550+
ret = pthread_create(&tids[0], NULL, client_thread_delete_while_session, *state);
551+
assert_int_equal(ret, 0);
552+
553+
ret = pthread_create(&tids[1], NULL, server_thread_delete_while_session, *state);
554+
assert_int_equal(ret, 0);
555+
556+
for (i = 0; i < 2; i++) {
557+
pthread_join(tids[i], NULL);
558+
}
559+
}
560+
385561
int
386562
main(void)
387563
{
388564
const struct CMUnitTest tests[] = {
389565
cmocka_unit_test_setup_teardown(test_nc_ch_ssh, setup_ssh, ln2_glob_test_teardown),
390566
cmocka_unit_test_setup_teardown(test_nc_ch_tls, setup_tls, ln2_glob_test_teardown),
567+
cmocka_unit_test_setup_teardown(test_nc_ch_delete_client_while_session, setup_delete_while_session, ln2_glob_test_teardown),
391568
};
392569

393-
/* try to get ports from the environment, otherwise use the default */
394-
if (ln2_glob_test_get_ports(2, &TEST_PORT, &TEST_PORT_STR, &TEST_PORT_2, &TEST_PORT_2_STR)) {
570+
if (ln2_glob_test_get_ports(4, &TEST_PORT, &TEST_PORT_STR, &TEST_PORT_2, &TEST_PORT_2_STR,
571+
&TEST_PORT_3, &TEST_PORT_3_STR, &TEST_PORT_4, &TEST_PORT_4_STR)) {
395572
return 1;
396573
}
397574

0 commit comments

Comments
 (0)