From d3508b6acd5a68bee4e0af4bc7b9591f7656bbe3 Mon Sep 17 00:00:00 2001 From: Michal Lenc Date: Mon, 23 Oct 2023 15:49:42 +0200 Subject: [PATCH] testing: add fmemopen function test tool Test tool application for fmemopen for CI testing. Performs basic read/write/seek/append operations. Signed-off-by: Michal Lenc --- testing/fmemopen/Kconfig | 13 ++ testing/fmemopen/Make.defs | 23 +++ testing/fmemopen/Makefile | 32 ++++ testing/fmemopen/fmemopen.c | 343 ++++++++++++++++++++++++++++++++++++ 4 files changed, 411 insertions(+) create mode 100644 testing/fmemopen/Kconfig create mode 100644 testing/fmemopen/Make.defs create mode 100644 testing/fmemopen/Makefile create mode 100644 testing/fmemopen/fmemopen.c diff --git a/testing/fmemopen/Kconfig b/testing/fmemopen/Kconfig new file mode 100644 index 000000000..1c17ffea2 --- /dev/null +++ b/testing/fmemopen/Kconfig @@ -0,0 +1,13 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config TESTING_FMEMOPEN_TEST + tristate "Fmemopen test tool" + default n + ---help--- + Performs a basic operations with fmemopen call. + +if TESTING_FMEMOPEN_TEST +endif diff --git a/testing/fmemopen/Make.defs b/testing/fmemopen/Make.defs new file mode 100644 index 000000000..03c3981fe --- /dev/null +++ b/testing/fmemopen/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/testing/fmemopen/Make.defs +# +# 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_FMEMOPEN_TEST),) +CONFIGURED_APPS += $(APPDIR)/testing/fmemopen +endif diff --git a/testing/fmemopen/Makefile b/testing/fmemopen/Makefile new file mode 100644 index 000000000..4b712aef1 --- /dev/null +++ b/testing/fmemopen/Makefile @@ -0,0 +1,32 @@ +############################################################################ +# apps/testing/fmemopen/Makefile +# +# 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 + +# SMART filesystem test tool + +PROGNAME = fmemopen_test +PRIORITY = SCHED_PRIORITY_DEFAULT +STACKSIZE = 4096 +MODULE = $(CONFIG_TESTING_FMEMOPEN_TEST) + +MAINSRC = fmemopen.c + +include $(APPDIR)/Application.mk diff --git a/testing/fmemopen/fmemopen.c b/testing/fmemopen/fmemopen.c new file mode 100644 index 000000000..909fa6b50 --- /dev/null +++ b/testing/fmemopen/fmemopen.c @@ -0,0 +1,343 @@ +/**************************************************************************** + * apps/testing/fmemopen/fmemopen.c + * + * 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 + +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private data + ****************************************************************************/ + +static char correctbuf[53] = "abcdefghijklmnopqrstuvwxyz"; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fmemopen_read_test + ****************************************************************************/ + +static int fmemopen_read_test(void) +{ + FILE *stream; + ssize_t size; + char buf[256]; + int n; + + size = strlen(correctbuf); + + /* Open for read only */ + + stream = fmemopen(correctbuf, size, "r"); + if (stream == NULL) + { + return -1; + } + + /* Read buffer and check whether characters match. */ + + n = fread(buf, 1, size, stream); + for (int i = 0; i < n; i++) + { + if (correctbuf[i] != buf[i]) + { + printf("fmemopen_read_test: error %d got %c, expected %c\n", i, + buf[i], correctbuf[i]); + fclose(stream); + return -1; + } + } + + printf("fmemopen_read_test: read buffer: %.*s\n", n, buf); + + /* Try writing, this should fail */ + + n = fputs(correctbuf, stream); + if (n >= 0) + { + printf("fmemopen_read_test: error: fputs was successful but" \ + "write not permited!.\n"); + fclose(stream); + return -1; + } + + printf("fmemopen_read_test: successful\n"); + fclose(stream); + return 0; +} + +/**************************************************************************** + * Name: fmemopen_write_test + ****************************************************************************/ + +static int fmemopen_write_test(void) +{ + FILE *stream; + char buf[256]; + int n; + + /* Open for writing and reading. */ + + stream = fmemopen(NULL, 256, "w+"); + if (stream == NULL) + { + return -1; + } + + n = fputs(correctbuf, stream); + if (n < 0) + { + printf("fmemopen_write_test: fputs failed.\n"); + fclose(stream); + return -1; + } + + /* Seek to begining */ + + fseek(stream, 0, SEEK_SET); + + /* And read written buffer. */ + + n = fread(buf, 1, 256, stream); + for (int i = 0; i < n; i++) + { + if (correctbuf[i] != buf[i]) + { + printf("fmemopen_write_test: error %d got %c, expected %c\n", i, + buf[i], correctbuf[i]); + fclose(stream); + return -1; + } + } + + printf("fmemopen_write_test: read buffer: %.*s\n", n, buf); + printf("fmemopen_write_test: successful\n"); + fclose(stream); + return 0; +} + +/**************************************************************************** + * Name: fmemopen_seek_test + ****************************************************************************/ + +static int fmemopen_seek_test(void) +{ + FILE *stream; + ssize_t size; + char buf[1]; + int n; + + size = strlen(correctbuf); + + stream = fmemopen(correctbuf, size, "r"); + if (stream == NULL) + { + return -1; + } + + /* SEEK_END test */ + + n = fseek(stream, -1, SEEK_END); + if (n < 0) + { + printf("fmemopen_seek_test: error SEEK_END: %d\n", -errno); + fclose(stream); + return -1; + } + + n = fread(buf, 1, 1, stream); + if ((n != 1) || (correctbuf[size - 1] != buf[0])) + { + printf("fmemopen_seek_test: read at SEEK_END failed:" \ + "expected: %c, read %c\n", correctbuf[size - 1], buf[0]); + fclose(stream); + return -1; + } + + /* SEEK_SET test */ + + n = fseek(stream, 0, SEEK_SET); + if (n < 0) + { + printf("fmemopen_seek_test: error SEEK_SET: %d\n", -errno); + fclose(stream); + return -1; + } + + n = fread(buf, 1, 1, stream); + if ((n != 1) || (correctbuf[0] != buf[0])) + { + printf("fmemopen_seek_test: read at SEEK_SET failed:" \ + "expected: %c, read %c\n", correctbuf[0], buf[0]); + fclose(stream); + return -1; + } + + /* SEEK_CUR test. Note that current position is 1 because of previous + * read, therefore the check has to be correctbuf[10] != buf[0]. + */ + + n = fseek(stream, 9, SEEK_CUR); + if (n < 0) + { + printf("fmemopen_seek_test: error SEEK_CUR: %d\n", -errno); + fclose(stream); + return -1; + } + + n = fread(buf, 1, 1, stream); + if ((n != 1) || (correctbuf[10] != buf[0])) + { + printf("fmemopen_seek_test: read at SEEK_CUR failed:" \ + "expected: %c, read %c\n", correctbuf[10], buf[0]); + fclose(stream); + return -1; + } + + fclose(stream); + printf("fmemopen_seek_test: successful\n"); + return 0; +} + +/**************************************************************************** + * Name: fmemopen_seek_test + ****************************************************************************/ + +static int fmemopen_append_test(void) +{ + FILE *stream; + char buf[256]; + int n; + + /* Add termination to the half of the buffer. This is to ensure we + * can perform the test multiple times if required. + */ + + correctbuf[26] = '\0'; + + stream = fmemopen(correctbuf, 53, "a+"); + if (stream == NULL) + { + return -1; + } + + n = fputs(correctbuf, stream); + if (n < 0) + { + printf("fmemopen_append_test: fputs failed.\n"); + fclose(stream); + return -1; + } + + n = fseek(stream, 0, SEEK_SET); + + n = fread(buf, 1, 256, stream); + for (int i = 0; i < n; i++) + { + if (correctbuf[i % 26] != buf[i]) + { + printf("fmemopen_append_test: error %d got %c, expected %c\n", i, + buf[i], correctbuf[i]); + fclose(stream); + return -1; + } + } + + printf("fmemopen_append_test: read buffer: %.*s\n", n, buf); + printf("fmemopen_append_test: successful\n"); + fclose(stream); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + int ret; + int tests_ok; + int tests_err; + + tests_ok = tests_err = 0; + + /* Run tests. They should return 0 on success, -1 otherwise. */ + + ret = fmemopen_read_test(); + if (ret < 0) + { + tests_err += 1; + } + else + { + tests_ok += 1; + } + + ret = fmemopen_write_test(); + if (ret < 0) + { + tests_err += 1; + } + else + { + tests_ok += 1; + } + + ret = fmemopen_seek_test(); + if (ret < 0) + { + tests_err += 1; + } + else + { + tests_ok += 1; + } + + ret = fmemopen_append_test(); + if (ret < 0) + { + tests_err += 1; + } + else + { + tests_ok += 1; + } + + printf("fmemopen tests: SUCCESSFUL: %d; FAILED: %d\n", tests_ok, + tests_err); + + return 0; +}