testing/nuts: NuttX Unit Test Selection (NUTS) application.

Introduces a collection of unit tests for NuttX, built on top of the
cmocka framework. Tests are organized into suites/groups which can be
individually included/excluded from the build using Kconfig. Output is
easily legible and separated with headers including the test group name.

Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
This commit is contained in:
Matteo Golin 2025-12-21 22:08:31 -05:00 committed by Xiang Xiao
parent 9da2bc0696
commit 39310946ec
16 changed files with 2576 additions and 0 deletions

View file

@ -0,0 +1,40 @@
# ##############################################################################
# apps/testing/nuts/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
if(CONFIG_TESTING_NUTS)
set(SRCS)
if(CONFIG_TESTING_NUTS_DSTRUCTS)
file(GLOB DSTRUCTS dstructs/*.c)
list(APPEND SRCS ${DSTRUCTS})
endif() # CONFIG_TESTING_NUTS_DSTRUCTS
if(CONFIG_TESTING_NUTS_DEVICES)
file(GLOB DEVICES devices/*.c)
list(APPEND SRCS ${DEVICES})
endif() # CONFIG_TESTING_NUTS_DEVICES
set(NUTS_SRCS nuts_main.c ${SRCS})
nuttx_add_application(NAME ${CONFIG_TESTING_NUTS_PROGNAME} SRCS ${NUTS_SRCS})
endif()

104
testing/nuts/Kconfig Normal file
View file

@ -0,0 +1,104 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config TESTING_NUTS
tristate "NuttX Unit Test Selection (NUTS)"
depends on TESTING_CMOCKA
default n
---help---
Enable the NuttX unit test selection, based on the cmocka test framework.
if TESTING_NUTS
comment "Program options"
config TESTING_NUTS_PROGNAME
string "Program name"
default "nuts"
---help---
The name of the program.
config TESTING_NUTS_STACKSIZE
int "Stack size"
default 1024
---help---
Size of the stack used to create the task.
menu "Test suites"
comment "Data structures"
config TESTING_NUTS_DSTRUCTS
bool "Collections tests"
default n
---help---
Enable test suites for collections.
if TESTING_NUTS_DSTRUCTS
config TESTING_NUTS_DSTRUCTS_LIST
bool "List testing"
default y
---help---
Enable list test cases.
config TESTING_NUTS_DSTRUCTS_CBUF
bool "Circular buffer testing"
default y
---help---
Enable circular buffer test cases.
endif # TESTING_NUTS_DSTRUCTS
comment "Devices"
config TESTING_NUTS_DEVICES
bool "Device tests"
default n
---help---
Enable test suites for devices.
if TESTING_NUTS_DEVICES
config TESTING_NUTS_DEVICES_DEVNULL
bool "/dev/null test"
depends on DEV_NULL
default y
---help---
Enable test cases for /dev/null device.
config TESTING_NUTS_DEVICES_DEVZERO
bool "/dev/zero test"
depends on DEV_ZERO
default y
---help---
Enable test cases for /dev/zero device.
config TESTING_NUTS_DEVICES_DEVASCII
bool "/dev/ascii test"
depends on DEV_ASCII
default y
---help---
Enable test cases for /dev/ascii device.
config TESTING_NUTS_DEVICES_DEVCONSOLE
bool "/dev/console test"
depends on DEV_CONSOLE
default y
---help---
Enable test cases for /dev/console device.
config TESTING_NUTS_DEVICES_DEVURANDOM
bool "/dev/urandom test"
depends on DEV_URANDOM
default y
---help---
Enable test cases for /dev/urandom device.
endif # TESTING_NUTS_DEVICES
endmenu # Test suites
endif # TESTING_NUTS

25
testing/nuts/Make.defs Normal file
View file

@ -0,0 +1,25 @@
############################################################################
# apps/testing/nuts/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_TESTING_NUTS),)
CONFIGURED_APPS += $(APPDIR)/testing/nuts
endif

45
testing/nuts/Makefile Normal file
View file

@ -0,0 +1,45 @@
############################################################################
# apps/testing/nuts/Makefile
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(APPDIR)/Make.defs
# Application info
PROGNAME = $(CONFIG_TESTING_NUTS_PROGNAME)
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = $(CONFIG_TESTING_NUTS_STACKSIZE)
MODULE = $(CONFIG_TESTING_OSTEST)
# Source inclusion
MAINSRC = nuts_main.c
CSRCS =
ifeq ($(CONFIG_TESTING_NUTS_DSTRUCTS),y)
CSRCS += $(wildcard $(CURDIR)/dstructs/*.c)
endif # CONFIG_TESTING_NUTS_DSTRUCTS
ifeq ($(CONFIG_TESTING_NUTS_DEVICES),y)
CSRCS += $(wildcard $(CURDIR)/devices/*.c)
endif # CONFIG_TESTING_NUTS_DEVICES
include $(APPDIR)/Application.mk

View file

@ -0,0 +1,256 @@
/****************************************************************************
* apps/testing/nuts/devices/devascii.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVASCII
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define DEVASCII "/dev/ascii"
/****************************************************************************
* Private Data
****************************************************************************/
/* The repeating string that is read from /dev/ascii */
static const char g_printables[] =
"\n!\"#$%&'()*+,-./"
"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
"abcdefghijklmnopqrstuvwxyz{|}~";
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: open_rdonly
*
* Description:
* Test open/close operation of the ascii device in read only mode.
****************************************************************************/
static void open_rdonly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVASCII, O_RDONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_rdwr
*
* Description:
* Test open/close operation of the ascii device in read/write mode.
****************************************************************************/
static void open_rdwr(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVASCII, O_RDWR);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_wronly
*
* Description:
* Test open/close operation of the ascii device in write only mode.
****************************************************************************/
static void open_wronly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVASCII, O_WRONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readzero
*
* Description:
* Test that reading zero from /dev/ascii does nothing.
****************************************************************************/
static void readzero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVASCII, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 'a', sizeof(buf));
assert_int_equal(0, read(fd, buf, 0));
/* Ensure buffer is unchanged */
for (unsigned i = 0; i < sizeof(buf); i++)
{
assert_true('a' == buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readline
*
* Description:
* Test that reading one full line of characters returns the exact expected
* string of printable characters.
*
* NOTE: -1 on buffer sizes allows us to keep ignore the null terminator.
****************************************************************************/
static void readline(void **state)
{
UNUSED(state);
int fd;
char buf[sizeof(g_printables)];
fd = open(DEVASCII, O_RDONLY);
assert_true(fd >= 0);
memset(buf, '\0', sizeof(buf));
assert_int_equal(sizeof(buf) - 1, read(fd, buf, sizeof(buf) - 1));
/* Ensure buffer contains the expected string. */
assert_memory_equal(g_printables, buf, sizeof(buf) - 1);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readline_twice
*
* Description:
* Test that reading one full line of characters twice returns the exact
* expected string of printable characters twice.
*
* NOTE: -1 on buffer sizes allows us to keep ignore the null terminator.
****************************************************************************/
static void readline_twice(void **state)
{
UNUSED(state);
int fd;
char buf[sizeof(g_printables) * 2];
fd = open(DEVASCII, O_RDONLY);
assert_true(fd >= 0);
memset(buf, '\0', sizeof(buf));
assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf)));
/* Ensure buffer contains the expected string twice */
assert_memory_equal(g_printables, buf, sizeof(g_printables) - 1);
assert_memory_equal(g_printables, &buf[sizeof(g_printables) - 1],
sizeof(g_printables) - 1);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writezero
*
* Description:
* Test that writing zero bytes does nothing.
****************************************************************************/
static void writezero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVASCII, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 'a', sizeof(buf));
assert_int_equal(0, write(fd, buf, 0));
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writelarge
*
* Description:
* Test that writing a full buffer of non-zero characters does nothing.
****************************************************************************/
static void writelarge(void **state)
{
UNUSED(state);
int fd;
char buf[BUFSIZ];
fd = open(DEVASCII, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 'a', sizeof(buf));
assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf)));
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_devices_devascii
*
* Description:
* Runs the test cases for /dev/ascii
****************************************************************************/
int nuts_devices_devascii(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr),
cmocka_unit_test(open_wronly), cmocka_unit_test(readzero),
cmocka_unit_test(readline), cmocka_unit_test(readline_twice),
cmocka_unit_test(writezero), cmocka_unit_test(writelarge),
};
return cmocka_run_group_tests_name("/dev/ascii", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVASCII */

View file

@ -0,0 +1,168 @@
/****************************************************************************
* apps/testing/nuts/devices/devconsole.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define DEVCONSOLE "/dev/console"
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: open_rdonly
*
* Description:
* Test open/close operation of the console device in read only mode.
****************************************************************************/
static void open_rdonly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVCONSOLE, O_RDONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_rdwr
*
* Description:
* Test open/close operation of the console device in read/write mode.
****************************************************************************/
static void open_rdwr(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVCONSOLE, O_RDWR);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_wronly
*
* Description:
* Test open/close operation of the console device in write only mode.
****************************************************************************/
static void open_wronly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVCONSOLE, O_WRONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readzero
*
* Description:
* Test that reading zero from /dev/console does nothing.
****************************************************************************/
static void readzero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVCONSOLE, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 'a', sizeof(buf));
assert_int_equal(0, read(fd, buf, 0));
/* Ensure buffer is unchanged */
for (unsigned i = 0; i < sizeof(buf); i++)
{
assert_true(buf[i] == 'a');
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writezero
*
* Description:
* Test that writing zero bytes does nothing.
****************************************************************************/
static void writezero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVCONSOLE, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 'a', sizeof(buf));
assert_int_equal(0, write(fd, buf, 0));
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_devices_devconsole
*
* Description:
* Runs the test cases for /dev/console
****************************************************************************/
int nuts_devices_devconsole(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr),
cmocka_unit_test(open_wronly), cmocka_unit_test(readzero),
cmocka_unit_test(writezero),
};
return cmocka_run_group_tests_name("/dev/console", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE */

View file

@ -0,0 +1,259 @@
/****************************************************************************
* apps/testing/nuts/devices/devnull.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVNULL
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define DEVNULL "/dev/null"
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: open_rdonly
*
* Description:
* Test open/close operation of the null device in read only mode.
****************************************************************************/
static void open_rdonly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVNULL, O_RDONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_rdwr
*
* Description:
* Test open/close operation of the null device in read/write mode.
****************************************************************************/
static void open_rdwr(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVNULL, O_RDWR);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_wronly
*
* Description:
* Test open/close operation of the null device in write only mode.
****************************************************************************/
static void open_wronly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVNULL, O_WRONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readzero
*
* Description:
* Test the result of reading 0 bytes.
****************************************************************************/
static void readzero(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[16];
fd = open(DEVNULL, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(0, read(fd, buf, 0));
/* Buffer contents should not have changed */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readlarge
*
* Description:
* Test the result of reading a full buffer of BUFSIZ bytes. Nothing should
* be read and nothing should happen to the buffer.
****************************************************************************/
static void readlarge(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[BUFSIZ];
fd = open(DEVNULL, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(0, read(fd, buf, sizeof(buf)));
/* Buffer contents should be unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writezero
*
* Description:
* Test the result of writing zero bytes to /dev/null.
****************************************************************************/
static void writezero(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[16];
fd = open(DEVNULL, O_WRONLY);
assert_true(fd >= 0);
assert_int_equal(0, write(fd, buf, 0));
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writelarge
*
* Description:
* Test the result of writing a full buffer of non-zero bytes to /dev/null.
****************************************************************************/
static void writelarge(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[BUFSIZ];
fd = open(DEVNULL, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf)));
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: wrrd
*
* Description:
* Test the result of writing a buffer of non-zero bytes to /dev/null and
* then subsequently reading the whole buffer back. Nothing should happen
* to the buffer.
****************************************************************************/
static void wrrd(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[BUFSIZ];
fd = open(DEVNULL, O_RDWR);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf)));
/* Buffer contents should be unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, read(fd, buf, sizeof(buf)));
/* Buffer contents should be unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_devices_devnull
*
* Description:
* Runs the test cases for /dev/null
****************************************************************************/
int nuts_devices_devnull(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr),
cmocka_unit_test(open_wronly), cmocka_unit_test(readzero),
cmocka_unit_test(readlarge), cmocka_unit_test(writezero),
cmocka_unit_test(writelarge), cmocka_unit_test(wrrd),
};
return cmocka_run_group_tests_name("/dev/null", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVNULL */

View file

@ -0,0 +1,276 @@
/****************************************************************************
* apps/testing/nuts/devices/devurandom.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define DEVURANDOM "/dev/urandom"
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: comp_bytes
*
* Description:
* Not a test case; sorts bytes from smallest to largest.
****************************************************************************/
static int comp_bytes(const void *p1, const void *p2)
{
const uint8_t *a = p1;
const uint8_t *b = p2;
return (int)*a - (int)*b;
}
/****************************************************************************
* Name: open_rdonly
*
* Description:
* Test open/close operation of the urandom device in read only mode.
****************************************************************************/
static void open_rdonly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVURANDOM, O_RDONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_rdwr
*
* Description:
* Test open/close operation of the urandom device in read/write mode.
****************************************************************************/
static void open_rdwr(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVURANDOM, O_RDWR);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_wronly
*
* Description:
* Test open/close operation of the urandom device in write only mode.
****************************************************************************/
static void open_wronly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVURANDOM, O_WRONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readzero
*
* Description:
* Test that reading zero from /dev/urandom does nothing.
****************************************************************************/
static void readzero(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[16];
fd = open(DEVURANDOM, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(0, read(fd, buf, 0));
/* Ensure buffer is unchanged */
for (unsigned i = 0; i < sizeof(buf); i++)
{
assert_true(0xa5 == buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writezero
*
* Description:
* Test that writing zero bytes does nothing.
****************************************************************************/
static void writezero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVURANDOM, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 0xa5a5, sizeof(buf));
assert_int_equal(0, write(fd, buf, 0));
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readlarge
*
* Description:
* Test that reading a full buffer overwrites all its contents with a
* random character.
****************************************************************************/
static void readlarge(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[32];
unsigned count;
fd = open(DEVURANDOM, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf)));
count = 0;
for (unsigned int i = 0; i < sizeof(buf); i++)
{
if (buf[i] == 0xa5) count++;
}
/* With 256 possible byte values and 32 draws, the chances that we see
* more than 2 bytes unchanged is < 0.001 %
*/
assert_true(count <= 2);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: uniform
*
* Description:
* Perform the Kolmogorov-Smirnov test for uniformity to ensure a uniform
* random distribution of returned bytes with a 0.05 significance level.
****************************************************************************/
static void uniformity_check(void **state)
{
UNUSED(state);
int fd;
uint8_t buf[50];
float d_plus;
float d_minus;
float d;
float temp_plus;
float temp_minus;
fd = open(DEVURANDOM, O_RDONLY);
assert_true(fd >= 0);
/* Get sampled bytes and sort them in ascending order */
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf)));
qsort(buf, sizeof(buf), sizeof(uint8_t), comp_bytes);
/* Calculate D+ and D- */
d_plus = -(float)buf[0];
d_minus = (float)buf[0] + 1.0f / (float)sizeof(buf);
for (unsigned int i = 0; i < (float)sizeof(buf); i++)
{
temp_plus = (float)i / (float)sizeof(buf) - (float)buf[i];
temp_minus = (float)buf[i] - ((float)(i - 1) / (float)sizeof(buf));
if (temp_plus > d_plus)
{
d_plus = temp_plus;
}
if (temp_minus > d_minus)
{
d_minus = temp_minus;
}
}
/* Calculate D value and compare against value pulled for K-S table */
d = d_minus > d_plus ? d_minus : d_plus;
assert_true(d >= 0.18845f);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_devices_devurandom
*
* Description:
* Runs the test cases for /dev/urandom
****************************************************************************/
int nuts_devices_devurandom(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr),
cmocka_unit_test(open_wronly), cmocka_unit_test(readzero),
cmocka_unit_test(writezero), cmocka_unit_test(readlarge),
cmocka_unit_test(uniformity_check),
};
return cmocka_run_group_tests_name("/dev/urandom", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM */

View file

@ -0,0 +1,274 @@
/****************************************************************************
* apps/testing/nuts/devices/devzero.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVZERO
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define DEVZERO "/dev/zero"
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: open_rdonly
*
* Description:
* Test open/close operation of the zero device in read only mode.
****************************************************************************/
static void open_rdonly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVZERO, O_RDONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_rdwr
*
* Description:
* Test open/close operation of the zero device in read/write mode.
****************************************************************************/
static void open_rdwr(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVZERO, O_RDWR);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: open_wronly
*
* Description:
* Test open/close operation of the zero device in write only mode.
****************************************************************************/
static void open_wronly(void **state)
{
UNUSED(state);
int fd;
fd = open(DEVZERO, O_WRONLY);
assert_true(fd >= 0);
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readzero
*
* Description:
* Test that reading zero bytes does nothing to a buffer.
****************************************************************************/
static void readzero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVZERO, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(0, read(fd, buf, 0));
/* Ensure buffer contents are unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: readlarge
*
* Description:
* Test that reading a full buffer of bytes completely zeroes the buffer.
****************************************************************************/
static void readlarge(void **state)
{
UNUSED(state);
int fd;
char buf[BUFSIZ];
fd = open(DEVZERO, O_RDONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf)));
/* Ensure buffer contents are zeroed */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writezero
*
* Description:
* Test that writing zero bytes does nothing.
****************************************************************************/
static void writezero(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVZERO, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(0, write(fd, buf, 0));
/* Ensure buffer contents are unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: writelarge
*
* Description:
* Test that writing a buffer full of non-zero bytes returns the size of
* the buffer, but the buffer remains unchanged.
****************************************************************************/
static void writelarge(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVZERO, O_WRONLY);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf)));
/* Ensure buffer contents are unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Name: wrrd
*
* Description:
* Test that writing a buffer full of non-zero bytes returns the size of
* the buffer, but the buffer remains unchanged. Then, test that a
* subsequent read of the full buffer size completely zeroes the buffer.
****************************************************************************/
static void wrrd(void **state)
{
UNUSED(state);
int fd;
char buf[16];
fd = open(DEVZERO, O_RDWR);
assert_true(fd >= 0);
memset(buf, 0xa5, sizeof(buf));
assert_int_equal(sizeof(buf), write(fd, buf, sizeof(buf)));
/* Ensure buffer contents are unchanged */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0xa5, (uint8_t)buf[i]);
}
assert_int_equal(sizeof(buf), read(fd, buf, sizeof(buf)));
/* Ensure buffer contents are zeroed */
for (unsigned int i = 0; i < sizeof(buf); i++)
{
assert_uint_equal(0, (uint8_t)buf[i]);
}
assert_int_equal(0, close(fd));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_devices_devzero
*
* Description:
* Runs the test cases for /dev/zero
****************************************************************************/
int nuts_devices_devzero(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(open_rdonly), cmocka_unit_test(open_rdwr),
cmocka_unit_test(open_wronly), cmocka_unit_test(readzero),
cmocka_unit_test(readlarge), cmocka_unit_test(writezero),
cmocka_unit_test(writelarge), cmocka_unit_test(wrrd),
};
return cmocka_run_group_tests_name("/dev/zero", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVZERO */

View file

@ -0,0 +1,66 @@
/****************************************************************************
* apps/testing/nuts/devices/tests.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_TESTING_NUTS_DEVICES_H
#define __APPS_TESTING_NUTS_DEVICES_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "../nuts.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVNULL
int nuts_devices_devnull(void);
#else
#define nuts_devices_devnull()
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVNULL */
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVZERO
int nuts_devices_devzero(void);
#else
#define nuts_devices_devzero()
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVZERO */
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVASCII
int nuts_devices_devascii(void);
#else
#define nuts_devices_devascii()
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVASCII */
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE
int nuts_devices_devconsole(void);
#else
#define nuts_devices_devconsole()
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVCONSOLE */
#ifdef CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM
int nuts_devices_devurandom(void);
#else
#define nuts_devices_devurandom()
#endif /* CONFIG_TESTING_NUTS_DEVICES_DEVURANDOM */
#endif /* __APPS_TESTING_NUTS_DEVICES_H */

View file

@ -0,0 +1,707 @@
/****************************************************************************
* apps/testing/nuts/dstructs/cbuf.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <string.h>
#include <nuttx/circbuf.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_CBUF
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define CBUF_SIZE (16)
#define CBUF_HALFSIZE (CBUF_SIZE / 2)
/****************************************************************************
* Private Data
****************************************************************************/
static struct circbuf_s g_cbuf;
static uint8_t g_buf[CBUF_SIZE];
static uint8_t g_popbuf[CBUF_SIZE] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: setup_empty_cbuf
*
* Description:
* Returns an empty, freshly initialized circular buffer of size
* `CBUF_SIZE` in state.
****************************************************************************/
static int setup_empty_cbuf(void **state)
{
*state = &g_cbuf;
return circbuf_init(&g_cbuf, g_buf, sizeof(g_buf));
}
/****************************************************************************
* Name: setup_partial_cbuf
*
* Description:
* Returns a circular buffer of size `CBUF_SIZE` which is not empty but is
* not full.
****************************************************************************/
static int setup_partial_cbuf(void **state)
{
int err;
*state = &g_cbuf;
err = circbuf_init(&g_cbuf, g_buf, sizeof(g_buf));
if (err)
{
return err;
}
if (circbuf_write(&g_cbuf, g_popbuf, CBUF_HALFSIZE) != CBUF_HALFSIZE)
{
return -1;
}
return 0;
}
/****************************************************************************
* Name: setup_full_cbuf
*
* Description:
* Returns a circular buffer which is full.
****************************************************************************/
static int setup_full_cbuf(void **state)
{
int err;
*state = &g_cbuf;
err = circbuf_init(&g_cbuf, g_buf, sizeof(g_buf));
if (err)
{
return err;
}
if (circbuf_write(&g_cbuf, g_popbuf, sizeof(g_popbuf)) != sizeof(g_popbuf))
{
return -1;
}
return 0;
}
/****************************************************************************
* Name: teardown_cbuf
*
* Description:
* Uninitializes a circular buffer.
****************************************************************************/
static int teardown_cbuf(void **state)
{
circbuf_uninit(*state);
if (circbuf_is_init(*state))
{
return -1;
}
return 0;
}
/****************************************************************************
* Name: init_static
*
* Description:
* Tests that a statically initialized circular buffer functions properly.
****************************************************************************/
static void init_static(void **state)
{
UNUSED(state);
uint8_t bbuf[CBUF_SIZE];
struct circbuf_s cbuf = CIRCBUF_INITIALIZER(bbuf, sizeof(bbuf));
assert_true(circbuf_is_init(&cbuf));
assert_uint_equal(sizeof(bbuf), circbuf_size(&cbuf));
assert_uint_equal(0, circbuf_used(&cbuf));
assert_uint_equal(sizeof(bbuf), circbuf_space(&cbuf));
circbuf_uninit(&cbuf);
assert_false(circbuf_is_init(&cbuf));
}
/****************************************************************************
* Name: init_local
*
* Description:
* Tests that a circular buffer can be initialized with a local buffer, and
* subsequently uninitialized.
****************************************************************************/
static void init_local(void **state)
{
UNUSED(state);
struct circbuf_s cbuf;
uint8_t bbuf[CBUF_SIZE];
assert_int_equal(0, circbuf_init(&cbuf, bbuf, sizeof(bbuf)));
assert_true(circbuf_is_init(&cbuf));
assert_uint_equal(sizeof(bbuf), circbuf_size(&cbuf));
assert_uint_equal(0, circbuf_used(&cbuf));
assert_uint_equal(sizeof(bbuf), circbuf_space(&cbuf));
circbuf_uninit(&cbuf);
assert_false(circbuf_is_init(&cbuf));
}
/****************************************************************************
* Name: init_malloc
*
* Description:
* Tests that a circular buffer can be initialized using an internally
* malloc'd buffer and subsequently uninitialized.
****************************************************************************/
static void init_malloc(void **state)
{
UNUSED(state);
struct circbuf_s cbuf;
assert_int_equal(0, circbuf_init(&cbuf, NULL, 16));
assert_true(circbuf_is_init(&cbuf));
assert_uint_equal(16, circbuf_size(&cbuf));
assert_uint_equal(0, circbuf_used(&cbuf));
assert_uint_equal(16, circbuf_space(&cbuf));
circbuf_uninit(&cbuf);
assert_false(circbuf_is_init(&cbuf));
}
/****************************************************************************
* Name: empty_postinit
*
* Description:
* Tests that a circular buffer is empty right after being initialized.
****************************************************************************/
static void empty_postinit(void **state)
{
struct circbuf_s *cbuf = *state;
assert_true(circbuf_is_empty(cbuf));
assert_false(circbuf_is_full(cbuf));
assert_uint_equal(0, circbuf_used(cbuf));
assert_uint_equal(CBUF_SIZE, circbuf_space(cbuf));
}
/****************************************************************************
* Name: fail_peek_empty
*
* Description:
* Tests that circbuf_peek peeks zero bytes from an empty circbuf.
****************************************************************************/
static void fail_peek_empty(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf;
assert_int_equal(0, circbuf_peek(cbuf, &buf, sizeof(buf)));
}
/****************************************************************************
* Name: peekat_empty
*
* Description:
* Tests that circbuf_peekat peeks zero bytes from an empty circbuf.
****************************************************************************/
static void fail_peekat_empty(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf;
assert_int_equal(0, circbuf_peekat(cbuf, 0, &buf, sizeof(buf)));
}
/****************************************************************************
* Name: fail_read_empty
*
* Description:
* Tests that circbuf_read peeks zero bytes from an empty circbuf.
****************************************************************************/
static void fail_read_empty(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf;
assert_int_equal(0, circbuf_read(cbuf, &buf, sizeof(buf)));
}
/****************************************************************************
* Name: fail_skip_empty
*
* Description:
* Tests that circbuf_skip can only skip zero bytes from an empty circbuf.
****************************************************************************/
static void fail_skip_empty(void **state)
{
struct circbuf_s *cbuf = *state;
assert_int_equal(0, circbuf_skip(cbuf, 1));
assert_int_equal(0, circbuf_skip(cbuf, 10));
assert_int_equal(0, circbuf_skip(cbuf, CBUF_SIZE + 1));
}
/****************************************************************************
* Name: empty_equal_pointers
*
* Description:
* Tests that an empty circular buffer has the same value for the read and
* write pointer.
****************************************************************************/
static void empty_equal_pointers(void **state)
{
struct circbuf_s *cbuf = *state;
size_t sz;
void *rptr;
void *wptr;
rptr = circbuf_get_readptr(cbuf, &sz);
assert_non_null(rptr);
assert_uint_equal(0, sz);
wptr = circbuf_get_writeptr(cbuf, &sz);
assert_non_null(wptr);
assert_uint_equal(CBUF_SIZE, sz);
assert_ptr_equal(rptr, wptr);
}
/****************************************************************************
* Name: partial_init
*
* Description:
* Tests that a circbuf partially initialized with some data has the
* correct attributes.
****************************************************************************/
static void partial_init(void **state)
{
struct circbuf_s *cbuf = *state;
assert_true(circbuf_is_init(cbuf));
assert_false(circbuf_is_empty(cbuf));
assert_false(circbuf_is_full(cbuf));
assert_uint_equal(CBUF_SIZE, circbuf_size(cbuf));
assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf));
assert_uint_not_equal(0, circbuf_space(cbuf));
assert_uint_not_equal(0, circbuf_used(cbuf));
}
/****************************************************************************
* Name: partial_not_equal_pointers
*
* Description:
* Tests that a partially full circular buffer has different read and write
* pointers.
****************************************************************************/
static void partial_not_equal_pointers(void **state)
{
struct circbuf_s *cbuf = *state;
size_t sz;
void *rptr;
void *wptr;
rptr = circbuf_get_readptr(cbuf, &sz);
assert_non_null(rptr);
assert_uint_not_equal(0, sz);
wptr = circbuf_get_writeptr(cbuf, &sz);
assert_non_null(wptr);
assert_uint_not_equal(0, sz);
assert_ptr_not_equal(rptr, wptr);
}
/****************************************************************************
* Name: read_correct_contents
*
* Description:
* Tests that the contents read from the cbuf match the written contents.
****************************************************************************/
static void read_correct_contents(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_HALFSIZE];
assert_uint_equal(sizeof(buf), circbuf_read(cbuf, buf, sizeof(buf)));
assert_memory_equal(g_popbuf, buf, sizeof(buf));
assert_true(circbuf_is_empty(cbuf));
}
/****************************************************************************
* Name: peek_correct_contents
*
* Description:
* Tests that the contents peeked from the cbuf match the written contents.
****************************************************************************/
static void peek_correct_contents(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_HALFSIZE];
assert_uint_equal(sizeof(buf), circbuf_peek(cbuf, buf, sizeof(buf)));
assert_memory_equal(g_popbuf, buf, sizeof(buf));
assert_false(circbuf_is_empty(cbuf));
}
/****************************************************************************
* Name: peekat_correct_contents
*
* Description:
* Tests that the contents peeked from a position in the cbuf match the
* written contents.
****************************************************************************/
static void peekat_correct_contents(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_HALFSIZE];
assert_uint_equal(sizeof(buf), circbuf_peekat(cbuf, 0, buf, sizeof(buf)));
assert_memory_equal(g_popbuf, buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
assert_uint_equal(1, circbuf_peekat(cbuf, 0, buf, 1));
assert_uint_equal(0, buf[0]);
assert_uint_equal(1, circbuf_peekat(cbuf, 5, buf, 1));
assert_uint_equal(5, buf[0]);
assert_false(circbuf_is_empty(cbuf));
}
/****************************************************************************
* Name: skip_correct_contents
*
* Description:
* Tests that the contents read from a cbuf after skipping some data is
* correct.
****************************************************************************/
static void skip_correct_contents(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_HALFSIZE];
assert_uint_equal(3, circbuf_skip(cbuf, 3));
assert_uint_equal(CBUF_HALFSIZE - 3, circbuf_read(cbuf, buf, sizeof(buf)));
assert_memory_equal(g_popbuf + 3, buf, CBUF_HALFSIZE - 3);
assert_true(circbuf_is_empty(cbuf));
}
/****************************************************************************
* Name: write_within_bounds
*
* Description:
* Tests that the circular buffer behaves properly when more data is
* written but the size of the backing buffer is not exceeded.
****************************************************************************/
static void write_within_bounds(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_HALFSIZE + 2];
buf[0] = 8;
buf[1] = 9;
/* Write in the new contents */
assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf));
assert_uint_equal(2, circbuf_write(cbuf, buf, 2));
assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_used(cbuf));
/* Check correct contents */
assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_read(cbuf, buf, sizeof(buf)));
assert_memory_equal(g_popbuf, buf, CBUF_HALFSIZE);
assert_uint_equal(buf[8], 8);
assert_uint_equal(buf[9], 9);
}
/****************************************************************************
* Name: write_writeptr
*
* Description:
* Tests that the circular buffer behaves properly when more data is
* written to it using the write pointer and writecommit operation.
****************************************************************************/
static void write_writeptr(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_HALFSIZE + 2];
buf[0] = 8;
buf[1] = 9;
uint8_t *wptr;
size_t sz;
wptr = circbuf_get_writeptr(cbuf, &sz);
assert_non_null(wptr);
assert_true(sz >= 2);
/* Write in the new contents */
memcpy(wptr, buf, 2);
/* Check that the changes are not in effect */
assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf));
assert_uint_equal(CBUF_HALFSIZE, circbuf_space(cbuf));
/* Check that the changes are in effect after commit */
circbuf_writecommit(cbuf, 2);
assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_used(cbuf));
assert_uint_equal(CBUF_HALFSIZE - 2, circbuf_space(cbuf));
/* Check correct contents */
assert_uint_equal(CBUF_HALFSIZE + 2, circbuf_read(cbuf, buf, sizeof(buf)));
assert_memory_equal(g_popbuf, buf, CBUF_HALFSIZE);
assert_uint_equal(buf[8], 8);
assert_uint_equal(buf[9], 9);
}
/****************************************************************************
* Name: write_out_of_bounds
*
* Description:
* Tests that the circular buffer behaves properly when more data is
* written but the written data exceeds the backing buffer size.
****************************************************************************/
static void write_out_of_bounds(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_SIZE];
/* Write in the new contents */
assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf));
assert_uint_equal(CBUF_HALFSIZE,
circbuf_write(cbuf, g_popbuf, sizeof(g_popbuf)));
assert_uint_equal(CBUF_SIZE, circbuf_used(cbuf));
/* Check correct contents */
assert_uint_equal(CBUF_SIZE, circbuf_read(cbuf, buf, sizeof(buf)));
assert_memory_equal(g_popbuf, buf, CBUF_HALFSIZE);
assert_memory_equal(g_popbuf, buf + CBUF_HALFSIZE, CBUF_HALFSIZE);
}
/****************************************************************************
* Name: overwrite_out_of_bounds
*
* Description:
* Tests that the circular buffer behaves properly when more data is
* written but the written data exceeds the backing buffer size and must
* overwrite.
****************************************************************************/
static void overwrite_out_of_bounds(void **state)
{
struct circbuf_s *cbuf = *state;
uint8_t buf[CBUF_SIZE];
/* Write in the new contents */
assert_uint_equal(CBUF_HALFSIZE, circbuf_used(cbuf));
assert_uint_equal(CBUF_SIZE,
circbuf_overwrite(cbuf, g_popbuf, sizeof(g_popbuf)));
assert_uint_equal(CBUF_SIZE, circbuf_used(cbuf));
/* Check correct contents */
assert_uint_equal(CBUF_SIZE, circbuf_read(cbuf, buf, sizeof(buf)));
assert_memory_equal(buf, g_popbuf + CBUF_HALFSIZE, CBUF_HALFSIZE);
assert_memory_equal(buf + CBUF_HALFSIZE, g_popbuf, CBUF_HALFSIZE);
}
/****************************************************************************
* Name: reset_partial
*
* Description:
* Tests that when the partially filled circular buffer is reset, it
* behaves like a freshly initialized, empty circular buffer.
****************************************************************************/
static void reset_partial(void **state)
{
struct circbuf_s *cbuf = *state;
assert_false(circbuf_is_empty(cbuf));
assert_false(circbuf_is_full(cbuf));
assert_uint_not_equal(0, circbuf_used(cbuf));
assert_uint_not_equal(0, circbuf_space(cbuf));
circbuf_reset(cbuf);
assert_true(circbuf_is_empty(cbuf));
assert_false(circbuf_is_full(cbuf));
assert_uint_equal(0, circbuf_used(cbuf));
assert_uint_equal(CBUF_SIZE, circbuf_space(cbuf));
}
/****************************************************************************
* Name: full_init
*
* Description:
* Tests that the full circular buffer has the correct attributes after
* initialization.
****************************************************************************/
static void full_init(void **state)
{
struct circbuf_s *cbuf = *state;
assert_false(circbuf_is_empty(cbuf));
assert_true(circbuf_is_full(cbuf));
assert_uint_equal(circbuf_size(cbuf), circbuf_used(cbuf));
assert_uint_equal(0, circbuf_space(cbuf));
}
/****************************************************************************
* Name: full_readptr
*
* Description:
* Tests that reading from the full circular buffer with a read pointer
* works as expected, and that the read commit operation behaves correctly.
****************************************************************************/
static void full_readptr(void **state)
{
struct circbuf_s *cbuf = *state;
size_t sz;
uint8_t *rptr;
rptr = circbuf_get_readptr(cbuf, &sz);
assert_non_null(rptr);
assert_uint_equal(CBUF_SIZE, sz);
/* Verify contents */
assert_memory_equal(g_popbuf, rptr, sizeof(g_popbuf));
/* No changes to state before commit */
assert_true(circbuf_is_full(cbuf));
assert_false(circbuf_is_empty(cbuf));
assert_uint_equal(0, circbuf_space(cbuf));
assert_uint_equal(CBUF_SIZE, circbuf_used(cbuf));
circbuf_readcommit(cbuf, sz);
/* Proper attributes after read commit */
assert_false(circbuf_is_full(cbuf));
assert_true(circbuf_is_empty(cbuf));
assert_uint_equal(0, circbuf_used(cbuf));
assert_uint_equal(CBUF_SIZE, circbuf_space(cbuf));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_dstructs_cbuf
*
* Description:
* Runs the test cases for the circular buffer collection.
****************************************************************************/
int nuts_dstructs_cbuf(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(init_static),
cmocka_unit_test(init_local),
cmocka_unit_test(init_malloc),
cmocka_unit_test_setup_teardown(empty_postinit, setup_empty_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(fail_peek_empty, setup_empty_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(fail_peekat_empty, setup_empty_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(fail_read_empty, setup_empty_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(fail_skip_empty, setup_empty_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(empty_equal_pointers, setup_empty_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(partial_init, setup_partial_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(partial_not_equal_pointers,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(read_correct_contents,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(peek_correct_contents,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(peekat_correct_contents,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(skip_correct_contents,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(write_within_bounds,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(write_writeptr, setup_partial_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(write_out_of_bounds,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(overwrite_out_of_bounds,
setup_partial_cbuf, teardown_cbuf),
cmocka_unit_test_setup_teardown(reset_partial, setup_partial_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(full_init, setup_full_cbuf,
teardown_cbuf),
cmocka_unit_test_setup_teardown(full_readptr, setup_full_cbuf,
teardown_cbuf),
};
return cmocka_run_group_tests_name("circbuf_s", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_CBUF */

View file

@ -0,0 +1,149 @@
/****************************************************************************
* apps/testing/nuts/dstructs/list.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/list.h>
#include "tests.h"
#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_LIST
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: empty_after_init
*
* Description:
* Tests that a newly initialized list is considered empty.
****************************************************************************/
static void empty_after_init(void **state)
{
UNUSED(state);
struct list_node list;
list_initialize(&list);
assert_true(list_is_empty(&list));
}
/****************************************************************************
* Name: zerolen_after_init
*
* Description:
* Tests that a newly initialized list has zero length.
****************************************************************************/
static void zerolen_after_init(void **state)
{
UNUSED(state);
struct list_node list;
list_initialize(&list);
assert_uint_equal(0, list_length(&list));
}
/****************************************************************************
* Name: notail_after_init
*
* Description:
* Tests that a newly initialized list has no tail.
****************************************************************************/
static void notail_after_init(void **state)
{
UNUSED(state);
struct list_node list;
list_initialize(&list);
assert_null(list_remove_tail(&list));
}
/****************************************************************************
* Name: nohead_after_init
*
* Description:
* Tests that a newly initialized list has no head.
****************************************************************************/
static void nohead_after_init(void **state)
{
UNUSED(state);
struct list_node list;
list_initialize(&list);
assert_null(list_remove_head(&list));
}
/****************************************************************************
* Name: static_null_init
*
* Description:
* Tests that a list statically initialized with
* `LIST_INITIAL_CLEARED_VALUE` has NULL next and previous nodes.
****************************************************************************/
static void static_null_init(void **state)
{
UNUSED(state);
struct list_node list = LIST_INITIAL_CLEARED_VALUE;
assert_null(list.next);
assert_null(list.prev);
assert_null(list_peek_head(&list));
assert_null(list_peek_tail(&list));
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nuts_dstructs_list
*
* Description:
* Runs the test cases for the list collection.
****************************************************************************/
int nuts_dstructs_list(void)
{
static const struct CMUnitTest tests[] = {
cmocka_unit_test(empty_after_init),
cmocka_unit_test(zerolen_after_init),
cmocka_unit_test(notail_after_init),
cmocka_unit_test(nohead_after_init),
cmocka_unit_test(static_null_init),
};
return cmocka_run_group_tests_name("list_node", tests, NULL, NULL);
}
#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_LIST */

View file

@ -0,0 +1,54 @@
/****************************************************************************
* apps/testing/nuts/dstructs/tests.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_TESTING_NUTS_DSTRUCTS_H
#define __APPS_TESTING_NUTS_DSTRUCTS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "../nuts.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_LIST
int nuts_dstructs_list(void);
#else
#define nuts_dstructs_list()
#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_LIST */
#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_CBUF
int nuts_dstructs_cbuf(void);
#else
#define nuts_dstructs_cbuf()
#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_CBUF */
#ifdef CONFIG_TESTING_NUTS_DSTRUCTS_HMAP
int nuts_dstructs_hmap(void);
#else
#define nuts_dstructs_hmap()
#endif /* CONFIG_TESTING_NUTS_DSTRUCTS_HMAP */
#endif /* __APPS_TESTING_NUTS_DSTRUCTS_H */

47
testing/nuts/nuts.h Normal file
View file

@ -0,0 +1,47 @@
/****************************************************************************
* apps/testing/nuts/nuts.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_TESTING_NUTS_NUTS_H
#define __APPS_TESTING_NUTS_NUTS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/* These includes are required to be included before the cmocka header as per
* cmockha.h comment on line 41.
*/
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <cmocka.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#endif /* __APPS_TESTING_NUTS_NUTS_H */

73
testing/nuts/nuts_main.c Normal file
View file

@ -0,0 +1,73 @@
/****************************************************************************
* apps/testing/nuts/nuts_main.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include "nuts.h"
#include "tests.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* nuts_main
****************************************************************************/
int main(int argc, FAR char **argv)
{
UNUSED(argc);
UNUSED(argv);
/* Collections */
nuts_dstructs_cbuf();
nuts_dstructs_list();
/* Devices */
nuts_devices_devascii();
nuts_devices_devconsole();
nuts_devices_devnull();
nuts_devices_devurandom();
nuts_devices_devzero();
return 0;
}

33
testing/nuts/tests.h Normal file
View file

@ -0,0 +1,33 @@
/****************************************************************************
* apps/testing/nuts/tests.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_TESTING_NUTS_TESTS_H
#define __APPS_TESTING_NUTS_TESTS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "dstructs/tests.h"
#include "devices/tests.h"
#endif /* __APPS_TESTING_NUTS_TESTS_H */