blob: a6c81d73a300f647786124b5b5adc48d7142f7c1 [file] [log] [blame]
roman83683fb2023-02-24 09:15:23 +01001/**
Roytakb2794852023-10-18 14:30:22 +02002 * @file test_unix_socket.c
roman83683fb2023-02-24 09:15:23 +01003 * @author Roman Janota <xjanot04@fit.vutbr.cz>
Roytakb2794852023-10-18 14:30:22 +02004 * @brief libnetconf2 UNIX socket test
roman83683fb2023-02-24 09:15:23 +01005 *
6 * @copyright
7 * Copyright (c) 2022 CESNET, z.s.p.o.
8 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
15
roman9b1379c2023-03-31 10:11:10 +020016#define _GNU_SOURCE
17
roman83683fb2023-02-24 09:15:23 +010018#include <errno.h>
19#include <pthread.h>
20#include <setjmp.h>
roman9b1379c2023-03-31 10:11:10 +020021#include <stdarg.h>
roman83683fb2023-02-24 09:15:23 +010022#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <cmocka.h>
27
roman83683fb2023-02-24 09:15:23 +010028#include "tests/config.h"
29
30#define NC_ACCEPT_TIMEOUT 2000
31#define NC_PS_POLL_TIMEOUT 2000
32
33struct ly_ctx *ctx;
34
35struct test_state {
36 pthread_barrier_t barrier;
37};
38
roman83683fb2023-02-24 09:15:23 +010039static void *
40server_thread(void *arg)
41{
42 int ret;
43 NC_MSG_TYPE msgtype;
44 struct nc_session *session;
45 struct nc_pollsession *ps;
46 struct test_state *state = arg;
47
48 ps = nc_ps_new();
49 assert_non_null(ps);
50
51 /* accept a session and add it to the poll session structure */
52 pthread_barrier_wait(&state->barrier);
53 msgtype = nc_accept(NC_ACCEPT_TIMEOUT, ctx, &session);
54 assert_int_equal(msgtype, NC_MSG_HELLO);
55
56 ret = nc_ps_add_session(ps, session);
57 assert_int_equal(ret, 0);
58
59 do {
60 ret = nc_ps_poll(ps, NC_PS_POLL_TIMEOUT, NULL);
61 assert_int_equal(ret & NC_PSPOLL_RPC, NC_PSPOLL_RPC);
62 } while (!(ret & NC_PSPOLL_SESSION_TERM));
63
64 nc_ps_clear(ps, 1, NULL);
65 nc_ps_free(ps);
roman83683fb2023-02-24 09:15:23 +010066 return NULL;
67}
68
69static void *
70client_thread(void *arg)
71{
roman3f9b65c2023-06-05 14:26:58 +020072 int ret = 0;
roman83683fb2023-02-24 09:15:23 +010073 struct nc_session *session = NULL;
74 struct test_state *state = arg;
75
roman3f9b65c2023-06-05 14:26:58 +020076 ret = nc_client_set_schema_searchpath(MODULES_DIR);
77 assert_int_equal(ret, 0);
78
roman83683fb2023-02-24 09:15:23 +010079 pthread_barrier_wait(&state->barrier);
80 session = nc_connect_unix("/tmp/nc2_test_unix_sock", NULL);
81 assert_non_null(session);
82
83 nc_session_free(session, NULL);
roman83683fb2023-02-24 09:15:23 +010084 return NULL;
85}
86
87static void
88test_nc_connect_unix_socket(void **state)
89{
90 int ret, i;
91 pthread_t tids[2];
92
93 assert_non_null(state);
94
95 ret = pthread_create(&tids[0], NULL, client_thread, *state);
96 assert_int_equal(ret, 0);
97 ret = pthread_create(&tids[1], NULL, server_thread, *state);
98 assert_int_equal(ret, 0);
99
100 for (i = 0; i < 2; i++) {
101 pthread_join(tids[i], NULL);
102 }
103}
104
105static int
106setup_f(void **state)
107{
108 int ret;
romand0b78372023-09-14 10:06:03 +0200109 struct lyd_node *tree = NULL;
roman83683fb2023-02-24 09:15:23 +0100110 struct test_state *test_state;
111
112 nc_verbosity(NC_VERB_VERBOSE);
113
114 /* init barrier */
115 test_state = malloc(sizeof *test_state);
116 assert_non_null(test_state);
117
118 ret = pthread_barrier_init(&test_state->barrier, NULL, 2);
119 assert_int_equal(ret, 0);
120
121 *state = test_state;
122
123 ret = ly_ctx_new(MODULES_DIR, 0, &ctx);
124 assert_int_equal(ret, 0);
125
126 /* initialize context */
127 ret = nc_server_init_ctx(&ctx);
128 assert_int_equal(ret, 0);
129
romand0b78372023-09-14 10:06:03 +0200130 /* create the UNIX socket */
romanfb3f7cf2023-11-30 16:10:09 +0100131 ret = nc_server_add_endpt_unix_socket_listen("unix", "/tmp/nc2_test_unix_sock", 0700, -1, -1);
roman83683fb2023-02-24 09:15:23 +0100132 assert_int_equal(ret, 0);
133
roman83683fb2023-02-24 09:15:23 +0100134 /* initialize server */
135 ret = nc_server_init();
136 assert_int_equal(ret, 0);
137
romand0b78372023-09-14 10:06:03 +0200138 /* initialize client */
139 ret = nc_client_init();
140 assert_int_equal(ret, 0);
roman83683fb2023-02-24 09:15:23 +0100141
romand0b78372023-09-14 10:06:03 +0200142 lyd_free_all(tree);
roman83683fb2023-02-24 09:15:23 +0100143 return 0;
144}
145
146static int
147teardown_f(void **state)
148{
149 int ret = 0;
150 struct test_state *test_state;
151
152 assert_non_null(state);
153 test_state = *state;
154
155 ret = pthread_barrier_destroy(&test_state->barrier);
156 assert_int_equal(ret, 0);
157
158 free(*state);
159 nc_client_destroy();
160 nc_server_destroy();
161 ly_ctx_destroy(ctx);
162
163 return 0;
164}
165
166int
167main(void)
168{
169 const struct CMUnitTest tests[] = {
170 cmocka_unit_test_setup_teardown(test_nc_connect_unix_socket, setup_f, teardown_f),
171 };
172
173 setenv("CMOCKA_TEST_ABORT", "1", 1);
174 return cmocka_run_group_tests(tests, NULL, NULL);
175}