188 lines
4.1 KiB
C
188 lines
4.1 KiB
C
/**
|
|
* \file test_io.c
|
|
* \author Radek Krejci <rkrejci@cesnet.cz>
|
|
* \brief libnetconf2 tests - input/output functions
|
|
*
|
|
* Copyright (c) 2015 CESNET, z.s.p.o.
|
|
*
|
|
* This source code is licensed under BSD 3-Clause License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include <setjmp.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include <cmocka.h>
|
|
#include <libyang/libyang.h>
|
|
|
|
#include <messages_p.h>
|
|
#include <session_p.h>
|
|
|
|
#include "ln2_test.h"
|
|
|
|
struct wr {
|
|
struct nc_session *session;
|
|
struct nc_rpc *rpc;
|
|
};
|
|
|
|
static int
|
|
setup_write(void **state)
|
|
{
|
|
(void) state; /* unused */
|
|
int fd, pipes[2];
|
|
struct wr *w;
|
|
|
|
w = malloc(sizeof *w);
|
|
w->session = calloc(1, sizeof *w->session);
|
|
ly_ctx_new(TESTS_DIR "/data/modules", 0, &w->session->ctx);
|
|
|
|
/* ietf-netconf */
|
|
fd = open(TESTS_DIR "/data/modules/ietf-netconf.yin", O_RDONLY);
|
|
if (fd == -1) {
|
|
free(w);
|
|
return -1;
|
|
}
|
|
|
|
lys_parse_fd(w->session->ctx, fd, LYS_IN_YIN, NULL);
|
|
close(fd);
|
|
|
|
assert_return_code(pipe(pipes), errno);
|
|
|
|
w->session->status = NC_STATUS_RUNNING;
|
|
w->session->version = NC_VERSION_10;
|
|
w->session->opts.client.msgid = 999;
|
|
w->session->ti_type = NC_TI_FD;
|
|
w->session->io_lock = malloc(sizeof *w->session->io_lock);
|
|
pthread_mutex_init(w->session->io_lock, NULL);
|
|
w->session->ti.fd.in = pipes[0];
|
|
w->session->ti.fd.out = pipes[1];
|
|
|
|
/* get rpc to write */
|
|
w->rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
|
|
assert_non_null(w->rpc);
|
|
|
|
*state = w;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
teardown_write(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
|
|
nc_rpc_free(w->rpc);
|
|
close(w->session->ti.fd.in);
|
|
w->session->ti.fd.in = -1;
|
|
close(w->session->ti.fd.out);
|
|
w->session->ti.fd.out = -1;
|
|
nc_session_free(w->session, NULL);
|
|
free(w);
|
|
*state = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
test_write_rpc(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
uint64_t msgid;
|
|
NC_MSG_TYPE type;
|
|
|
|
w->session->side = NC_CLIENT;
|
|
|
|
do {
|
|
type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
|
|
} while (type == NC_MSG_WOULDBLOCK);
|
|
|
|
assert_int_equal(type, NC_MSG_RPC);
|
|
|
|
assert_int_equal(write(w->session->ti.fd.out, "\n", 1), 1);
|
|
}
|
|
|
|
static void
|
|
test_write_rpc_10(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
|
|
w->session->version = NC_VERSION_10;
|
|
|
|
return test_write_rpc(state);
|
|
}
|
|
|
|
static void
|
|
test_write_rpc_11(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
|
|
w->session->version = NC_VERSION_11;
|
|
|
|
return test_write_rpc(state);
|
|
}
|
|
|
|
static void
|
|
test_write_rpc_bad(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
uint64_t msgid;
|
|
NC_MSG_TYPE type;
|
|
|
|
w->session->side = NC_SERVER;
|
|
pthread_mutex_init(&w->session->opts.server.rpc_lock, NULL);
|
|
pthread_cond_init(&w->session->opts.server.rpc_cond, NULL);
|
|
w->session->opts.server.rpc_inuse = 0;
|
|
|
|
do {
|
|
type = nc_send_rpc(w->session, w->rpc, 1000, &msgid);
|
|
} while (type == NC_MSG_WOULDBLOCK);
|
|
|
|
assert_int_equal(type, NC_MSG_ERROR);
|
|
}
|
|
|
|
static void
|
|
test_write_rpc_10_bad(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
|
|
w->session->version = NC_VERSION_10;
|
|
|
|
return test_write_rpc_bad(state);
|
|
}
|
|
|
|
static void
|
|
test_write_rpc_11_bad(void **state)
|
|
{
|
|
struct wr *w = (struct wr *)*state;
|
|
|
|
w->session->version = NC_VERSION_11;
|
|
|
|
return test_write_rpc_bad(state);
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
const struct CMUnitTest io[] = {
|
|
cmocka_unit_test_setup_teardown(test_write_rpc_10, setup_write, teardown_write),
|
|
cmocka_unit_test_setup_teardown(test_write_rpc_10_bad, setup_write, teardown_write),
|
|
cmocka_unit_test_setup_teardown(test_write_rpc_11, setup_write, teardown_write),
|
|
cmocka_unit_test_setup_teardown(test_write_rpc_11_bad, setup_write, teardown_write)
|
|
};
|
|
|
|
return cmocka_run_group_tests(io, NULL, NULL);
|
|
}
|