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 6, 2023
1 parent 737dd9d commit 575a50e
Showing 1 changed file with 155 additions and 59 deletions.
214 changes: 155 additions & 59 deletions libc/test_ioctl.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
* Phoenix-RTOS
*
* POSIX.1-2017 standard library functions tests
* Phoenix-RTOS standard library functions tests
* HEADER:
* - stropts.h
* - ioctl.h
* TESTED:
* - ioctl()
*
Expand All @@ -30,38 +30,61 @@


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

int fd_pipe[2];
int32_t ret_pipe;
int8_t ret_pipe64[64];

/* 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 };
int8_t data[64] = { [0 ... 63] = 3 };
int32_t flag = 1;

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

switch (msg.type) {
case mtDevCtl: {
unsigned long request;
int err = 0;
const void *out_data = NULL;
const void *in_data = ioctl_unpack(&msg, &request, NULL);
if (request & IOC_INOUT) {
if (request & IOC_IN) {
TEST_ASSERT_EQUAL_INT(20, *((int32_t *)in_data));
}
else if (request & IOC_OUT) {
out_data = (const void *)(&out);
TEST_ASSERT_EQUAL_INT(15, *((int32_t *)(out_data)));
}
}
ioctl_setResponse(&msg, request, err, out_data);
} break;
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:
write(fd_pipe[1], &in_data, 4);
break;
case TIOCSIG:
write(fd_pipe[1], &flag, 4);
break;
case TIOCPTR:
write(fd_pipe[1], in_data, 4);
break;
case TIOCPTR2:
write(fd_pipe[1], in_data, 64);
close(fd_pipe[1]);
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);
}
Expand Down Expand Up @@ -90,66 +113,139 @@ TEST_GROUP(ioctl);

TEST_SETUP(ioctl)
{
TEST_ASSERT_EQUAL_INT(10, 20);
/*child_pid = fork();
if (child_pid < 0) {
TEST_ASSERT_GREATER_THAN_INT(0, child_pid);
}

TEST_TEAR_DOWN(ioctl)
{
}


TEST(ioctl, no_data)
{
/* Send data to driver by value */
while ((ret = ioctl(fd, TIOCSIG, NULL)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
else if (child_pid == 0) {*/
/* child */
/*init();
thread();
TEST_ASSERT_EQUAL_INT(10,20);
while ((fd = open("/dev/test", O_RDWR)) < 0) {
TEST_ASSERT_EQUAL_INT(0, ret);
read(fd_pipe[0], &ret_pipe, 4);
TEST_ASSERT_EQUAL_INT8(1, ret_pipe);
}


TEST(ioctl, in_val)
{
int32_t data = 14;
/* Send data to driver by value */
while ((ret = ioctl(fd, TIOCVAL, data)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_NOT_EQUAL_INT(-1, fd);
}*/
TEST_ASSERT_EQUAL_INT(0, ret);
read(fd_pipe[0], &ret_pipe, 4);
TEST_ASSERT_EQUAL_INT(14, ret_pipe);
}

TEST_TEAR_DOWN(ioctl)

TEST(ioctl, in)
{
/* device driver server (child process) no longer needed */
close(fd);
kill(child_pid, SIGKILL);
int32_t data_in = 20;

ret = ioctl(fd, 0, NULL);
TEST_ASSERT_EQUAL_INT(-1, ret);
/* Send data to driver by pointer */
while ((ret = ioctl(fd, TIOCPTR, &data_in)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_EQUAL_INT(0, ret);
read(fd_pipe[0], &ret_pipe, 4);
TEST_ASSERT_EQUAL_INT(20, ret_pipe);
}

TEST(ioctl, own_driver)

TEST(ioctl, in_64)
{
TEST_ASSERT_EQUAL_INT(10, 20);
if (child_pid > 0) {
/* parent */
errno = 0;
int32_t data_in = 20;
int32_t data_out;
/* Send data to driver */
while ((ret = ioctl(fd, _IOC(IOC_IN, 'T', 0x01, 4), &data_in)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
}
/* Get data from dirver */
while ((ret = ioctl(fd, _IOC(IOC_OUT, 'T', 0x02, 4), &data_out)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
}
TEST_ASSERT_EQUAL_INT(data_out, 15);
int8_t data_in[64] = { [0 ... 63] = 3 };

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


TEST(ioctl, out)
{
int32_t data_out;

/* Get data from dirver */
while ((ret = ioctl(fd, TIOCOUT, &data_out)) < 0) {
TEST_ASSERT_EQUAL_INT(-1, ret);
usleep(10000);
}
TEST_ASSERT_NOT_NULL(data_out);
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 dirver */
while ((ret = ioctl(fd, 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)
{
TEST_ASSERT_EQUAL_INT(10, 20);
errno = 0;
int ret = ioctl(123, 0, NULL);
TEST_ASSERT_EQUAL_INT(-1, ret);
TEST_ASSERT_EQUAL_INT(0, errno);
TEST_ASSERT_EQUAL_INT(EBADF, errno);
}


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

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

0 comments on commit 575a50e

Please sign in to comment.