Пример #1
0
static void
test_periodic_timer(void)
{
    int count;

    /* Should fire every 'repeat_time_ms' */
    count = 0;
    ind_soc_timer_event_register(timer_callback, &count, 100);
    ind_soc_select_and_run(1000);
    INDIGO_ASSERT(count >= 9 && count <= 11);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback, &count) == 0);

    /* A timer may re-register itself with a different period during its callback */
    count = 0;
    ind_soc_timer_event_register(timer_callback_reregister, &count, 100);
    ind_soc_select_and_run(1000);
    INDIGO_ASSERT(count > 50 && count < 100);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback_reregister, &count) == 0);

    /* A timer may unregister itself during its callback */
    count = 0;
    ind_soc_timer_event_register(timer_callback_unregister, &count, 100);
    ind_soc_select_and_run(1000);
    INDIGO_ASSERT(count == 1);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback_unregister, &count) < 0);
}
Пример #2
0
int main(int argc, char* argv[])
{
    int cxn_id;
    int idx;
    ind_soc_config_t config; /* Currently ignored */

    INDIGO_MEM_CLEAR(&config, sizeof(config));
    OK(ind_soc_init(&config));

    OK(ind_cxn_init(&cm_config));

    OK(indigo_cxn_status_change_register(cxn_status_change, NULL));

    OK(ind_cxn_enable_set(1));
    INDIGO_ASSERT((cxn_id = setup_cxn()) >= 0);

    for (idx = 1; idx < 5; idx++) {
        printf("run %d\n", idx);
        OK(ind_soc_select_and_run(2000));
    }

    /* Now remove and add the cxn a few times */
    for (idx = 1; idx < 5; idx++) {
        OK(indigo_cxn_connection_remove(cxn_id));
        INDIGO_ASSERT((cxn_id = setup_cxn()) >= 0);
    }

    OK(indigo_cxn_connection_remove(cxn_id));

    OK(ind_cxn_enable_set(0));
    OK(ind_cxn_finish());

    return 0;
}
Пример #3
0
int
main(int argc, char* argv[])
{
    ind_soc_config_t config = {0};
    int fds[2];

    printf("Init returned %d\n", ind_soc_init(&config));

    /* Should be called once */
    ind_soc_timer_event_register(timer_callback, NULL,
                                 IND_SOC_TIMER_IMMEDIATE);
    ind_soc_select_and_run(10);
    INDIGO_ASSERT(timer_called);
    timer_called = 0;
    ind_soc_select_and_run(1000);
    INDIGO_ASSERT(!timer_called);

    ind_soc_timer_event_register(timer_callback, NULL, 100);
    ind_soc_select_and_run(1000);
    INDIGO_ASSERT(timer_called);

    timer_called = 0;
    ind_soc_timer_event_register(timer_callback_repeat, NULL, 100);
    ind_soc_select_and_run(1000);
    INDIGO_ASSERT(timer_called >= 9);
    ind_soc_timer_event_unregister(timer_callback_repeat, NULL);

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
        perror("socketpair");
        abort();
    }

    INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, NULL) == 0);
    INDIGO_ASSERT(ind_soc_socket_register(fds[1], socket_callback, NULL) == 0);
    ind_soc_data_out_ready(fds[0]);
    ind_soc_data_out_ready(fds[1]);
    /* Do stuff for 3 seconds */
    ind_soc_select_and_run(3000);

    INDIGO_ASSERT(socket_called > 0);
    INDIGO_ASSERT(sock_read_seen > 0);
    INDIGO_ASSERT(sock_write_seen > 0);

    return 0;
}
Пример #4
0
static void
test_immediate_timer(void)
{
    int count = 0;
    INDIGO_ASSERT(ind_soc_timer_event_register(
                      timer_callback, &count, IND_SOC_TIMER_IMMEDIATE) == 0);

    /* Should run immediately */
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(count == 1);

    /* Should be unregistered after firing */
    count = 0;
    ind_soc_select_and_run(100);
    INDIGO_ASSERT(count == 0);

    /* Should be unregistered after firing */
    INDIGO_ASSERT(ind_soc_timer_event_unregister(timer_callback, &count) < 0);
}
Пример #5
0
int
aim_main(int argc, char *argv[])
{
    set_crash_handler(crash_handler);

    AIM_LOG_STRUCT_REGISTER();

    loci_logger = ofagent_loci_logger;

    core_cfg.stats_check_ms = 900;

    parse_options(argc, argv);

    /* Setup logging from command line options */
    if (loglevel >= LOGLEVEL_DEFAULT) {
        aim_log_fid_set_all(AIM_LOG_FLAG_MSG, 1);
        aim_log_fid_set_all(AIM_LOG_FLAG_FATAL, 1);
        aim_log_fid_set_all(AIM_LOG_FLAG_ERROR, 1);
        aim_log_fid_set_all(AIM_LOG_FLAG_WARN, 1);
    }

    if (loglevel >= LOGLEVEL_VERBOSE) {
        aim_log_fid_set_all(AIM_LOG_FLAG_VERBOSE, 1);
    }

    if (loglevel >= LOGLEVEL_TRACE) {
        aim_log_fid_set_all(AIM_LOG_FLAG_TRACE, 1);
    }

    if (use_syslog) {
        aim_log_pvs_set_all(aim_pvs_syslog_open("ofagent", LOG_NDELAY, LOG_DAEMON));
    }

    create_pidfile();

    AIM_LOG_MSG("Starting ofagent %s (%s %s) pid %d",
            ofagent_version, ofagent_build_id, ofagent_build_os, getpid());

    /* Increase maximum number of file descriptors */
    struct rlimit rlim = {
        .rlim_cur = SOCKETMANAGER_CONFIG_MAX_SOCKETS,
        .rlim_max = SOCKETMANAGER_CONFIG_MAX_SOCKETS
    };
    if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
        AIM_LOG_WARN("Failed to increase RLIMIT_NOFILE");
    }

    /* Initialize all modules */
    if (ind_soc_init(&soc_cfg) < 0) {
        AIM_LOG_FATAL("Failed to initialize Indigo socket manager");
        return 1;
    }

    if (ind_cxn_init(&cxn_cfg) < 0) {
        AIM_LOG_FATAL("Failed to initialize Indigo connection manager");
        return 1;
    }

    if (ind_core_init(&core_cfg) < 0) {
        AIM_LOG_FATAL("Failed to initialize Indigo core module");
        return 1;
    }

    if (bcm_driver_init() < 0) {
        AIM_LOG_FATAL("Failed to initialize BCM driver");
        return 1;
    }

    if (pipeline == NULL) {
        if (openflow_version == NULL || !strcmp(openflow_version, "1.0")) {
            pipeline = "standard-1.0";
        } else if (!strcmp(openflow_version, "1.3")) {
            pipeline = "standard-1.3";
        } else {
            AIM_DIE("unexpected OpenFlow version");
        }
    }

    AIM_LOG_VERBOSE("Initializing forwarding pipeline '%s'", pipeline);
    indigo_error_t rv = pipeline_set(pipeline);
    if (rv < 0) {
        AIM_LOG_FATAL("Failed to set pipeline: %s", indigo_strerror(rv));
        return 1;
    }

    if (config_filename) {
        ind_cfg_filename_set(config_filename);
        if (ind_cfg_load() < 0) {
            AIM_LOG_FATAL("Failed to load configuration file");
            return 1;
        }
    }

    if (dpid) {
        indigo_core_dpid_set(dpid);
    }

    /* Enable all modules */
    if (ind_soc_enable_set(1) < 0) {
        AIM_LOG_FATAL("Failed to enable Indigo socket manager");
        return 1;
    }

    if (ind_cxn_enable_set(1) < 0) {
        AIM_LOG_FATAL("Failed to enable Indigo connection manager");
        return 1;
    }

    if (ind_core_enable_set(1) < 0) {
        AIM_LOG_FATAL("Failed to enable Indigo core module");
        return 1;
    }

    if (bcm_driver_enable_set(1) < 0) {
        AIM_LOG_FATAL("Failed to enable BCM driver");
        return 1;
    }

    /* Add controller from command line */
    {
        biglist_t *element;
        char *str;
        BIGLIST_FOREACH_DATA(element, controllers, char *, str) {
            AIM_LOG_VERBOSE("Adding controller %s", str);

            indigo_cxn_protocol_params_t proto;
            if (parse_controller(str, &proto, OF_TCP_PORT) < 0) {
                AIM_LOG_FATAL("Failed to parse controller string '%s'", str);
                return 1;
            }

            indigo_cxn_config_params_t config = {
                .version = OF_VERSION_1_0,
                .cxn_priority = 0,
                .local = 0,
                .listen = 0,
                .periodic_echo_ms = 2000,
                .reset_echo_count = 3,
            };

            indigo_controller_id_t id;
            if (indigo_controller_add(&proto, &config, &id) < 0) {
                AIM_LOG_FATAL("Failed to add controller %s", str);
                return 1;
            }
        }
    }

    ind_core_mfr_desc_set(mfr_desc);

    snprintf(sw_desc, sizeof(sw_desc),
            "ofagent %s %s %s", ofagent_version,
            ofagent_build_id, ofagent_build_os);
    ind_core_sw_desc_set(sw_desc);

    // TODO
    //read_hardware_version(hw_desc);
    ind_core_hw_desc_set(hw_desc);

    char hostname[256];
    char domainname[256];
    if (gethostname(hostname, sizeof(hostname))) {
        sprintf(hostname, "(unknown)");
    }
    if (getdomainname(domainname, sizeof(domainname))) {
        sprintf(domainname, "(unknown)");
    }
    snprintf(dp_desc, sizeof(dp_desc), "%s.%s pid %d",
             hostname, domainname, getpid());
    ind_core_dp_desc_set(dp_desc);

    AIM_LOG_INFO("Datapath description: %s", dp_desc);

    ind_core_serial_num_set(serial_num);

    /* The SIGHUP handler triggers sighup_callback to run in the main loop. */
    if ((sighup_eventfd = eventfd(0, 0)) < 0) {
        AIM_LOG_FATAL("Failed to allocate eventfd");
        abort();
    }
    signal(SIGHUP, sighup);
    if (ind_soc_socket_register(sighup_eventfd, sighup_callback, NULL) < 0) {
        abort();
    }

    /* The SIGTERM handler triggers sigterm_callback to run in the main loop. */
    if ((sigterm_eventfd = eventfd(0, 0)) < 0) {
        AIM_LOG_FATAL("Failed to allocate eventfd");
        abort();
    }
    signal(SIGTERM, sigterm);
    if (ind_soc_socket_register(sigterm_eventfd, sigterm_callback, NULL) < 0) {
        abort();
    }

    /* TODO Start handling upcalls */
    //ind_ovs_enable();

    //packet_trace_init(datapath_name);

    ind_soc_select_and_run(-1);

    AIM_LOG_MSG("Stopping ofagent %s", ofagent_version);

    ind_core_finish();
    bcm_driver_finish();
    ind_cxn_finish();
    ind_soc_finish();

    return 0;
}
Пример #6
0
static void
test_socket(void)
{
    int fds[2];
    struct sock_counters counters[2];
    indigo_time_t start_time, end_time;
    struct itimerval itv;

    signal(SIGALRM, sigalrm);

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
        perror("socketpair");
        abort();
    }

    INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_register(fds[1], socket_callback, &counters[1]) == 0);

    /* No events ready */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Write one byte to fds[0] */
    ind_soc_data_out_ready(fds[0]);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Read one byte from fds[1] */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 1);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Write one byte to each of fds[0] and fds[1] */
    ind_soc_data_out_ready(fds[0]);
    ind_soc_data_out_ready(fds[1]);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 1);

    /* Read one byte from each of fds[0] and fds[1] */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 1);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 1);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Write one byte to fds[0] */
    ind_soc_data_out_ready(fds[0]);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Pause data in from fds[1], expect no reads */
    ind_soc_data_in_pause(fds[1]);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Resume data in from fds[1] */
    ind_soc_data_in_resume(fds[1]);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 1);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Block for some time with no events */
    memset(counters, 0, sizeof(counters));
    start_time = INDIGO_CURRENT_TIME;
    ind_soc_select_and_run(100);
    end_time = INDIGO_CURRENT_TIME;
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);
    INDIGO_ASSERT((end_time - start_time) >= 100 &&
                  (end_time - start_time) < 200);

    /* Block for some time until SIGALRM, which causes read ready on fd[1] */
    memset(counters, 0, sizeof(counters));
    memset(&itv, 0, sizeof(itv));
    sigalrm_write_fd = fds[0];
    itv.it_value.tv_usec = 100*1000;
    setitimer(ITIMER_REAL, &itv, NULL);
    ind_soc_select_and_run(200);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 1);
    INDIGO_ASSERT(counters[1].write == 0);

    INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(fds[1]) == 0);

    close(fds[0]);
    close(fds[1]);
}
Пример #7
0
static void
test_priority(void)
{
    int read_fds[3], write_fds[3];
    struct sock_counters counters[3];
    int timer_counters[3];
    int task_counters[3];
    int i;

    task_counter_limit = 1;

    for (i = 0; i < 3; i++) {
        int fds[2];
        if (pipe(fds) < 0) {
            perror("pipe");
            abort();
        }
        read_fds[i] = fds[0];
        write_fds[i] = fds[1];
    }

    /* High priority */
    INDIGO_ASSERT(ind_soc_socket_register_with_priority(
                      read_fds[0], socket_callback, &counters[0], IND_SOC_HIGH_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_timer_event_register_with_priority(
                      timer_callback, &timer_counters[0], IND_SOC_TIMER_IMMEDIATE, IND_SOC_HIGH_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[0], IND_SOC_HIGH_PRIORITY) == 0);

    /* Medium priority */
    INDIGO_ASSERT(ind_soc_socket_register_with_priority(
                      read_fds[1], socket_callback, &counters[1], IND_SOC_NORMAL_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_timer_event_register_with_priority(
                      timer_callback, &timer_counters[1], IND_SOC_TIMER_IMMEDIATE, IND_SOC_NORMAL_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[1], IND_SOC_NORMAL_PRIORITY) == 0);

    /* Low priority */
    INDIGO_ASSERT(ind_soc_socket_register_with_priority(
                      read_fds[2], socket_callback, &counters[2], IND_SOC_LOW_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_timer_event_register_with_priority(
                      timer_callback, &timer_counters[2], IND_SOC_TIMER_IMMEDIATE, IND_SOC_LOW_PRIORITY) == 0);

    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[2], IND_SOC_LOW_PRIORITY) == 0);

    /* Make all sockets ready */
    for (i = 0; i < 3; i++) {
        write(write_fds[i], "x", 1);
    }

    /* Higher priority events should run first */
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[2].read == 0);
    INDIGO_ASSERT(timer_counters[0] == 1);
    INDIGO_ASSERT(timer_counters[1] == 0);
    INDIGO_ASSERT(timer_counters[2] == 0);
    INDIGO_ASSERT(task_counters[0] == 1);
    INDIGO_ASSERT(task_counters[1] == 0);
    INDIGO_ASSERT(task_counters[2] == 0);

    /* Medium priority events should run next */
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[1].read == 1);
    INDIGO_ASSERT(counters[2].read == 0);
    INDIGO_ASSERT(timer_counters[0] == 0);
    INDIGO_ASSERT(timer_counters[1] == 1);
    INDIGO_ASSERT(timer_counters[2] == 0);
    INDIGO_ASSERT(task_counters[0] == 0);
    INDIGO_ASSERT(task_counters[1] == 1);
    INDIGO_ASSERT(task_counters[2] == 0);

    /* New high priority events should run next */
    write(write_fds[0], "x", 1);
    INDIGO_ASSERT(ind_soc_task_register(
                      task_callback, &task_counters[0], IND_SOC_HIGH_PRIORITY) == 0);
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 1);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[2].read == 0);
    INDIGO_ASSERT(timer_counters[0] == 0);
    INDIGO_ASSERT(timer_counters[1] == 0);
    INDIGO_ASSERT(timer_counters[2] == 0);
    INDIGO_ASSERT(task_counters[0] == 1);
    INDIGO_ASSERT(task_counters[1] == 0);
    INDIGO_ASSERT(task_counters[2] == 0);

    /* Low priority events should run last */
    memset(counters, 0, sizeof(counters));
    memset(timer_counters, 0, sizeof(timer_counters));
    memset(task_counters, 0, sizeof(task_counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[2].read == 1);
    INDIGO_ASSERT(timer_counters[0] == 0);
    INDIGO_ASSERT(timer_counters[1] == 0);
    INDIGO_ASSERT(timer_counters[2] == 1);
    INDIGO_ASSERT(task_counters[0] == 0);
    INDIGO_ASSERT(task_counters[1] == 0);
    INDIGO_ASSERT(task_counters[2] == 1);

    INDIGO_ASSERT(ind_soc_socket_unregister(read_fds[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(read_fds[1]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(read_fds[2]) == 0);

    /* One-shot timers, already unregistered */
    INDIGO_ASSERT(ind_soc_timer_event_unregister(
                      timer_callback, &timer_counters[0]) < 0);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(
                      timer_callback, &timer_counters[1]) < 0);
    INDIGO_ASSERT(ind_soc_timer_event_unregister(
                      timer_callback, &timer_counters[3]) < 0);

    for (i = 0; i < 3; i++) {
        close(read_fds[i]);
        close(write_fds[i]);
    }
}
Пример #8
0
static void
test_task(void)
{
    int counters[2];
    int i;

    task_counter_limit = 3;

    INDIGO_ASSERT(ind_soc_task_register(task_callback, &counters[0], 0) == INDIGO_ERROR_NONE);

    /* Task should immediately run */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0] == 1);

    /* Task should keep running */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0] == 1);

    INDIGO_ASSERT(ind_soc_task_register(task_callback, &counters[1], 0) == INDIGO_ERROR_NONE);

    /* Both tasks should run until the counter == 3 */
    memset(counters, 0, sizeof(counters));
    for (i = 1; i <= 3; i++) {
        ind_soc_select_and_run(0);
        INDIGO_ASSERT(counters[0] == i);
        INDIGO_ASSERT(counters[1] == i);
    }

    /* No tasks should run after finishing */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0] == 0);
    INDIGO_ASSERT(counters[1] == 0);

    /* Task should yield after 10 ms */
    INDIGO_ASSERT(ind_soc_task_register(task_callback_yield, &counters[0], 0) == INDIGO_ERROR_NONE);
    memset(counters, 0, sizeof(counters));
    i = 0;
    while (counters[0] < 100) {
        int tmp;
        tmp = counters[0];
        ind_soc_select_and_run(0);
        tmp = counters[0] - tmp;
        INDIGO_ASSERT(tmp <= 10); /* 10 ms/timeslice / 1+ ms/unit <= 10 units/timeslice */
        i++;
    }
    INDIGO_ASSERT(i >= 10); /* (100 units * 1+ ms/unit) / 10 ms/timeslice >= 10 timeslices */
    INDIGO_ASSERT(100 / i >= 5); /* average at least 5 units per timeslice */

    /* Excessively long callback should trigger a warning (not checked) */
    INDIGO_ASSERT(ind_soc_task_register(task_callback_long, &counters[0], 0) == INDIGO_ERROR_NONE);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0] == 1);

    /* Task should be repeatedly rescheduled in the same call to ind_soc_select_and_run */
    INDIGO_ASSERT(ind_soc_task_register(task_callback_yield, &counters[0], 0) == INDIGO_ERROR_NONE);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(500);
    INDIGO_ASSERT(counters[0] == 100);
}
Пример #9
0
/* Test add/remove of sockets */
static void
test_socket_mgmt(void)
{
    int fds[2];
    struct sock_counters counters[2];

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
        perror("socketpair");
        abort();
    }

    /* Unregistering a not-registered socket should fail */
    INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) < 0);

    /* Adding and then unregistering a socket should succeed */
    INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0);

    /* Trying to unregister twice should fail */
    INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) < 0);

    /* Trying to register twice should fail */
    INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) < 0);

    /* Add another socket, then remove the first */
    INDIGO_ASSERT(ind_soc_socket_register(fds[1], socket_callback, &counters[1]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0);

    /* Write one byte to fds[1] */
    ind_soc_data_out_ready(fds[1]);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 1);

    /* Expect no events from the not-registered fds[0] */
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 0);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);

    /* Register fds[0] and expect a read event */
    INDIGO_ASSERT(ind_soc_socket_register(fds[0], socket_callback, &counters[0]) == 0);
    memset(counters, 0, sizeof(counters));
    ind_soc_select_and_run(0);
    INDIGO_ASSERT(counters[0].read == 1);
    INDIGO_ASSERT(counters[0].write == 0);
    INDIGO_ASSERT(counters[1].read == 0);
    INDIGO_ASSERT(counters[1].write == 0);

    INDIGO_ASSERT(ind_soc_socket_unregister(fds[0]) == 0);
    INDIGO_ASSERT(ind_soc_socket_unregister(fds[1]) == 0);

    close(fds[0]);
    close(fds[1]);
}