Merged nuttx/apps/master into master

This commit is contained in:
Masayuki Ishikawa 2017-04-06 17:04:16 +09:00
commit 3e53181302
40 changed files with 11909 additions and 43 deletions

View File

@ -12,21 +12,37 @@ config EXAMPLES_NETTEST
if EXAMPLES_NETTEST
config EXAMPLES_NETTEST_PROGNAME
string "Program name"
default "nettest"
depends on BUILD_KERNEL
---help---
This is the name of the program that will be use when the Nettest
program is installed.
config EXAMPLES_NETTEST_STACKSIZE
int "Nettest stack size"
default 2048
config EXAMPLES_NETTEST_PRIORITY
int "Nettest priority"
default 100
config EXAMPLES_NETTEST_LOOPBACK
bool "Loopback test"
default n
depends on NET_LOOPBACK
depends on NET_LOOPBACK || IEEE802154_LOOPBACK
---help---
Perform the test using the local loopback device. In this case,
both the client and the server reside on the target.
if EXAMPLES_NETTEST_LOOPBACK
config EXAMPLES_NETTEST_STACKSIZE
config EXAMPLES_NETTEST_SERVER_STACKSIZE
int "Server stack size"
default 2048
config EXAMPLES_NETTEST_PRIORITY
config EXAMPLES_NETTEST_SERVER_PRIORITY
int "Server priority"
default 100
@ -369,7 +385,7 @@ config EXAMPLES_NETTEST_IPv6NETMASK_8
endif # NET_ICMPv6_AUTOCONF
endif # EXAMPLES_NETTEST_INIT
if !EXAMPLES_NETTEST_LOOPBACK
if !EXAMPLES_NETTEST_LOOPBACK || !NET_LOOPBACK
comment "Client IPv6 address"

View File

@ -106,9 +106,15 @@ ROOTDEPPATH = --dep-path .
# NET test built-in application info
CONFIG_EXAMPLES_NETTEST_STACKSIZE ?= 2048
CONFIG_EXAMPLES_NETTEST_PRIORITY ?= 100
APPNAME = nettest
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
PRIORITY = $(CONFIG_EXAMPLES_NETTEST_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_NETTEST_STACKSIZE)
CONFIG_EXAMPLES_NETTEST_PROGNAME ?= nettest$(EXEEXT)
PROGNAME = $(CONFIG_EXAMPLES_HELLO_PROGNAME)
# Common build

View File

@ -219,8 +219,8 @@ int nettest_main(int argc, char *argv[])
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK)
/* Then perform the server side of the test on a child task */
child = task_create("Nettest Child", CONFIG_EXAMPLES_NETTEST_PRIORITY,
CONFIG_EXAMPLES_NETTEST_STACKSIZE, server_child,
child = task_create("Nettest Child", CONFIG_EXAMPLES_NETTEST_SERVER_PRIORITY,
CONFIG_EXAMPLES_NETTEST_SERVER_STACKSIZE, server_child,
NULL);
if (child < 0)
{

View File

@ -106,8 +106,8 @@ void send_client(void)
myaddr.sin6_family = AF_INET6;
myaddr.sin6_port = HTONS(PORTNO);
#ifdef CONFIG_EXAMPLES_NETTEST_LOOPBACK
myaddr.sin6_addr.s6_addr16[0] = 0;
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK) && defined(NET_LOOPBACK)
myaddr.sin6_addr.s6_addr16[0] = 0; /* Use the loopback address */
myaddr.sin6_addr.s6_addr16[1] = 0;
myaddr.sin6_addr.s6_addr16[2] = 0;
myaddr.sin6_addr.s6_addr16[3] = 0;
@ -126,17 +126,25 @@ void send_client(void)
myaddr.sin6_addr.s6_addr16[7] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_8);
#endif
printf("IPv6 Address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
myaddr.sin6_addr.s6_addr16[0], myaddr.sin6_addr.s6_addr16[1],
myaddr.sin6_addr.s6_addr16[2], myaddr.sin6_addr.s6_addr16[3],
myaddr.sin6_addr.s6_addr16[4], myaddr.sin6_addr.s6_addr16[5],
myaddr.sin6_addr.s6_addr16[6], myaddr.sin6_addr.s6_addr16[7]);
addrlen = sizeof(struct sockaddr_in6);
#else
myaddr.sin_family = AF_INET;
myaddr.sin_port = HTONS(PORTNO);
#ifdef CONFIG_EXAMPLES_NETTEST_LOOPBACK
#ifdef CONFIG_EXAMPLES_NETTEST_LOOPBACK && defined(NET_LOOPBACK)
myaddr.sin_addr.s_addr = HTONL(0x7f000001);
#else
myaddr.sin_addr.s_addr = HTONL(CONFIG_EXAMPLES_NETTEST_CLIENTIP);
#endif
printf("IPv4 Address: %08x\n", myaddr.sin_addr.s_addr);
addrlen = sizeof(struct sockaddr_in);
#endif

View File

@ -110,15 +110,33 @@ void recv_server(void)
/* Bind the socket to a local address */
#ifdef CONFIG_EXAMPLES_NETTEST_IPv6
myaddr.sin6_family = AF_INET6;
myaddr.sin6_port = HTONS(PORTNO);
myaddr.sin6_family = AF_INET6;
myaddr.sin6_port = HTONS(PORTNO);
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK) && !defined(NET_LOOPBACK)
myaddr.sin6_addr.s6_addr16[0] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_1);
myaddr.sin6_addr.s6_addr16[1] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_2);
myaddr.sin6_addr.s6_addr16[2] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_3);
myaddr.sin6_addr.s6_addr16[3] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_4);
myaddr.sin6_addr.s6_addr16[4] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_5);
myaddr.sin6_addr.s6_addr16[5] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_6);
myaddr.sin6_addr.s6_addr16[6] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_7);
myaddr.sin6_addr.s6_addr16[7] = HTONS(CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_8);
#else
memset(&myaddr.sin6_addr, 0, sizeof(struct in6_addr));
#endif
addrlen = sizeof(struct sockaddr_in6);
#else
myaddr.sin_family = AF_INET;
myaddr.sin_port = HTONS(PORTNO);
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_family = AF_INET;
myaddr.sin_port = HTONS(PORTNO);
#if defined(CONFIG_EXAMPLES_NETTEST_LOOPBACK) && !defined(NET_LOOPBACK)
myaddr.sin_addr.s_addr = HTONL(CONFIG_EXAMPLES_NETTEST_CLIENTIP);
#else
myaddr.sin_addr.s_addr = INADDR_ANY;
#endif
addrlen = sizeof(struct sockaddr_in);
#endif

14
examples/usrsocktest/.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
/Make.dep
/.depend
/.built
/*.asm
/*.obj
/*.rel
/*.lst
/*.sym
/*.adb
/*.lib
/*.src
/*.hobj
/*.exe
/*.dSYM

View File

@ -0,0 +1,36 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config EXAMPLES_USRSOCKTEST
bool "USRSOCK test example"
default n
depends on NET && NET_USRSOCK && !DISABLE_POLL
select NET_USRSOCK_TCP
select NET_USRSOCK_UDP
select NET_SOCKOPTS
select PIPES
---help---
Enable the User Socket test example. This example application runs
unit-tests for /dev/usrsock.
if EXAMPLES_USRSOCKTEST
config EXAMPLES_USRSOCKTEST_PROGNAME
string "Program name"
default "usrsocktest"
depends on BUILD_KERNEL
---help---
This is the name of the program that will be use when the NSH ELF
program is installed.
config EXAMPLES_USRSOCKTEST_PRIORITY
int "usrsocktest task priority"
default 100
config EXAMPLES_USRSOCKTEST_STACKSIZE
int "usrsocktest stack size"
default 4096
endif

View File

@ -0,0 +1,39 @@
############################################################################
# examples/usrsocktest/Make.defs
# Adds selected applications to apps/ build
#
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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 NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_EXAMPLES_USRSOCKTEST),y)
CONFIGURED_APPS += examples/usrsocktest
endif

View File

@ -0,0 +1,65 @@
############################################################################
# apps/examples/usrsocktest/Makefile
#
# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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 NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/Make.defs
# USRSOCK Test built-in application info
CONFIG_EXAMPLES_USRSOCKTEST_PRIORITY ?= SCHED_PRIORITY_DEFAULT
CONFIG_EXAMPLES_USRSOCKTEST_STACKSIZE ?= 4096
APPNAME = usrsocktest
PRIORITY = $(CONFIG_EXAMPLES_USRSOCKTEST_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_USRSOCKTEST_STACKSIZE)
# NuttX USRSOCK Test
ASRCS =
CSRCS = usrsocktest_daemon.c usrsocktest_basic_connect.c
CSRCS += usrsocktest_basic_daemon.c usrsocktest_basic_getsockname.c
CSRCS += usrsocktest_basic_getsockopt.c usrsocktest_basic_send.c
CSRCS += usrsocktest_basic_setsockopt.c usrsocktest_block_recv.c
CSRCS += usrsocktest_block_send.c usrsocktest_chardev.c
CSRCS += usrsocktest_multi_thread.c usrsocktest_noblock_connect.c
CSRCS += usrsocktest_noblock_recv.c usrsocktest_noblock_send.c
CSRCS += usrsocktest_nodaemon.c usrsocktest_poll.c
CSRCS += usrsocktest_remote_disconnect.c usrsocktest_wake_with_signal.c
MAINSRC = usrsocktest_main.c
CONFIG_EXAMPLES_USRSOCKTEST_PROGNAME ?= usrsocktest$(EXEEXT)
PROGNAME = $(CONFIG_EXAMPLES_USRSOCKTEST_PROGNAME)
include $(APPDIR)/Application.mk

View File

@ -0,0 +1,212 @@
/****************************************************************************
* examples/usrsocktest/defines.h
* Common defines for all usrsock testcases
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Author: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __EXAMPLES_USRSOCKTEST_DEFINES_H
#define __EXAMPLES_USRSOCKTEST_DEFINES_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <assert.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define USRSOCK_NODE "/dev/usrsock"
#define USRSOCKTEST_DAEMON_CONF_DEFAULTS \
{ \
.max_sockets = UINT_MAX, \
.supported_domain = AF_INET, \
.supported_type = SOCK_STREAM, \
.supported_protocol = 0, \
.delay_all_responses = false, \
.endpoint_addr = "127.0.0.1", \
.endpoint_port = 255, \
.endpoint_block_connect = false, \
.endpoint_block_send = false, \
.endpoint_recv_avail_from_start = true, \
.endpoint_recv_avail = 4, \
}
/* Test case macros */
#define utest_match(type, should_be_value, test_value) do { \
type tmp_utest_test_value = (type)(test_value); \
type tmp_utest_should_value = (type)(should_be_value); \
if (!usrsocktest_assert_print_value(__func__, __LINE__, \
"(" #type ")(" #test_value ") == " \
"(" #type ")(" #should_be_value ")", \
tmp_utest_test_value, \
tmp_utest_should_value)) \
{ \
usrsocktest_test_failed = true; \
return; \
} \
} while(false)
#define utest_match_buf(should_be_valuebuf, test_valuebuf, test_valuebuflen) do { \
if (!usrsocktest_assert_print_buf(__func__, __LINE__, \
"memcmp(" #should_be_valuebuf ", " \
#test_valuebuf ", " \
#test_valuebuflen ") == 0", \
should_be_valuebuf, \
test_valuebuf, \
test_valuebuflen)) \
{ \
usrsocktest_test_failed = true; \
return; \
} \
} while(false)
#define RUN_TEST_CASE(g,t) do { \
if (usrsocktest_test_failed) \
{ \
return; \
} \
usrsocktest_group_##g##_setup(); \
usrsocktest_test_##g##_##t(); \
usrsocktest_group_##g##_teardown(); \
if (usrsocktest_test_failed) \
{ \
return; \
} \
} while (false)
#define RUN_TEST_GROUP(g) do { \
extern const char *usrsocktest_group_##g; \
void usrsocktest_group_##g##_run(void); \
run_tests(usrsocktest_group_##g, usrsocktest_group_##g##_run); \
} while (false)
#define TEST_GROUP(g) const char *usrsocktest_group_##g = #g; \
void usrsocktest_group_##g##_run(void)
#define TEST_SETUP(g) static void usrsocktest_group_##g##_setup(void)
#define TEST_TEAR_DOWN(g) static void usrsocktest_group_##g##_teardown(void)
#define TEST(g,t) static void usrsocktest_test_##g##_##t(void)
#define TEST_ASSERT_TRUE(v) utest_match(bool, true, (v))
#define TEST_ASSERT_FALSE(v) utest_match(bool, false, (v))
#define TEST_ASSERT_EQUAL(e,v) utest_match(ssize_t, (e), (v))
#define TEST_ASSERT_EQUAL_UINT8_ARRAY(e,v,s) utest_match_buf((e), (v), (s))
/****************************************************************************
* Public Types
****************************************************************************/
struct usrsocktest_daemon_conf_s
{
unsigned int max_sockets;
int8_t supported_domain:8;
int8_t supported_type:8;
int8_t supported_protocol:8;
bool delay_all_responses:1;
bool endpoint_block_connect:1;
bool endpoint_block_send:1;
bool endpoint_recv_avail_from_start:1;
uint8_t endpoint_recv_avail:8;
const char *endpoint_addr;
uint16_t endpoint_port;
};
/****************************************************************************
* Public Data
****************************************************************************/
extern int usrsocktest_endp_malloc_cnt;
extern int usrsocktest_dcmd_malloc_cnt;
extern const struct usrsocktest_daemon_conf_s usrsocktest_daemon_defconf;
extern struct usrsocktest_daemon_conf_s usrsocktest_daemon_config;
extern bool usrsocktest_test_failed;
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
bool usrsocktest_assert_print_value(FAR const char *func,
const int line,
FAR const char *check_str,
long int test_value,
long int should_be);
bool usrsocktest_assert_print_buf(FAR const char *func,
const int line,
FAR const char *check_str,
FAR const void *test_buf,
FAR const void *expect_buf,
size_t buflen);
int usrsocktest_daemon_start(FAR const struct usrsocktest_daemon_conf_s *conf);
int usrsocktest_daemon_stop(void);
int usrsocktest_daemon_get_num_active_sockets(void);
int usrsocktest_daemon_get_num_connected_sockets(void);
int usrsocktest_daemon_get_num_waiting_connect_sockets(void);
int usrsocktest_daemon_get_num_recv_empty_sockets(void);
ssize_t usrsocktest_daemon_get_send_bytes(void);
ssize_t usrsocktest_daemon_get_recv_bytes(void);
int usrsocktest_daemon_get_num_unreachable_sockets(void);
int usrsocktest_daemon_get_num_remote_disconnected_sockets(void);
bool usrsocktest_daemon_establish_waiting_connections(void);
bool usrsocktest_send_delayed_command(char cmd, unsigned int delay_msec);
int usrsocktest_daemon_pause_usrsock_handling(bool pause);
#endif /* __EXAMPLES_USRSOCKTEST_DEFINES_H */

View File

@ -0,0 +1,488 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_basic_connect.c
* Basic connect tests with socket daemon
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Setup
*
* Description:
* Run before every testcase
*
* Input Parameters:
* dconf - test daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Setup(FAR struct usrsocktest_daemon_conf_s *dconf)
{
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
}
/****************************************************************************
* Name: Teardown
*
* Description:
* Run after every testcase
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Teardown(void)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
/****************************************************************************
* Name: NotConnected
*
* Description:
* Opened socket is not connected
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void NotConnected(void)
{
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
}
/****************************************************************************
* Name: Connect
*
* Description:
* Open and connect the socket
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Connect(void)
{
int ret;
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
/* Attempt reconnect to same address */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Attempt reconnect to different address */
inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(1);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: WrongAF
*
* Description:
* Open and connect the socket with wrong AF
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void WrongAF(void)
{
int ret;
struct sockaddr_in addr;
/* Try connect socket with wrong AF */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_UNIX;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAFNOSUPPORT, errno);
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: WrongPort
*
* Description:
* Open and connect the socket with wrong port
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void WrongPort(void)
{
int ret;
struct sockaddr_in addr;
/* Try connect socket to wrong port */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(127);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(ECONNREFUSED, errno);
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: WrongEndpoint
*
* Description:
* Open and connect the socket with wrong endpoint
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void WrongEndpoint(void)
{
int ret;
struct sockaddr_in addr;
/* Try connect socket to unreachable endpoint */
inet_pton(AF_INET, "1.1.1.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(1);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(ENETUNREACH, errno);
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Connect */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
TEST_SETUP(BasicConnect)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Setup(&usrsocktest_daemon_config);
}
TEST_TEAR_DOWN(BasicConnect)
{
Teardown();
}
TEST(BasicConnect, NotConnected)
{
NotConnected();
}
TEST(BasicConnect, Connect)
{
Connect();
}
TEST(BasicConnect, WrongAF)
{
WrongAF();
}
TEST(BasicConnect, WrongPort)
{
WrongPort();
}
TEST(BasicConnect, WrongEndpoint)
{
WrongEndpoint();
}
TEST_SETUP(BasicConnectDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Setup(&usrsocktest_daemon_config);
}
TEST_TEAR_DOWN(BasicConnectDelay)
{
Teardown();
}
TEST(BasicConnectDelay, NotConnected)
{
NotConnected();
}
TEST(BasicConnectDelay, Connect)
{
Connect();
}
TEST(BasicConnectDelay, WrongAF)
{
WrongAF();
}
TEST(BasicConnectDelay, WrongPort)
{
WrongPort();
}
TEST(BasicConnectDelay, WrongEndpoint)
{
WrongEndpoint();
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BasicConnect)
{
RUN_TEST_CASE(BasicConnect, NotConnected);
RUN_TEST_CASE(BasicConnect, Connect);
RUN_TEST_CASE(BasicConnect, WrongAF);
RUN_TEST_CASE(BasicConnect, WrongPort);
RUN_TEST_CASE(BasicConnect, WrongEndpoint);
}
TEST_GROUP(BasicConnectDelay)
{
RUN_TEST_CASE(BasicConnectDelay, NotConnected);
RUN_TEST_CASE(BasicConnectDelay, Connect);
RUN_TEST_CASE(BasicConnectDelay, WrongAF);
RUN_TEST_CASE(BasicConnectDelay, WrongPort);
RUN_TEST_CASE(BasicConnectDelay, WrongEndpoint);
}

View File

@ -0,0 +1,686 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_basic_daemon.c
* Basic tests with socket daemon
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd, sd2, sd3;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: NoActiveSockets
*
* Description:
* Checks there is no active sockets on daemon startup
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void NoActiveSockets(FAR struct usrsocktest_daemon_conf_s *dconf)
{
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
}
/****************************************************************************
* Name: OpenClose
*
* Description:
* Open and close AF_INET socket, check active socket counter updates
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void OpenClose(FAR struct usrsocktest_daemon_conf_s *dconf)
{
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: UnsupportedType
*
* Description:
* Try open socket for unsupported type
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void UnsupportedType(FAR struct usrsocktest_daemon_conf_s *dconf)
{
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_RDM, 0);
TEST_ASSERT_TRUE(sd < 0);
TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno);
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: UnsupportedProto
*
* Description:
* Try open socket for unsupported protocol
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void UnsupportedProto(FAR struct usrsocktest_daemon_conf_s *dconf)
{
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 1);
TEST_ASSERT_TRUE(sd < 0);
TEST_ASSERT_EQUAL(EPROTONOSUPPORT, errno);
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: OpenThree
*
* Description:
* Open multiple sockets
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void OpenThree(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
dconf->max_sockets = 3;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
sd3 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd3 >= 0);
TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets());
ret = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_FALSE(ret >= 0);
TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd2);
TEST_ASSERT_EQUAL(0, ret);
sd2 = -1;
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd);
TEST_ASSERT_EQUAL(0, ret);
sd = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd3);
TEST_ASSERT_EQUAL(0, ret);
sd3 = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: Dup
*
* Description:
* Dup opened socket
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Dup(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
sd2 = dup(sd);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
sd3 = dup(sd);
TEST_ASSERT_TRUE(sd3 >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd2);
TEST_ASSERT_EQUAL(0, ret);
sd2 = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd);
TEST_ASSERT_EQUAL(0, ret);
sd = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd3);
TEST_ASSERT_EQUAL(0, ret);
sd3 = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: Dup2
*
* Description:
* Clone opened socket with dup2
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Dup2(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
ret = dup2(sd2, sd);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd2);
TEST_ASSERT_EQUAL(0, ret);
sd2 = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
ret = close(sd);
TEST_ASSERT_EQUAL(0, ret);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: Stops
*
* Description:
* Daemon stops unexpectedly
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Stops(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
ret = usrsocktest_daemon_stop();
TEST_ASSERT_EQUAL(OK, ret);
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
TEST_ASSERT_EQUAL(0, close(sd));
sd = -1;
TEST_ASSERT_EQUAL(0, close(sd2));
sd2 = -1;
}
/****************************************************************************
* Name: StopsStarts
*
* Description:
* Daemon stops and restarts unexpectedly
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void StopsStarts(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
struct sockaddr_in addr;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = 255;
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EPIPE, errno);
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EPIPE, errno);
TEST_ASSERT_EQUAL(0, close(sd));
sd = -1;
TEST_ASSERT_EQUAL(0, close(sd2));
sd2 = -1;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BasicDaemon test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BasicDaemon)
{
sd = -1;
sd2 = -1;
sd3 = -1;
started = false;
}
/****************************************************************************
* Name: BasicDaemon test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BasicDaemon)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (sd2 >= 0)
{
ret = close(sd2);
assert(ret >= 0);
}
if (sd3 >= 0)
{
ret = close(sd3);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BasicDaemon, NoActiveSockets)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
NoActiveSockets(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, NoActiveSocketsDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
NoActiveSockets(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, OpenClose)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
OpenClose(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, OpenCloseDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
OpenClose(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, UnsupportedType)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
UnsupportedType(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, UnsupportedTypeDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
UnsupportedType(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, UnsupportedProto)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
UnsupportedProto(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, UnsupportedProtoDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
UnsupportedProto(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, OpenThree)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
OpenThree(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, OpenThreeDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
OpenThree(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, Dup)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Dup(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, DupDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Dup(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, Dup2)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Dup2(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, Dup2Delay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Dup2(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, Stops)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Stops(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, StopsDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Stops(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, StopsStarts)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
StopsStarts(&usrsocktest_daemon_config);
}
TEST(BasicDaemon, StopsStartsDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
StopsStarts(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BasicDaemon)
{
RUN_TEST_CASE(BasicDaemon, NoActiveSockets);
RUN_TEST_CASE(BasicDaemon, NoActiveSocketsDelay);
RUN_TEST_CASE(BasicDaemon, OpenClose);
RUN_TEST_CASE(BasicDaemon, OpenCloseDelay);
RUN_TEST_CASE(BasicDaemon, UnsupportedType);
RUN_TEST_CASE(BasicDaemon, UnsupportedTypeDelay);
RUN_TEST_CASE(BasicDaemon, UnsupportedProto);
RUN_TEST_CASE(BasicDaemon, UnsupportedProtoDelay);
RUN_TEST_CASE(BasicDaemon, OpenThree);
RUN_TEST_CASE(BasicDaemon, OpenThreeDelay);
RUN_TEST_CASE(BasicDaemon, Dup);
RUN_TEST_CASE(BasicDaemon, DupDelay);
RUN_TEST_CASE(BasicDaemon, Dup2);
RUN_TEST_CASE(BasicDaemon, Dup2Delay);
RUN_TEST_CASE(BasicDaemon, Stops);
RUN_TEST_CASE(BasicDaemon, StopsDelay);
RUN_TEST_CASE(BasicDaemon, StopsStarts);
RUN_TEST_CASE(BasicDaemon, StopsStartsDelay);
}

View File

@ -0,0 +1,287 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_basic_getsockname.c
* Basic getsockname tests
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Open
*
* Description:
* Open and get socket options
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Open(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
socklen_t addrlen;
union {
struct sockaddr_storage storage;
struct sockaddr_in in;
} addr;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get socket name */
memset(&addr, 0xff, sizeof(addr));
addrlen = sizeof(addr.in);
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family);
TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port);
TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get socket name, short buffer */
memset(&addr, 0xff, sizeof(addr));
addrlen = 1;
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
TEST_ASSERT_EQUAL(AF_INET, ((FAR uint8_t *)&addr.in.sin_family)[0]);
TEST_ASSERT_EQUAL(0xff, ((FAR uint8_t *)&addr.in.sin_family)[1]);
TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port);
TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get socket name, larger buffer */
memset(&addr, 0xff, sizeof(addr));
addrlen = sizeof(addr.storage);
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
TEST_ASSERT_EQUAL(AF_INET, addr.in.sin_family);
TEST_ASSERT_EQUAL(htons(12345), addr.in.sin_port);
TEST_ASSERT_EQUAL(htonl(0x7f000001), addr.in.sin_addr.s_addr);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get socket name, NULL addr */
memset(&addr, 0xff, sizeof(addr));
addrlen = sizeof(addr.in);
ret = getsockname(sd, NULL, &addrlen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINVAL, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get socket name, NULL addrlen */
memset(&addr, 0xff, sizeof(addr));
addrlen = sizeof(addr.in);
ret = getsockname(sd, (FAR void *)&addr.in, NULL);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINVAL, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get socket name, zero length buffer */
memset(&addr, 0xff, sizeof(addr));
addrlen = 0;
ret = getsockname(sd, (FAR void *)&addr.in, &addrlen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(addr.in), addrlen);
TEST_ASSERT_EQUAL(0xffff, addr.in.sin_family);
TEST_ASSERT_EQUAL(htons(0xffff), addr.in.sin_port);
TEST_ASSERT_EQUAL(htonl(0xffffffff), addr.in.sin_addr.s_addr);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BasicGetSockName test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BasicGetSockName)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: BasicGetSockName test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BasicGetSockName)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BasicGetSockName, Open)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Open(&usrsocktest_daemon_config);
}
TEST(BasicGetSockName, OpenDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Open(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BasicGetSockName)
{
RUN_TEST_CASE(BasicGetSockName, Open);
RUN_TEST_CASE(BasicGetSockName, OpenDelay);
}

View File

@ -0,0 +1,266 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_basic_getsockopt.c
* Basic getsockopt tests
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Open
*
* Description:
* Open and get socket options
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Open(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
int value;
int valuelarge[2];
socklen_t valuelen;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get supported option (SO_TYPE handled by nuttx) */
value = -2;
valuelen = sizeof(value);
ret = getsockopt(sd, SOL_SOCKET, SO_TYPE, &value, &valuelen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(value), valuelen);
TEST_ASSERT_EQUAL(SOCK_STREAM, value);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get supported option */
value = -1;
valuelen = sizeof(value);
ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(value), valuelen);
TEST_ASSERT_EQUAL(0, value);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get supported option, too short buffer */
value = -1;
valuelen = 1;
ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINVAL, errno);
TEST_ASSERT_EQUAL(-1, value);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get supported option, larger buffer */
valuelarge[0] = -1;
valuelarge[1] = -1;
valuelen = sizeof(valuelarge);
ret = getsockopt(sd, SOL_SOCKET, SO_REUSEADDR, valuelarge, &valuelen);
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(sizeof(value), valuelen);
TEST_ASSERT_EQUAL(0, valuelarge[0]);
TEST_ASSERT_EQUAL(-1, valuelarge[1]);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Get unsupported option */
value = -1;
valuelen = sizeof(value);
ret = getsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, &valuelen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(ENOPROTOOPT, errno);
TEST_ASSERT_EQUAL(-1, value);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BasicGetSockOpt test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BasicGetSockOpt)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: BasicGetSockOpt test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BasicGetSockOpt)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BasicGetSockOpt, Open)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Open(&usrsocktest_daemon_config);
}
TEST(BasicGetSockOpt, OpenDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Open(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BasicGetSockOpt)
{
RUN_TEST_CASE(BasicGetSockOpt, Open);
RUN_TEST_CASE(BasicGetSockOpt, OpenDelay);
}

View File

@ -0,0 +1,359 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_basic_send.c
* Basic sending tests
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Send
*
* Description:
* Open socket and send
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Send(FAR struct usrsocktest_daemon_conf_s *dconf)
{
struct sockaddr_in addr;
ssize_t ret;
size_t datalen;
const void *data;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Send on non-connected socket */
data = "data";
datalen = strlen("data");
ret = send(sd, data, datalen, 0);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(ENOTCONN, errno);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Sendto with address */
data = "data";
datalen = strlen("data");
ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr,
sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(ENOTCONN, errno);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Connect socket to available endpoint */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
/* Sendto with address */
data = "data";
datalen = strlen("data");
ret = sendto(sd, data, datalen, 0, (FAR const struct sockaddr *)&addr,
sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV,
usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: ConnectSend
*
* Description:
* Send over connected socket
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ConnectSend(FAR struct usrsocktest_daemon_conf_s *dconf)
{
struct sockaddr_in addr;
ssize_t ret;
size_t datalen;
const void *data;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Connect socket to available endpoint */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Send data to remote */
data = "data";
datalen = strlen("data");
ret = send(sd, data, datalen, 0);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV,
usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BasicSend test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BasicSend)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: BasicSend test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BasicSend)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BasicSend, Send)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Send(&usrsocktest_daemon_config);
}
TEST(BasicSend, SendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Send(&usrsocktest_daemon_config);
}
TEST(BasicSend, ConnectSend)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ConnectSend(&usrsocktest_daemon_config);
}
TEST(BasicSend, ConnectSendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ConnectSend(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BasicSend)
{
RUN_TEST_CASE(BasicSend, Send);
RUN_TEST_CASE(BasicSend, SendDelay);
RUN_TEST_CASE(BasicSend, ConnectSend);
RUN_TEST_CASE(BasicSend, ConnectSendDelay);
}

View File

@ -0,0 +1,235 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_basic_setsockopt.c
* Basic setsockopt tests
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Open
*
* Description:
* Open and set socket options
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Open(FAR struct usrsocktest_daemon_conf_s *dconf)
{
int ret;
int value;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Set supported option */
value = 1;
ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Set supported option, too small buffer */
value = 1;
ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, 1);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINVAL, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Set unsupported option */
value = 1;
ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(ENOPROTOOPT, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BasicSetSockOpt test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BasicSetSockOpt)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: BasicSetSockOpt test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BasicSetSockOpt)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BasicSetSockOpt, Open)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Open(&usrsocktest_daemon_config);
}
TEST(BasicSetSockOpt, OpenDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Open(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BasicSetSockOpt)
{
RUN_TEST_CASE(BasicSetSockOpt, Open);
RUN_TEST_CASE(BasicSetSockOpt, OpenDelay);
}

View File

@ -0,0 +1,514 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_block_recv.c
* Receive from the socket in blocking mode
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ConnectReceive
*
* Description:
* Blocking connect and receive
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ConnectReceive(FAR struct usrsocktest_daemon_conf_s *dconf)
{
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
char databuf[5];
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = true;
dconf->endpoint_recv_avail_from_start = false;
dconf->endpoint_recv_avail = 7;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Do connect, should succeed (after connect block released). */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote */
data = databuf;
datalen = sizeof(databuf);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
ret = recvfrom(sd, data, datalen, 0, NULL, 0);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(5, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, 0);
TEST_ASSERT_EQUAL(2, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("ab", data, 2);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: NoBlockConnect
*
* Description:
* Non-blocking connect and blocking receive
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void NoBlockConnect(FAR struct usrsocktest_daemon_conf_s *dconf)
{
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
char databuf[5];
struct sockaddr_in remoteaddr;
socklen_t addrlen;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = true;
dconf->endpoint_recv_avail_from_start = true;
dconf->endpoint_recv_avail = 6;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Do connect, should succeed (after connect block released). */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100));
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote */
data = databuf;
datalen = sizeof(databuf);
ret = read(sd, data, datalen);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(5, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(5, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote */
data = databuf;
datalen = sizeof(databuf);
addrlen = sizeof(remoteaddr);
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
&addrlen);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("a", data, 1);
TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen);
TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote */
data = databuf;
datalen = sizeof(databuf);
addrlen = sizeof(remoteaddr);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
&addrlen);
TEST_ASSERT_EQUAL(5, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcde", data, 5);
TEST_ASSERT_EQUAL(sizeof(remoteaddr), addrlen);
TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(11, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: ReceiveTimeout
*
* Description:
* Blocking connect and receive with SO_RCVTIMEO
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ReceiveTimeout(FAR struct usrsocktest_daemon_conf_s *dconf)
{
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
char databuf[5];
struct timeval tv;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = true;
dconf->endpoint_recv_avail_from_start = false;
dconf->endpoint_recv_avail = 7;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Do connect, should succeed (after connect block released). */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Setup recv timeout. */
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (FAR const void *)&tv,
sizeof(tv));
TEST_ASSERT_EQUAL(0, ret);
/* Receive data from remote */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, 0);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BlockRecv test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BlockRecv)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: BlockRecv test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BlockRecv)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BlockRecv, ConnectReceive)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ConnectReceive(&usrsocktest_daemon_config);
}
TEST(BlockRecv, ConnectReceiveDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ConnectReceive(&usrsocktest_daemon_config);
}
TEST(BlockRecv, NoBlockConnect)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
NoBlockConnect(&usrsocktest_daemon_config);
}
TEST(BlockRecv, NoBlockConnectDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
NoBlockConnect(&usrsocktest_daemon_config);
}
TEST(BlockRecv, ReceiveTimeout)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ReceiveTimeout(&usrsocktest_daemon_config);
}
TEST(BlockRecv, ReceiveTimeoutDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ReceiveTimeout(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BlockRecv)
{
RUN_TEST_CASE(BlockRecv, ConnectReceive);
RUN_TEST_CASE(BlockRecv, ConnectReceiveDelay);
RUN_TEST_CASE(BlockRecv, NoBlockConnect);
RUN_TEST_CASE(BlockRecv, NoBlockConnectDelay);
RUN_TEST_CASE(BlockRecv, ReceiveTimeout);
RUN_TEST_CASE(BlockRecv, ReceiveTimeoutDelay);
}

View File

@ -0,0 +1,442 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_block_send.c
* Send through the socket in blocking mode
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/time.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ConnectSend
*
* Description:
* Open socket, connect in blocking mode and send
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ConnectSend(FAR struct usrsocktest_daemon_conf_s *dconf)
{
ssize_t ret;
size_t datalen;
const void *data;
struct sockaddr_in addr;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Do connect, should succeed (after connect block released). */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Send data to remote, */
data = "abcde";
datalen = strlen("abcde");
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100));
ret = sendto(sd, data, datalen, 0, NULL, 0);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: NonBlockConnectSend
*
* Description:
* Open socket, connect in non-blocking mode and send
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void NonBlockConnectSend(FAR struct usrsocktest_daemon_conf_s *dconf)
{
ssize_t ret;
size_t datalen;
const void *data;
struct sockaddr_in addr;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = false;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Do connect, should succeed (after connect block released). */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('W', 100));
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Send data to remote. */
data = "abcde";
datalen = strlen("abcde");
ret = write(sd, data, datalen);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: SendTimeout
*
* Description:
* Open socket, connect in blocking mode and send with SO_SNDTIMEO
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void SendTimeout(FAR struct usrsocktest_daemon_conf_s *dconf)
{
ssize_t ret;
size_t datalen;
const void *data;
struct sockaddr_in addr;
struct timeval tv;
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Do connect, should succeed (after connect block released). */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Setup send timeout. */
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
ret = setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (FAR const void *)&tv,
sizeof(tv));
TEST_ASSERT_EQUAL(0, ret);
/* Try send data to remote. */
data = "abcde";
datalen = strlen("abcde");
ret = sendto(sd, data, datalen, 0, NULL, 0);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: BlockSend test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(BlockSend)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: BlockSend test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(BlockSend)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(BlockSend, ConnectSend)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ConnectSend(&usrsocktest_daemon_config);
}
TEST(BlockSend, ConnectSendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ConnectSend(&usrsocktest_daemon_config);
}
TEST(BlockSend, NonBlockConnectSend)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
NonBlockConnectSend(&usrsocktest_daemon_config);
}
TEST(BlockSend, NonBlockConnectSendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
NonBlockConnectSend(&usrsocktest_daemon_config);
}
TEST(BlockSend, SendTimeout)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
SendTimeout(&usrsocktest_daemon_config);
}
TEST(BlockSend, SendTimeoutDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
SendTimeout(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(BlockSend)
{
RUN_TEST_CASE(BlockSend, ConnectSend);
RUN_TEST_CASE(BlockSend, ConnectSendDelay);
RUN_TEST_CASE(BlockSend, NonBlockConnectSend);
RUN_TEST_CASE(BlockSend, NonBlockConnectSendDelay);
RUN_TEST_CASE(BlockSend, SendTimeout);
RUN_TEST_CASE(BlockSend, SendTimeoutDelay);
}

View File

@ -0,0 +1,234 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_chardev.c
* Character device node tests
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <fcntl.h>
#include <errno.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static int us_fd;
static int us_fd_two;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: CharDev test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(CharDev)
{
us_fd = -1;
us_fd_two = -1;
}
/****************************************************************************
* Name: CharDev test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(CharDev)
{
int ret;
if (us_fd >= 0)
{
ret = close(us_fd);
assert(ret >= 0);
}
if (us_fd_two >= 0)
{
ret = close(us_fd_two);
assert(ret >= 0);
}
}
/****************************************************************************
* Name: OpenRw
*
* Description:
* Simple test for opening and closing usrsock node
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST(CharDev, OpenRw)
{
int ret;
us_fd = open(USRSOCK_NODE, O_RDWR);
TEST_ASSERT_TRUE(us_fd >= 0);
ret = close(us_fd);
TEST_ASSERT_TRUE(ret >= 0);
us_fd = -1;
}
/****************************************************************************
* Name: ReopenRw
*
* Description:
* Repeated simple test for opening and closing usrsock node, reopen should
* work
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST(CharDev, ReopenRw)
{
int ret;
us_fd = open(USRSOCK_NODE, O_RDWR);
TEST_ASSERT_TRUE(us_fd >= 0);
ret = close(us_fd);
TEST_ASSERT_TRUE(ret >= 0);
us_fd = -1;
us_fd = open(USRSOCK_NODE, O_RDWR);
TEST_ASSERT_TRUE(us_fd >= 0);
ret = close(us_fd);
TEST_ASSERT_TRUE(ret >= 0);
us_fd = -1;
}
/****************************************************************************
* Name: NoMultipleOpen
*
* Description:
* No permission for multiple access,
* first user should be only user.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST(CharDev, NoMultipleOpen)
{
us_fd = open(USRSOCK_NODE, O_RDWR);
TEST_ASSERT_TRUE(us_fd >= 0);
us_fd_two = open(USRSOCK_NODE, O_RDWR);
TEST_ASSERT_FALSE(us_fd_two >= 0);
TEST_ASSERT_EQUAL(EPERM, errno);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(CharDev)
{
RUN_TEST_CASE(CharDev, OpenRw);
RUN_TEST_CASE(CharDev, ReopenRw);
RUN_TEST_CASE(CharDev, NoMultipleOpen);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,284 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_main.c
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Author: Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <debug.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Definitions
****************************************************************************/
#ifndef dbg
#define dbg _warn
#endif
#define usrsocktest_dbg(...) ((void)0)
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static struct
{
unsigned int ok;
unsigned int failed;
unsigned int nchecks;
} overall;
/****************************************************************************
* Public Data
****************************************************************************/
int usrsocktest_endp_malloc_cnt = 0;
int usrsocktest_dcmd_malloc_cnt = 0;
bool usrsocktest_test_failed = false;
/****************************************************************************
* Private Functions
****************************************************************************/
static void get_mallinfo(struct mallinfo *mem)
{
#ifdef CONFIG_CAN_PASS_STRUCTS
*mem = mallinfo();
#else
(void)mallinfo(mem);
#endif
}
static void print_mallinfo(const struct mallinfo *mem, const char *title)
{
if (title)
printf("%s:\n", title);
printf(" %11s%11s%11s%11s\n", "total", "used", "free", "largest");
printf("Mem: %11d%11d%11d%11d\n",
mem->arena, mem->uordblks, mem->fordblks, mem->mxordblk);
}
static void utest_assert_print_head(FAR const char *func, const int line,
FAR const char *check_str)
{
printf("\t[TEST ASSERT FAILED!]\n"
"\t\tIn function \"%s\":\n"
"\t\tline %d: Assertion `%s' failed.\n", func, line, check_str);
}
static void run_tests(FAR const char *name, void (CODE *test_fn)(void))
{
printf("Testing group \"%s\" =>\n", name);
fflush(stdout);
fflush(stderr);
usrsocktest_test_failed = false;
test_fn();
if (!usrsocktest_test_failed)
{
printf("\tGroup \"%s\": [OK]\n", name);
overall.ok++;
}
else
{
printf("\tGroup \"%s\": [FAILED]\n", name);
overall.failed++;
}
fflush(stdout);
fflush(stderr);
}
/****************************************************************************
* Name: runAllTests
*
* Description:
* Sequentially runs all included test groups
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void runAllTests(void)
{
RUN_TEST_GROUP(CharDev);
RUN_TEST_GROUP(NoDaemon);
RUN_TEST_GROUP(BasicDaemon);
RUN_TEST_GROUP(BasicConnect);
RUN_TEST_GROUP(BasicConnectDelay);
RUN_TEST_GROUP(NoBlockConnect);
RUN_TEST_GROUP(BasicSend);
RUN_TEST_GROUP(NoBlockSend);
RUN_TEST_GROUP(BlockSend);
RUN_TEST_GROUP(NoBlockRecv);
RUN_TEST_GROUP(BlockRecv);
RUN_TEST_GROUP(RemoteDisconnect);
RUN_TEST_GROUP(BasicSetSockOpt);
RUN_TEST_GROUP(BasicGetSockOpt);
RUN_TEST_GROUP(BasicGetSockName);
RUN_TEST_GROUP(WakeWithSignal);
RUN_TEST_GROUP(MultiThread);
}
/****************************************************************************
* Public Functions
****************************************************************************/
bool usrsocktest_assert_print_value(FAR const char *func,
const int line,
FAR const char *check_str,
long int test_value,
long int should_be)
{
++overall.nchecks;
if (test_value == should_be)
{
int keep_errno = errno;
usrsocktest_dbg("%d => OK.\n", line);
errno = keep_errno;
return true;
}
utest_assert_print_head(func, line, check_str);
printf("\t\t\tgot value: %ld\n", test_value);
printf("\t\t\tshould be: %ld\n", should_be);
fflush(stdout);
fflush(stderr);
return false;
}
bool usrsocktest_assert_print_buf(FAR const char *func,
const int line,
FAR const char *check_str,
FAR const void *test_buf,
FAR const void *expect_buf,
size_t buflen)
{
++overall.nchecks;
if (memcmp(test_buf, expect_buf, buflen) == 0)
{
int keep_errno = errno;
usrsocktest_dbg("%d => OK.\n", line);
errno = keep_errno;
return true;
}
utest_assert_print_head(func, line, check_str);
fflush(stdout);
fflush(stderr);
return false;
}
/****************************************************************************
* usrsocktest_main
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int usrsocktest_main(int argc, char *argv[])
#endif
{
struct mallinfo mem_before, mem_after;
memset(&overall, 0, sizeof(overall));
printf("Starting unit-tests...\n");
fflush(stdout);
fflush(stderr);
get_mallinfo(&mem_before);
runAllTests();
printf("Unit-test groups done... OK:%d, FAILED:%d, TOTAL:%d\n",
overall.ok, overall.failed, overall.ok + overall.failed);
printf(" -- number of checks made: %d\n", overall.nchecks);
fflush(stdout);
fflush(stderr);
get_mallinfo(&mem_after);
print_mallinfo(&mem_before, "HEAP BEFORE TESTS");
print_mallinfo(&mem_after, "HEAP AFTER TESTS");
fflush(stdout);
fflush(stderr);
exit(0);
return 0;
}

View File

@ -0,0 +1,267 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_multi_thread.c
* Multi-threaded access to sockets
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static pthread_t tids[4];
static int sds[4];
static bool started;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
static void usrsock_socket_multitask_do_work(int *sd)
{
struct sockaddr_in addr;
int ret;
int i;
for (i = 0; i < 10; i++)
{
/* Simple test for opening socket with usrsock daemon running. */
*sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(*sd >= 0);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(*sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
/* Close socket */
TEST_ASSERT_TRUE(close(*sd) >= 0);
*sd = -1;
}
}
static FAR void *usrsock_socket_multitask_thread(FAR void *param)
{
usrsock_socket_multitask_do_work((int*)param);
return NULL;
}
/****************************************************************************
* Name: MultiThread test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(MultiThread)
{
int i;
for (i = 0; i < ARRAY_SIZE(sds); i++)
{
sds[i] = -1;
}
for (i = 0; i < ARRAY_SIZE(tids); i++)
{
tids[i] = -1;
}
started = false;
}
/****************************************************************************
* Name: MultiThread test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(MultiThread)
{
int ret;
int i;
for (i = 0; i < ARRAY_SIZE(tids); i++)
{
if (tids[i] != -1)
{
ret = pthread_cancel(tids[i]);
assert(ret == OK);
ret = pthread_join(tids[i], NULL);
assert(ret == OK);
}
}
for (i = 0; i < ARRAY_SIZE(sds); i++)
{
if (sds[i] != -1)
{
ret = close(sds[i]);
assert(ret >= 0);
}
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
/****************************************************************************
* Name: OpenClose
*
* Description:
* Open and close socket with multiple threads
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST(MultiThread, OpenClose)
{
int ret;
int i;
/* Start test daemon. */
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
usrsocktest_daemon_config.endpoint_block_send = false;
usrsocktest_daemon_config.endpoint_block_connect = false;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Launch worker threads. */
for (i = 0; i < ARRAY_SIZE(tids); i++)
{
ret = pthread_create(&tids[i], NULL, usrsock_socket_multitask_thread,
sds + i);
TEST_ASSERT_EQUAL(OK, ret);
}
/* Wait threads to complete work. */
while (--i > -1)
{
pthread_addr_t tparam;
ret = pthread_join(tids[i], &tparam);
TEST_ASSERT_EQUAL(OK, ret);
tids[i] = -1;
/* This flag is set whenever a test fails, otherwise it is not touched
* No need for synchronization. Here we bail from main test thread on
* first failure in any thread.
*/
TEST_ASSERT_FALSE(usrsocktest_test_failed);
}
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(MultiThread)
{
RUN_TEST_CASE(MultiThread, OpenClose);
}

View File

@ -0,0 +1,816 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_noblock_connect.c
* Socket connect tests in non-blocking mode
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd, sd2;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
TEST_SETUP(NoBlockConnect)
{
sd = -1;
sd2 = -1;
started = false;
}
TEST_TEAR_DOWN(NoBlockConnect)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret == 0);
}
if (sd2 >= 0)
{
ret = close(sd2);
assert(ret == 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(NoBlockConnect, InstantConnect)
{
int flags;
int ret;
struct sockaddr_in addr;
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Do connect, should succeed instantly. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
TEST(NoBlockConnect, DelayedConnect)
{
int flags, ret, count;
struct sockaddr_in addr;
/* Start test daemon. */
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.endpoint_block_connect = true;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
usrsocktest_daemon_config.delay_all_responses = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Another connect attempt results EALREADY. */
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EALREADY, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Release delayed connect. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Another connect attempt results EISCONN. */
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
/* Close socket. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
TEST(NoBlockConnect, CloseNotConnected)
{
int flags, ret;
struct sockaddr_in addr;
/* Start test daemon. */
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.endpoint_block_connect = true;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
usrsocktest_daemon_config.delay_all_responses = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Close socket. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
TEST(NoBlockConnect, EarlyDrop)
{
int flags, ret;
struct sockaddr_in addr;
/* Start test daemon. */
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.endpoint_block_connect = true;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
usrsocktest_daemon_config.delay_all_responses = false;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
/* Close socket. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
}
TEST(NoBlockConnect, Multiple)
{
int flags, ret, count;
struct sockaddr_in addr;
/* Start test daemon. */
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.endpoint_block_connect = true;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
usrsocktest_daemon_config.delay_all_responses = false;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open sockets */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
flags = fcntl(sd2, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd2, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempts, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Release delayed connections. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Release delayed connections. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0;
count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Close sockets. */
TEST_ASSERT_TRUE(close(sd2) >= 0);
sd2 = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Open sockets */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
flags = fcntl(sd2, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd2, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempts, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Release delayed connections. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Close sockets. */
TEST_ASSERT_TRUE(close(sd2) >= 0);
sd2 = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Open sockets */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
sd2 = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
flags = fcntl(sd2, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd2, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd2, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Release delayed connections. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Launch another connect attempt, daemon delays actual connection until triggered. */
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(2, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Close sockets. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_TRUE(close(sd2) >= 0);
sd2 = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
TEST(NoBlockConnect, Dup2)
{
int flags, ret, count;
struct sockaddr_in addr;
/* Start test daemon. */
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.endpoint_block_connect = true;
usrsocktest_daemon_config.endpoint_addr = "127.0.0.1";
usrsocktest_daemon_config.endpoint_port = 255;
usrsocktest_daemon_config.delay_all_responses = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(&usrsocktest_daemon_config));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Duplicate socket */
sd2 = dup(sd);
TEST_ASSERT_TRUE(sd2 >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Another connect attempt results EALREADY. */
ret = connect(sd2, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EALREADY, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Release delayed connect. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Another connect attempt results EISCONN. */
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
/* Close sockets. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_TRUE(close(sd2) >= 0);
sd2 = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(NoBlockConnect)
{
RUN_TEST_CASE(NoBlockConnect, InstantConnect);
RUN_TEST_CASE(NoBlockConnect, DelayedConnect);
RUN_TEST_CASE(NoBlockConnect, CloseNotConnected);
RUN_TEST_CASE(NoBlockConnect, EarlyDrop);
RUN_TEST_CASE(NoBlockConnect, Multiple);
RUN_TEST_CASE(NoBlockConnect, Dup2);
}

View File

@ -0,0 +1,521 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_noblock_recv.c
* Receive from the socket in non-blocking mode
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Receive
*
* Description:
* Non-blocking & instant connect+recv
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Receive(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
int count;
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
char databuf[4];
struct sockaddr_in remoteaddr;
socklen_t addrlen;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_recv_avail_from_start = true;
dconf->endpoint_recv_avail = 7;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Do connect, should succeed instantly. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
if (!dconf->delay_all_responses)
{
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0,
usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
}
else
{
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0,
usrsocktest_daemon_get_num_waiting_connect_sockets());
for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1;
count++)
{
TEST_ASSERT_TRUE(count <= 3);
usleep(25 * 1000);
}
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
}
/* Receive data from remote, daemon returns 4 bytes. */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(4, datalen);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote with address, daemon returns 3 bytes. */
addrlen = sizeof(remoteaddr);
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
&addrlen);
TEST_ASSERT_EQUAL(3, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3);
TEST_ASSERT_EQUAL(addrlen, sizeof(remoteaddr));
TEST_ASSERT_EQUAL_UINT8_ARRAY(&remoteaddr, &addr, addrlen);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(datalen + ret, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote, daemon has 0 bytes buffered => -EAGAIN */
data = databuf;
datalen = sizeof(databuf);
ret = read(sd, data, datalen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(7, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Reset recv buffer for open sockets */
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0));
for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(5 * 1000);
}
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Receive data from remote, daemon returns 4 bytes. */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(4, datalen);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(7 + 4, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: DelayedConnect
*
* Description:
* Non-blocking & delayed connect
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void DelayedConnect(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
int count;
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
char databuf[4];
struct sockaddr_in remoteaddr;
socklen_t addrlen;
/* Start test daemon. */
dconf->endpoint_block_connect = true;
dconf->endpoint_recv_avail_from_start = false;
dconf->endpoint_recv_avail = 4;
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Try receive data, not connected yet. */
data = databuf;
datalen = sizeof(databuf);
ret = read(sd, data, datalen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Release delayed connect. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0;
count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Try receive data, not received data yet. */
data = databuf;
datalen = sizeof(databuf);
addrlen = sizeof(remoteaddr);
ret = recvfrom(sd, data, datalen, 0, (FAR struct sockaddr *)&remoteaddr,
&addrlen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(0, addrlen);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Reset recv buffer for open sockets */
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0));
for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(5 * 1000);
}
/* Receive data from remote, daemon returns 4 bytes. */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(4, datalen);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abcd", data, 4);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(4, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Close socket. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV,
usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: NoBlockRecv test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(NoBlockRecv)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: NoBlockRecv test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(NoBlockRecv)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(NoBlockRecv, Receive)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Receive(&usrsocktest_daemon_config);
}
TEST(NoBlockRecv, ReceiveDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Receive(&usrsocktest_daemon_config);
}
TEST(NoBlockRecv, DelayedConnect)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
DelayedConnect(&usrsocktest_daemon_config);
}
TEST(NoBlockRecv, DelayedConnectDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
DelayedConnect(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(NoBlockRecv)
{
RUN_TEST_CASE(NoBlockRecv, Receive);
RUN_TEST_CASE(NoBlockRecv, ReceiveDelay);
RUN_TEST_CASE(NoBlockRecv, DelayedConnect);
RUN_TEST_CASE(NoBlockRecv, DelayedConnectDelay);
}

View File

@ -0,0 +1,414 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_noblock_send.c
* Send through the socket in non-blocking mode
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: Send
*
* Description:
* Open socket, connect instantly and send
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void Send(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
int count;
ssize_t ret;
size_t datalen;
const void *data;
struct sockaddr_in addr;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Do connect, should succeed instantly. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
if (!dconf->delay_all_responses)
{
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
}
else
{
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1;
count++)
{
TEST_ASSERT_TRUE(count <= 3);
usleep(25 * 1000);
}
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
}
/* Send data to remote */
data = "abcde";
datalen = strlen("abcde");
ret = sendto(sd, data, datalen, 0, NULL, 0);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
}
/****************************************************************************
* Name: ConnectSend
*
* Description:
* Open socket, connect is delayed and send
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
int count;
ssize_t ret;
size_t datalen;
const void *data;
struct sockaddr_in addr;
/* Start test daemon. */
dconf->endpoint_block_connect = true;
dconf->endpoint_block_send = true;
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Launch connect attempt, daemon delays actual connection until triggered. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Send data to remote, not connected yet. */
data = "abcde";
datalen = strlen("abcde");
ret = write(sd, data, datalen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Release delayed connect. */
TEST_ASSERT_TRUE(usrsocktest_daemon_establish_waiting_connections());
for (count = 0; usrsocktest_daemon_get_num_waiting_connect_sockets() > 0;
count++)
{
TEST_ASSERT_TRUE(count <= 5);
usleep(10 * 1000);
}
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Send data to remote */
data = "abcde";
datalen = strlen("abcde");
ret = write(sd, data, datalen);
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EAGAIN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_send_bytes());
/* Close socket. */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV,
usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: NoBlockSend test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(NoBlockSend)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: NoBlockSend test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(NoBlockSend)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(NoBlockSend, Send)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
Send(&usrsocktest_daemon_config);
}
TEST(NoBlockSend, SendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
Send(&usrsocktest_daemon_config);
}
TEST(NoBlockSend, ConnectSend)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ConnectSend(&usrsocktest_daemon_config);
}
TEST(NoBlockSend, ConnectSendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ConnectSend(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(NoBlockSend)
{
RUN_TEST_CASE(NoBlockSend, Send);
RUN_TEST_CASE(NoBlockSend, SendDelay);
RUN_TEST_CASE(NoBlockSend, ConnectSend);
RUN_TEST_CASE(NoBlockSend, ConnectSendDelay);
}

View File

@ -0,0 +1,154 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_nodaemon.c
* Tests without user socket daemon
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: NoDaemon test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(NoDaemon)
{
sd = -1;
}
/****************************************************************************
* Name: NoDaemon test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(NoDaemon)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
}
/****************************************************************************
* Name: NoSocket
*
* Description:
* Simple test for opening socket without usrsock daemon running
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST(NoDaemon, NoSocket)
{
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_EQUAL(-1, sd);
TEST_ASSERT_TRUE(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT || errno == ENETDOWN);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(NoDaemon)
{
RUN_TEST_CASE(NoDaemon, NoSocket);
}

View File

@ -0,0 +1,646 @@
/****************************************************************************
* examples/usrsocktest/usrsocktest_poll.c
* User socket polling tests
*
* Copyright (C) 2015, 2017 Haltian Ltd. All rights reserved.
* Authors: Roman Saveljev <roman.saveljev@haltian.com>
* Jussi Kivilinna <jussi.kivilinna@haltian.com>
*
* 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 NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <stdbool.h>
#include <assert.h>
#include <fcntl.h>
#include <poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "defines.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static bool started;
static int sd;
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ConnectReceive
*
* Description:
* Non-blocking connect and receive
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ConnectReceive(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
int count;
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
char databuf[4];
struct pollfd pfd;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_recv_avail_from_start = false;
dconf->endpoint_recv_avail = 3;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Poll for input (instant timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 0);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR);
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
/* Do connect, should succeed instantly. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
if (!dconf->delay_all_responses)
{
TEST_ASSERT_EQUAL(0, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
}
else
{
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
for (count = 0; usrsocktest_daemon_get_num_connected_sockets() != 1; count++)
{
TEST_ASSERT_TRUE(count <= 3);
usleep(25 * 1000);
}
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
}
/* Poll for input (instant timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 0);
TEST_ASSERT_EQUAL(0, ret);
/* Poll for input (with timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 10);
TEST_ASSERT_EQUAL(0, ret);
/* Poll for input (no timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 100));
ret = poll(&pfd, 1, -1);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(POLLIN, pfd.revents);
/* Receive data from remote, daemon returns 3 bytes. */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
TEST_ASSERT_EQUAL(3, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(3, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Poll for input (instant timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 0);
TEST_ASSERT_EQUAL(0, ret);
/* Make more data avail */
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('r', 0));
for (count = 0; usrsocktest_daemon_get_num_recv_empty_sockets() > 0; count++)
{
TEST_ASSERT_TRUE(count <= 3);
usleep(5 * 1000);
}
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Poll for input (no timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, -1);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(POLLIN, pfd.revents);
/* Receive data from remote, daemon returns 3 bytes. */
data = databuf;
datalen = sizeof(databuf);
ret = recvfrom(sd, data, datalen, 0, NULL, NULL);
TEST_ASSERT_EQUAL(3, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY("abc", data, 3);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(6, usrsocktest_daemon_get_recv_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: ConnectSend
*
* Description:
* Non-blocking connect and receive
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void ConnectSend(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
ssize_t ret;
size_t datalen;
void *data;
struct sockaddr_in addr;
struct pollfd pfd;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_recv_avail_from_start = true;
dconf->endpoint_recv_avail = 3;
dconf->endpoint_block_send = false;
dconf->endpoint_block_connect = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Poll for input (instant timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 0);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR);
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
/* Start non-blocking connect. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Poll for input (no timeout). As send is ready after established connection,
* poll will exit with POLLOUT. */
memset(&pfd, 0, sizeof(pfd));
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('E', 100));
pfd.fd = sd;
pfd.events = POLLOUT;
ret = poll(&pfd, 1, -1);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(POLLOUT, pfd.revents);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EISCONN, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Send data to remote. */
data = "abcdeFG";
datalen = strlen(data);
ret = write(sd, data, datalen);
TEST_ASSERT_EQUAL(datalen, ret);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(datalen, usrsocktest_daemon_get_send_bytes());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_recv_empty_sockets());
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
}
/****************************************************************************
* Name: DaemonAbort
*
* Description:
* Poll with daemon abort
*
* Input Parameters:
* dconf - socket daemon configuration
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
static void DaemonAbort(struct usrsocktest_daemon_conf_s *dconf)
{
int flags;
ssize_t ret;
struct sockaddr_in addr;
struct pollfd pfd;
/* Start test daemon. */
dconf->endpoint_addr = "127.0.0.1";
dconf->endpoint_port = 255;
dconf->endpoint_recv_avail_from_start = false;
dconf->endpoint_recv_avail = 3;
dconf->endpoint_block_send = false;
dconf->endpoint_block_connect = true;
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_start(dconf));
started = true;
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_active_sockets());
/* Open socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT_TRUE(sd >= 0);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Make socket non-blocking */
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(0, flags & O_NONBLOCK);
ret = fcntl(sd, F_SETFL, flags | O_NONBLOCK);
TEST_ASSERT_EQUAL(0, ret);
flags = fcntl(sd, F_GETFL, 0);
TEST_ASSERT_TRUE(flags >= 0);
TEST_ASSERT_EQUAL(O_RDWR, flags & O_RDWR);
TEST_ASSERT_EQUAL(O_NONBLOCK, flags & O_NONBLOCK);
/* Poll for input (instant timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 0);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLERR);
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
TEST_ASSERT_EQUAL(POLLIN, pfd.revents & POLLIN);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
/* Start non-blocking connect. */
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(255);
ret = connect(sd, (FAR const struct sockaddr *)&addr, sizeof(addr));
TEST_ASSERT_EQUAL(-1, ret);
TEST_ASSERT_EQUAL(EINPROGRESS, errno);
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(1, usrsocktest_daemon_get_num_waiting_connect_sockets());
/* Poll for input (no timeout). Stop daemon forcefully. */
memset(&pfd, 0, sizeof(pfd));
TEST_ASSERT_TRUE(usrsocktest_send_delayed_command('S', 100));
pfd.fd = sd;
pfd.events = POLLOUT;
ret = poll(&pfd, 1, -1);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR);
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
/* Stopping daemon should succeed. */
TEST_ASSERT_EQUAL(OK, usrsocktest_daemon_stop());
started = false;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(0, usrsocktest_endp_malloc_cnt);
TEST_ASSERT_EQUAL(0, usrsocktest_dcmd_malloc_cnt);
/* Poll for input (no timeout). */
memset(&pfd, 0, sizeof(pfd));
pfd.fd = sd;
pfd.events = POLLOUT;
ret = poll(&pfd, 1, -1);
TEST_ASSERT_EQUAL(1, ret);
TEST_ASSERT_EQUAL(POLLERR, pfd.revents & POLLERR);
TEST_ASSERT_EQUAL(POLLHUP, pfd.revents & POLLHUP);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLIN);
TEST_ASSERT_EQUAL(0, pfd.revents & POLLOUT);
/* Close socket */
TEST_ASSERT_TRUE(close(sd) >= 0);
sd = -1;
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_active_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_connected_sockets());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_send_bytes());
TEST_ASSERT_EQUAL(-ENODEV, usrsocktest_daemon_get_num_recv_empty_sockets());
}
/****************************************************************************
* Name: Poll test group setup
*
* Description:
* Setup function executed before each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_SETUP(Poll)
{
sd = -1;
started = false;
}
/****************************************************************************
* Name: Poll test group teardown
*
* Description:
* Setup function executed after each testcase in this test group
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions/Limitations:
* None
*
****************************************************************************/
TEST_TEAR_DOWN(Poll)
{
int ret;
if (sd >= 0)
{
ret = close(sd);
assert(ret >= 0);
}
if (started)
{
ret = usrsocktest_daemon_stop();
assert(ret == OK);
}
}
TEST(Poll, ConnectReceive)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ConnectReceive(&usrsocktest_daemon_config);
}
TEST(Poll, ConnectReceiveDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ConnectReceive(&usrsocktest_daemon_config);
}
TEST(Poll, ConnectSend)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
ConnectSend(&usrsocktest_daemon_config);
}
TEST(Poll, ConnectSendDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
ConnectSend(&usrsocktest_daemon_config);
}
TEST(Poll, DaemonAbort)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
DaemonAbort(&usrsocktest_daemon_config);
}
TEST(Poll, DaemonAbortDelay)
{
usrsocktest_daemon_config = usrsocktest_daemon_defconf;
usrsocktest_daemon_config.delay_all_responses = true;
DaemonAbort(&usrsocktest_daemon_config);
}
/****************************************************************************
* Public Functions
****************************************************************************/
TEST_GROUP(Poll)
{
RUN_TEST_CASE(Poll, ConnectReceive);
RUN_TEST_CASE(Poll, ConnectReceiveDelay);
RUN_TEST_CASE(Poll, ConnectSend);
RUN_TEST_CASE(Poll, ConnectSendDelay);
RUN_TEST_CASE(Poll, DaemonAbort);
RUN_TEST_CASE(Poll, DaemonAbortDelay);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,8 @@
#include <stdbool.h>
#include <nuttx/net/netconfig.h>
#include <nuttx/net/ethernet.h>
#include <nuttx/net/ip.h>
/****************************************************************************
* Pre-processor Definitions

View File

@ -1017,10 +1017,10 @@ o rmmod <module-name>
NAME INIT UNINIT ARG TEXT SIZE DATA SIZE
nsh>
o set <name> <value>
o set [{+|-}{e|x|xe|ex}] [<name> <value>]
Set the environment variable <name> to the sting <value>.
For example,
Set the environment variable <name> to the sting <value> and or set NSH
parser control options. For example,
nsh> echo $foobar
@ -1029,6 +1029,38 @@ o set <name> <value>
foovalue
nsh>
Set the 'exit on error control' and/or 'print a trace' of commands when parsing
scripts in NSH. The settinngs are in effect from the point of exection, until
they are changed again, or in the case of the init script, the settings are
returned to the default settings when it exits. Included child scripts will run
with the parents settings and changes made in the child script will effect the
parent on return.
Use 'set -e' to enable and 'set +e' to disable (ignore) the exit condition on commands.
The default is -e. Errors cause script to exit.
Use 'set -x' to enable and 'set +x' to disable (silence) printing a trace of the script
commands as they are ececuted.
The default is +x. No printing of a trace of script commands as they are executed.
Example 1 - no exit on command not found
set +e
notacommand
Example 2 - will exit on command not found
set -e
notacommand
Example 3 - will exit on command not found, and print a trace of the script commmands
set -ex
Example 4 - will exit on command not found, and print a trace of the script commmands
and set foobar to foovalue.
set -ex foobar foovalue
nsh> echo $foobar
foovalue
o sh <script-path>
Execute the sequence of NSH commands in the file referred

View File

@ -690,6 +690,15 @@
# undef NSH_HAVE_TRIMSPACES
#endif
#ifndef CONFIG_NSH_DISABLESCRIPT
# define NSH_NP_SET_OPTIONS "ex" /* Maintain order see nsh_npflags_e */
# define NSH_NP_SET_OPTIONS_INIT (NSH_PFLAG_SILENT)
#endif
#if defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_NSH_DISABLESCRIPT)
# define CONFIG_NSH_DISABLE_SET
#endif
/****************************************************************************
* Public Types
****************************************************************************/
@ -741,6 +750,22 @@ struct nsh_loop_s
};
#endif
#ifndef CONFIG_NSH_DISABLESCRIPT
/* Define the bits that correspond to the option defined in
* NSH_NP_SET_OPTIONS. The bit value is 1 shifted left the offset
* of the char in NSH_NP_SET_OPTIONS string.
*/
enum nsh_npflags_e
{
NSH_PFLAG_IGNORE = 1, /* set for +e no exit on errors,
* cleared -e exit on error */
NSH_PFLAG_SILENT = 2, /* cleared -x print a trace of commands
* when parsing.
* set +x no print a trace of commands */
};
#endif
/* These structure provides the overall state of the parser */
struct nsh_parser_s
@ -752,6 +777,9 @@ struct nsh_parser_s
bool np_redirect; /* true: Output from the last command was re-directed */
#endif
bool np_fail; /* true: The last command failed */
#ifndef CONFIG_NSH_DISABLESCRIPT
uint8_t np_flags; /* See nsh_npflags_e above */
#endif
#ifndef CONFIG_NSH_DISABLEBG
int np_nice; /* "nice" value applied to last background cmd */
#endif
@ -1175,10 +1203,10 @@ int cmd_lsmod(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
int cmd_uname(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_DISABLE_ENVIRON
# ifndef CONFIG_NSH_DISABLE_SET
#ifndef CONFIG_NSH_DISABLE_SET
int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#endif
#ifndef CONFIG_DISABLE_ENVIRON
# ifndef CONFIG_NSH_DISABLE_UNSET
int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif

View File

@ -436,10 +436,14 @@ static const struct cmdmap_s g_cmdmap[] =
{ "rmmod", cmd_rmmod, 2, 2, "<module-name>" },
#endif
#ifndef CONFIG_DISABLE_ENVIRON
# ifndef CONFIG_NSH_DISABLE_SET
#ifndef CONFIG_NSH_DISABLE_SET
# if !defined(CONFIG_DISABLE_ENVIRON) && !defined(CONFIG_NSH_DISABLESCRIPT)
{ "set", cmd_set, 2, 4, "[{+|-}{e|x|xe|ex}] [<name> <value>]" },
# elif !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_NSH_DISABLESCRIPT)
{ "set", cmd_set, 3, 3, "<name> <value>" },
# endif
# elif defined(CONFIG_DISABLE_ENVIRON) && !defined(CONFIG_NSH_DISABLESCRIPT)
{ "set", cmd_set, 2, 2, "{+|-}{e|x|xe|ex}" },
# endif
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_NSH_DISABLESCRIPT)

View File

@ -480,5 +480,11 @@ FAR struct console_stdio_s *nsh_newconsole(void)
#endif
}
#ifndef CONFIG_NSH_DISABLESCRIPT
/* Set the initial option flags */
pstate->cn_vtbl.np.np_flags = NSH_NP_SET_OPTIONS_INIT;
#endif
return pstate;
}

View File

@ -85,6 +85,12 @@ int nsh_consolemain(int argc, char *argv[])
/* Execute the start-up script */
(void)nsh_initscript(&pstate->cn_vtbl);
#ifndef CONFIG_NSH_DISABLESCRIPT
/* Reset the option flags */
pstate->cn_vtbl.np.np_flags = NSH_NP_SET_OPTIONS_INIT;
#endif
#endif
#ifdef CONFIG_NSH_USBDEV_TRACE

View File

@ -311,29 +311,86 @@ int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
* Name: cmd_set
****************************************************************************/
#ifndef CONFIG_DISABLE_ENVIRON
#ifndef CONFIG_NSH_DISABLE_SET
int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
FAR char *value;
int ret;
int ret = OK;
int ndx = 1;
#ifndef CONFIG_NSH_DISABLESCRIPT
FAR char *popt;
const char opts[] = NSH_NP_SET_OPTIONS;
int op;
/* Trim whitespace from the value */
/* Support set [{+|-}{e|x|xe|ex}] [<name> <value>] */
value = nsh_trimspaces(argv[2]);
/* Set the environment variable */
ret = setenv(argv[1], value, TRUE);
if (ret < 0)
if (argc == 2 || argc == 4)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
}
if (strlen(argv[1]) < 2)
{
ret = -EINVAL;
nsh_output(vtbl, g_fmtargrequired, argv[0], "set", NSH_ERRNO);
}
else
{
op = argv[1][0];
if (op != '-' && op != '+')
{
ret = -EINVAL;
nsh_output(vtbl, g_fmtarginvalid, argv[0], "set", NSH_ERRNO);
}
else
{
value = &argv[1][1];
while(*value && *value != ' ')
{
popt = strchr(opts, *value++);
if (popt == NULL)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0], "set", NSH_ERRNO);
ret = -EINVAL;
break;
}
if (op == '+')
{
vtbl->np.np_flags |= 1 << (popt-opts);
}
else
{
vtbl->np.np_flags &= ~(1 << (popt-opts));
}
}
if (ret == OK)
{
ndx = 2;
}
}
}
}
# ifndef CONFIG_DISABLE_ENVIRON
if (ret == OK && (argc == 3 || argc == 4))
# endif
#endif
#ifndef CONFIG_DISABLE_ENVIRON
{
/* Trim whitespace from the value */
value = nsh_trimspaces(argv[ndx+1]);
/* Set the environment variable */
ret = setenv(argv[ndx], value, TRUE);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
}
}
#endif
return ret;
}
#endif
#endif
/****************************************************************************
* Name: cmd_unset

View File

@ -575,7 +575,7 @@ static int nsh_gethostip(FAR char *hostname, FAR union ip_addr_u *ipaddr,
static void wget_callback(FAR char **buffer, int offset, int datend,
FAR int *buflen, FAR void *arg)
{
(void)write((int)arg, &((*buffer)[offset]), datend - offset);
(void)write((int)((intptr_t)arg), &((*buffer)[offset]), datend - offset);
}
#endif
#endif
@ -1668,7 +1668,7 @@ int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* And perform the wget */
ret = wget(url, buffer, 512, wget_callback, (FAR void *)fd);
ret = wget(url, buffer, 512, wget_callback, (FAR void *)((intptr_t)fd));
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "wget", NSH_ERRNO);

View File

@ -101,13 +101,17 @@
/* Select the single network device name supported this this network
* initialization logci. If multiple interfaces are present with different
* link types, the the orider of definition in the following conditional
* logic will select the one interface that will be used.
* link types, the the order of definition in the following conditional
* logic will select the one interface that will be used (which might
* not be the one that you want).
*/
#if defined(CONFIG_NET_ETHERNET)
# define NET_DEVNAME "eth0"
# define NSH_HAVE_NETDEV
#elif defined(CONFIG_NET_6LOWPAN)
# define NET_DEVNAME "wpan0"
# define NSH_HAVE_NETDEV
#elif defined(CONFIG_NET_SLIP)
# define NET_DEVNAME "sl0"
# ifndef CONFIG_NSH_NOMAC
@ -120,6 +124,8 @@
#elif defined(CONFIG_NET_LOCAL)
# define NET_DEVNAME "lo"
# define NSH_HAVE_NETDEV
#elif defined(CONFIG_NET_USRSOCK)
# undef NSH_HAVE_NETDEV
#elif !defined(CONFIG_NET_LOOPBACK)
# error ERROR: No link layer protocol defined
#endif
@ -200,7 +206,7 @@ static const uint16_t g_ipv6_netmask[8] =
HTONS(CONFIG_NSH_IPv6NETMASK_7),
HTONS(CONFIG_NSH_IPv6NETMASK_8),
};
#endif /* CONFIG_NET_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF*/
#endif /* CONFIG_NET_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF */
/****************************************************************************
* Private Functions

View File

@ -1169,6 +1169,11 @@ static FAR char *nsh_argexpand(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline,
envstr = nsh_envexpand(vtbl, ptr);
if ((vtbl->np.np_flags & NSH_PFLAG_SILENT) == 0)
{
nsh_output(vtbl," %s=%s\n", ptr, envstr ? envstr :"(null)");
}
/* Concatenate the result of the operation with the accumulated
* string. On failures to allocation memory, nsh_strcat will
* just return value value of argument

View File

@ -136,10 +136,15 @@ int nsh_script(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
* considerable amount of stack may be used.
*/
if ((vtbl->np.np_flags & NSH_PFLAG_SILENT) == 0)
{
nsh_output(vtbl,"%s", buffer);
}
ret = nsh_parse(vtbl, buffer);
}
}
while (pret && ret == OK);
while (pret && (ret == OK || (vtbl->np.np_flags & NSH_PFLAG_IGNORE)));
/* Close the script file */