blob: 1a86c082f7a2e26a30d9d42a07475dc1b8063dbe [file] [log] [blame]
/**
* \file test_io.c
* \author Radek Krejci <rkrejci@cesnet.cz>
* \brief libnetconf2 tests - input/output functions
*
* Copyright (c) 2015 CESNET, z.s.p.o.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the Company nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
*/
#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 <cmocka.h>
#include <libyang/libyang.h>
#include <session_p.h>
#include <session_client.h>
#include <messages_p.h>
#include "config.h"
/*static int
setup_read(void **state)
{
int fd;
struct nc_session *session;
session = calloc(1, sizeof *session);
* test IO with standard file descriptors *
session->ti_type = NC_TI_FD;
session->status = NC_STATUS_RUNNING;
session->ctx = ly_ctx_new(TESTS_DIR"../schemas");
session->ti_lock = malloc(sizeof *session->ti_lock);
pthread_mutex_init(session->ti_lock, NULL);
* ietf-netconf *
fd = open(TESTS_DIR"../schemas/ietf-netconf.yin", O_RDONLY);
if (fd == -1) {
return -1;
}
lys_parse_fd(session->ctx, fd, LYS_IN_YIN);
close(fd);
*state = session;
return 0;
}
static int
teardown_read(void **state)
{
struct nc_session *session = (struct nc_session *)*state;
nc_session_free(session);
*state = NULL;
return 0;
}
static void
test_read_rpc_10(void **state)
{
struct nc_session *session = (struct nc_session *)*state;
struct nc_rpc_server *rpc = NULL;
NC_MSG_TYPE type;
session->ti.fd.in = open(TESTS_DIR"/data/nc10/rpc-lock", O_RDONLY);
session->version = NC_VERSION_10;
session->side = NC_SERVER;
type = nc_recv_rpc(session, 1000, &rpc);
assert_int_equal(type, NC_MSG_RPC);
assert_non_null(rpc);
nc_rpc_free((struct nc_rpc *)rpc);
}
static void
test_read_rpc_10_bad(void **state)
{
struct nc_session *session = (struct nc_session *)*state;
struct nc_rpc_server *rpc = NULL;
NC_MSG_TYPE type;
session->ti.fd.in = open(TESTS_DIR"/data/nc10/rpc-lock", O_RDONLY);
session->version = NC_VERSION_10;
session->side = NC_CLIENT;
type = nc_recv_rpc(session, 1000, &rpc);
assert_int_equal(type, NC_MSG_ERROR);
assert_null(rpc);
nc_rpc_free((struct nc_rpc *)rpc);
}
static void
test_read_rpc_11(void **state)
{
struct nc_session *session = (struct nc_session *)*state;
struct nc_rpc_server *rpc = NULL;
NC_MSG_TYPE type;
session->ti.fd.in = open(TESTS_DIR"/data/nc11/rpc-lock", O_RDONLY);
session->version = NC_VERSION_11;
session->side = NC_SERVER;
type = nc_recv_rpc(session, 1000, &rpc);
assert_int_equal(type, NC_MSG_RPC);
assert_non_null(rpc);
nc_rpc_free((struct nc_rpc *)rpc);
}
static void
test_read_rpc_11_bad(void **state)
{
struct nc_session *session = (struct nc_session *)*state;
struct nc_rpc_server *rpc = NULL;
NC_MSG_TYPE type;
session->ti.fd.in = open(TESTS_DIR"/data/nc11/rpc-lock", O_RDONLY);
session->version = NC_VERSION_11;
session->side = NC_CLIENT;
type = nc_recv_rpc(session, 1000, &rpc);
assert_int_equal(type, NC_MSG_ERROR);
assert_null(rpc);
nc_rpc_free((struct nc_rpc *)rpc);
}*/
struct wr {
struct nc_session *session;
struct nc_rpc *rpc;
};
static int
setup_write(void **state)
{
(void) state; /* unused */
int fd;
struct wr *w;
w = malloc(sizeof *w);
w->session = calloc(1, sizeof *w->session);
w->session->ctx = ly_ctx_new(TESTS_DIR"../schemas");
w->session->ti_lock = malloc(sizeof *w->session->ti_lock);
pthread_mutex_init(w->session->ti_lock, NULL);
/* ietf-netconf */
fd = open(TESTS_DIR"../schemas/ietf-netconf.yin", O_RDONLY);
if (fd == -1) {
free(w);
return -1;
}
lys_parse_fd(w->session->ctx, fd, LYS_IN_YIN);
close(fd);
w->session->status = NC_STATUS_RUNNING;
w->session->version = NC_VERSION_10;
w->session->msgid = 999;
w->session->ti_type = NC_TI_FD;
w->session->ti.fd.in = STDIN_FILENO;
w->session->ti.fd.out = STDOUT_FILENO;
/* get rpc to write */
w->rpc = nc_rpc_lock(NC_DATASTORE_RUNNING);
assert_non_null(w->rpc);
w->session->ti.fd.in = -1;
*state = w;
return 0;
}
static int
teardown_write(void **state)
{
struct wr *w = (struct wr *)*state;
nc_rpc_free(w->rpc);
w->session->ti.fd.in = -1;
w->session->ti.fd.out = -1;
nc_session_free(w->session);
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);
write(w->session->ti.fd.out, "\n", 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;
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_read_rpc_10, setup_read, teardown_read),
cmocka_unit_test_setup_teardown(test_read_rpc_10_bad, setup_read, teardown_read),
cmocka_unit_test_setup_teardown(test_read_rpc_11, setup_read, teardown_read),
cmocka_unit_test_setup_teardown(test_read_rpc_11_bad, setup_read, teardown_read),*/
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);
}