<commit_before>/**
 * \file test_io.c
 * \author <NAME> <<EMAIL>>
 * \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 <messages_p.h>
#include "config.h"

struct nc_session session = {0};
struct nc_rpc *rpc = NULL;

static int
setup_f(void **state)
{
    (void) state; /* unused */
    int fd;

    session.ctx = ly_ctx_new(TESTS_DIR"/models");
    pthread_mutex_init(&session.ti_lock, NULL);

    /* ietf-netconf */
    fd = open(TESTS_DIR"/models/ietf-netconf.yin", O_RDONLY);
    if (fd == -1) {
        return -1;
    }

    lys_read(session.ctx, fd, LYS_IN_YIN);
    close(fd);

    return 0;
}

static int
teardown_f(void **state)
{
    (void) state; /* unused */

    if (rpc) {
        lyxml_free_elem(session.ctx, rpc->root);
        lyd_free(rpc->tree);
        free(rpc);
        rpc = NULL;
    }

    ly_ctx_destroy(session.ctx);

    return 0;
}

static void
test_read_rpc(void **state)
{
    (void) state; /* unused */
    NC_MSG_TYPE type;

    /* test IO with standard file descriptors */
    session.ti_type = NC_TI_FD;
    session.ti.fd.c = 0;
    session.side = NC_SIDE_SERVER;
    session.version = NC_VERSION_11;

    session.ti.fd.in = open(TESTS_DIR"/data/nc11/rpc-lock", O_RDONLY);
    if (session.ti.fd.in == -1) {
        fail_msg(" Openning \"%s\" failed (%s)", TESTS_DIR"/data/nc10/rpc-lock", strerror(errno));
    }

    type = nc_recv_rpc(&session, 1000, &rpc);
    assert_int_equal(type, NC_MSG_RPC);
    assert_non_null(rpc);

}

static void
test_write_rpc(void **state)
{
    (void) state; /* unused */
    NC_MSG_TYPE type;

    session.side = NC_SIDE_CLIENT;
    session.ti.fd.out = STDOUT_FILENO;

    do {
        type = nc_send_rpc(&session, rpc->tree, NULL);
    } while(type == NC_MSG_WOULDBLOCK);

    assert_int_equal(type, NC_MSG_RPC);

    write( session.ti.fd.out, "\n", 1);
}

int main(void)
{
    const struct CMUnitTest io[] = {
        cmocka_unit_test_setup(test_read_rpc, setup_f),
        cmocka_unit_test_teardown(test_write_rpc, teardown_f)};

    return cmocka_run_group_tests(io, NULL, NULL);
}
<commit_msg>tests CHANGE extend IO testing<commit_after>/**
 * \file test_io.c
 * \author <NAME> <<EMAIL>>
 * \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 <messages_p.h>
#include "config.h"

static void
free_rpc(struct nc_session *s, struct nc_rpc *rpc)
{
    if (rpc) {
        lyxml_free_elem(s->ctx, rpc->root);
        lyd_free(rpc->tree);
        free(rpc);
        rpc = NULL;
    }
}

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->ti.fd.c = 0;

    session->ctx = ly_ctx_new(TESTS_DIR"/models");
    pthread_mutex_init(&session->ti_lock, NULL);

    /* ietf-netconf */
    fd = open(TESTS_DIR"/models/ietf-netconf.yin", O_RDONLY);
    if (fd == -1) {
        return -1;
    }

    lys_read(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;

    close(session->ti.fd.in);
    close(session->ti.fd.out);

    ly_ctx_destroy(session->ctx);

    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 *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_SIDE_SERVER;

    type = nc_recv_rpc(session, 1000, &rpc);
    assert_int_equal(type, NC_MSG_RPC);
    assert_non_null(rpc);

    free_rpc(session, rpc);
}

static void
test_read_rpc_10_bad(void **state)
{
    struct nc_session *session = (struct nc_session *)*state;
    struct nc_rpc *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_SIDE_CLIENT;

    type = nc_recv_rpc(session, 1000, &rpc);
    assert_int_equal(type, NC_MSG_ERROR);
    assert_null(rpc);

    free_rpc(session, rpc);
}

static void
test_read_rpc_11(void **state)
{
    struct nc_session *session = (struct nc_session *)*state;
    struct nc_rpc *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_SIDE_SERVER;

    type = nc_recv_rpc(session, 1000, &rpc);
    assert_int_equal(type, NC_MSG_RPC);
    assert_non_null(rpc);

    free_rpc(session, rpc);
}

static void
test_read_rpc_11_bad(void **state)
{
    struct nc_session *session = (struct nc_session *)*state;
    struct nc_rpc *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_SIDE_CLIENT;

    type = nc_recv_rpc(session, 1000, &rpc);
    assert_int_equal(type, NC_MSG_ERROR);
    assert_null(rpc);

    free_rpc(session, rpc);
}


struct wr {
    struct nc_session *session;
    struct nc_rpc *rpc;
};

static int
setup_write(void **state)
{
    (void) state; /* unused */
    int fd;
    NC_MSG_TYPE type;
    struct wr *w;

    w = malloc(sizeof *w);
    w->session = calloc(1, sizeof *w->session);
    w->session->ctx = ly_ctx_new(TESTS_DIR"/models");
    pthread_mutex_init(&w->session->ti_lock, NULL);

    /* ietf-netconf */
    fd = open(TESTS_DIR"/models/ietf-netconf.yin", O_RDONLY);
    if (fd == -1) {
        return -1;
    }

    lys_read(w->session->ctx, fd, LYS_IN_YIN);
    close(fd);

    /* get rpc to write - TODO client side way */
    fd = open(TESTS_DIR"/data/nc10/rpc-lock", O_RDONLY);
    w->session->version = NC_VERSION_10;
    w->session->msgid = 999;
    w->session->ti_type = NC_TI_FD;
    w->session->ti.fd.c = 0;
    w->session->ti.fd.in = fd;

    type = nc_recv_rpc(w->session, 1000, &w->rpc);
    assert_int_equal(type, NC_MSG_RPC);
    assert_non_null(w->rpc);

    close(fd);
    w->session->ti.fd.in = -1;

    *state = w;

    return 0;
}

static int
teardown_write(void **state)
{
    struct wr *w = (struct wr *)*state;

    if (w->session->ti.fd.in != -1) {
        close(w->session->ti.fd.in);
    }
    if (w->session->ti.fd.out != -1) {
        close(w->session->ti.fd.out);
    }

    free_rpc(w->session, w->rpc);
    ly_ctx_destroy(w->session->ctx);

    free(w->session);
    free(w);
    *state = NULL;

    return 0;
}

static void
test_write_rpc(void **state)
{
    struct wr *w = (struct wr *)*state;
    NC_MSG_TYPE type;

    w->session->side = NC_SIDE_CLIENT;
    w->session->ti_type = NC_TI_FD;
    w->session->ti.fd.c = 0;
    w->session->ti.fd.out = STDOUT_FILENO;

    do {
        type = nc_send_rpc(w->session, w->rpc->tree, NULL);
    } while(type == NC_MSG_WOULDBLOCK);

    assert_int_equal(type, NC_MSG_RPC);

    write(w->session->ti.fd.out, "\n", 1);

    w->session->ti.fd.out = -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;
    NC_MSG_TYPE type;

    w->session->side = NC_SIDE_SERVER;
    w->session->ti_type = NC_TI_FD;
    w->session->ti.fd.c = 0;
    w->session->ti.fd.out = STDOUT_FILENO;

    do {
        type = nc_send_rpc(w->session, w->rpc->tree, NULL);
    } while(type == NC_MSG_WOULDBLOCK);

    assert_int_equal(type, NC_MSG_ERROR);

    w->session->ti.fd.out = -1;
}

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);
}

{'fraction_non_alphanumeric': 0.13328510715254543, 'fraction_numerical': 0.012388100189890587, 'mean_word_length': 3.3203125, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 135, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3691936', 'n_tokens_mistral': 4246, 'n_tokens_neox': 4056, 'n_words': 900}