Skip to content

Commit

Permalink
libc: add ioctl test
Browse files Browse the repository at this point in the history
JIRA: CI-237
  • Loading branch information
adamdebek committed Apr 12, 2023
1 parent 549e819 commit 0b9582e
Show file tree
Hide file tree
Showing 3 changed files with 287 additions and 0 deletions.
7 changes: 7 additions & 0 deletions ioctl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
NAME := test-ioctl
LOCAL_SRCS := test_ioctl.c
DEP_LIBS := unity

LOCAL_LDFLAGS += -z stack-size=12288

include $(binary.mk)
7 changes: 7 additions & 0 deletions ioctl/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
test:
type: unity
tests:
- name: unit
execute: test-ioctl
targets:
exclude: [armv7m7-imxrt106x-evk, armv7m7-imxrt117x-evk, armv7m4-stm32l4x6-nucleo]
273 changes: 273 additions & 0 deletions ioctl/test_ioctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
/*
* Phoenix-RTOS
*
* Phoenix-RTOS standard library functions tests
* HEADER:
* - ioctl.h
* TESTED:
* - ioctl()
*
* Copyright 2023 Phoenix Systems
* Author: Adam Debek
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <phoenix/ioctl.h>
#include <sys/msg.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <posix/utils.h>
#include <unity_fixture.h>


uint32_t port;
pid_t pid = -1;
int ret, dd, fd;

#define FILENAME "tmpFile"
/* In above T stands for test, do not confuse with tty */
#define TIOCSIG _IOC(0, 'T', 0x01, 0)
#define TIOCVAL _IOC(0, 'T', 0x02, 4)
#define TIOCPTR _IOC(IOC_IN, 'T', 0x03, 4)
#define TIOCPTR2 _IOC(IOC_IN, 'T', 0x04, 64)
#define TIOCOUT _IOC(IOC_OUT, 'T', 0x05, 4)
#define TIOCOUT2 _IOC(IOC_OUT, 'T', 0x06, 64)

static void thread(void)
{
msg_t msg;
unsigned long int rid;
int32_t out = 15;
int8_t out2[64] = { [0 ... 63] = 5 };
int flag = 1;

while (1) {
if (msgRecv(port, &msg, &rid) < 0) {
continue;
}

if (msg.type == mtDevCtl) {
unsigned long request;
int err = 0;
const void *out_data = NULL;
const void *in_data = ioctl_unpack(&msg, &request, NULL);
switch (request) {
case TIOCVAL:
lseek(fd, 0, SEEK_SET);
write(fd, &in_data, 4);
break;
case TIOCSIG:
lseek(fd, 0, SEEK_SET);
write(fd, &flag, 4);
break;
case TIOCPTR:
lseek(fd, 0, SEEK_SET);
write(fd, in_data, 4);
break;
case TIOCPTR2:
lseek(fd, 0, SEEK_SET);
write(fd, in_data, 64);
break;
case TIOCOUT:
out_data = (const void *)(&out);
break;
case TIOCOUT2:
out_data = (const void *)(out2);
break;
}
ioctl_setResponse(&msg, request, err, out_data);
}
msgRespond(port, &msg, rid);
}
return;
}


static void init(void)
{
char devpath[5] = "test";
oid_t dev;

TEST_ASSERT_EQUAL_INT(EOK, portCreate(&port));

dev.port = port;
dev.id = 0;

TEST_ASSERT_EQUAL_INT(EOK, create_dev(&dev, devpath));

return;
}


TEST_GROUP(ioctl);


TEST_SETUP(ioctl)
{
}

TEST_TEAR_DOWN(ioctl)
{
}


TEST(ioctl, no_data)
{
int flag;
/* Send data to driver by value */
while ((ret = ioctl(dd, TIOCSIG, NULL)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_INT(0, ret);
lseek(fd, 0, SEEK_SET);
read(fd, &flag, 4);
TEST_ASSERT_EQUAL_INT32(1, flag);
}


TEST(ioctl, in_val)
{
int32_t data = 14;
int32_t rdata;

/* Send data to driver by value */
while ((ret = ioctl(dd, TIOCVAL, data)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_INT(0, ret);
lseek(fd, 0, SEEK_SET);
read(fd, &rdata, 4);
TEST_ASSERT_EQUAL_INT32(14, rdata);
}


TEST(ioctl, in)
{
int32_t data_in = 20;
int32_t rdata;

/* Send data to driver by pointer */
while ((ret = ioctl(dd, TIOCPTR, &data_in)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_INT(0, ret);
lseek(fd, 0, SEEK_SET);
read(fd, &rdata, 4);
TEST_ASSERT_EQUAL_INT32(20, rdata);
}


TEST(ioctl, in_64)
{
int8_t data_in[64] = { [0 ... 63] = 3 };
int8_t rdata[64];

/* Send data to driver by pointer , data big enough to not be copied by ioctl_pack directly into message */
while ((ret = ioctl(dd, TIOCPTR2, data_in)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_INT(0, ret);
lseek(fd, 0, SEEK_SET);
read(fd, rdata, 64);
TEST_ASSERT_EQUAL_MEMORY(data_in, rdata, 64);
}


TEST(ioctl, out)
{
int32_t data_out;

/* Get data from driver */
while ((ret = ioctl(dd, TIOCOUT, &data_out)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_INT32(15, data_out);
}


TEST(ioctl, out_64)
{
int8_t data_expected[64] = { [0 ... 63] = 5 };
int8_t data_out[64];

/* Get data from driver */
while ((ret = ioctl(dd, TIOCOUT2, data_out)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_MEMORY(data_expected, data_out, 64);
}


TEST(ioctl, no_device)
{
errno = 0;
int ret = ioctl(123, 0, NULL);
TEST_ASSERT_EQUAL_INT(-1, ret);
TEST_ASSERT_EQUAL_INT(EBADF, errno);
}


TEST_GROUP_RUNNER(ioctl)
{
fd = open(FILENAME, O_RDWR | O_CREAT, 0666);

pid = fork();
if (pid < 0) {
TEST_ASSERT_GREATER_THAN_INT(0, pid);
}
else if (pid == 0) {
/* child - create device server */
init();
thread();
}
while ((dd = open("/dev/test", O_RDWR)) < 0) {
usleep(10000);
}
if (pid > 0) {
/* parent - run test cases */
RUN_TEST_CASE(ioctl, no_device);
RUN_TEST_CASE(ioctl, no_data);
RUN_TEST_CASE(ioctl, in_val);
RUN_TEST_CASE(ioctl, in);
RUN_TEST_CASE(ioctl, in_64);
RUN_TEST_CASE(ioctl, out);
RUN_TEST_CASE(ioctl, out_64);
/* device driver server (child process) no longer needed */
close(fd);
remove(FILENAME);
close(dd);
kill(pid, SIGKILL);

ret = ioctl(dd, 0, NULL);
TEST_ASSERT_EQUAL_INT(-1, ret);
}
}


void runner(void)
{
RUN_TEST_GROUP(ioctl);
}


int main(int argc, char *argv[])
{
UnityMain(argc, (const char **)argv, runner);
return 0;
}

0 comments on commit 0b9582e

Please sign in to comment.