[v5,3/4] test: restore cfgfile tests

Message ID 20240802164626.389286-4-stephen@networkplumber.org (mailing list archive)
State Superseded
Delegated to: Thomas Monjalon
Headers
Series restore unused cfgfile tests |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Stephen Hemminger Aug. 2, 2024, 4:45 p.m. UTC
These tests were not built since the conversion to meson.
Instead of using embedded resource functions, put data in include
file and generate temporary file before the test.

The changes to app/test/meson.build are to handle auto-generated
files (resources) differently. Don't scan these files to look
for test input.

Using common unit test macro allows for simpler management
of more tests.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/meson.build                    |   3 +-
 app/test/meson.build               |   6 +-
 app/test/test_cfgfile.c            | 213 ++++++++++++++++++-----------
 app/test/test_cfgfiles/meson.build |  19 +++
 4 files changed, 157 insertions(+), 84 deletions(-)
 create mode 100644 app/test/test_cfgfiles/meson.build
  

Comments

Bruce Richardson Aug. 2, 2024, 4:52 p.m. UTC | #1
On Fri, Aug 02, 2024 at 09:45:02AM -0700, Stephen Hemminger wrote:
> These tests were not built since the conversion to meson.
> Instead of using embedded resource functions, put data in include
> file and generate temporary file before the test.
> 
> The changes to app/test/meson.build are to handle auto-generated
> files (resources) differently. Don't scan these files to look
> for test input.
> 
> Using common unit test macro allows for simpler management
> of more tests.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>


Acked-by: Bruce Richardson <bruce.richardson@intel.com>
  

Patch

diff --git a/app/meson.build b/app/meson.build
index 5b2c80c7a1..e2db888ae1 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -55,6 +55,7 @@  foreach app:apps
     build = true
     reason = '<unknown reason>' # set if build == false to explain
     sources = []
+    resources = []
     includes = []
     cflags = default_cflags
     ldflags = default_ldflags
@@ -115,7 +116,7 @@  foreach app:apps
     endif
 
     exec = executable('dpdk-' + name,
-            sources,
+            [ sources, resources ],
             c_args: cflags,
             link_args: ldflags,
             link_whole: link_libs,
diff --git a/app/test/meson.build b/app/test/meson.build
index 62478c0bb6..b2bb7c36f6 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -35,7 +35,7 @@  source_file_deps = {
     'test_bitratestats.c': ['metrics', 'bitratestats', 'ethdev'] + sample_packet_forward_deps,
     'test_bpf.c': ['bpf', 'net'],
     'test_byteorder.c': [],
-#    'test_cfgfile.c': ['cfgfile'],
+    'test_cfgfile.c': ['cfgfile'],
     'test_cksum.c': ['net'],
     'test_cksum_perf.c': ['net'],
     'test_cmdline.c': [],
@@ -261,3 +261,7 @@  if not is_windows
             build_by_default: true,
             install: false)
 endif
+
+subdir('test_cfgfiles')
+
+resources += test_cfgfile_h
diff --git a/app/test/test_cfgfile.c b/app/test/test_cfgfile.c
index a5e3d8699c..8146435033 100644
--- a/app/test/test_cfgfile.c
+++ b/app/test/test_cfgfile.c
@@ -5,48 +5,54 @@ 
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
-#include <sys/queue.h>
+#include <unistd.h>
+
+#ifdef RTE_EXEC_ENV_WINDOWS
+#include <io.h>
+#endif
 
 #include <rte_cfgfile.h>
 
 #include "test.h"
-#include "resource.h"
-
 
-#define CFG_FILES_ETC "test_cfgfiles/etc"
-
-REGISTER_LINKED_RESOURCE(test_cfgfiles);
+#include "test_cfgfiles.h"
 
 static int
-test_cfgfile_setup(void)
+make_tmp_file(char *filename, const char *prefix, const char *data)
 {
-	const struct resource *r;
-	int ret;
+	size_t len = strlen(data);
+	size_t count;
+	FILE *f;
 
-	r = resource_find("test_cfgfiles");
-	TEST_ASSERT_NOT_NULL(r, "missing resource test_cfgfiles");
+#ifdef RTE_EXEC_ENV_WINDOWS
+	char tempDirName[MAX_PATH - 14];
 
-	ret = resource_untar(r);
-	TEST_ASSERT_SUCCESS(ret, "failed to untar %s", r->name);
+	if (GetTempPathA(sizeof(tempDirName), tempDirName) == 0)
+		return -1;
 
-	return 0;
-}
+	if (GetTempFileNameA(tempDirName, prefix, 0, filename) == 0)
+		return -1;
 
-static int
-test_cfgfile_cleanup(void)
-{
-	const struct resource *r;
-	int ret;
+	f = fopen(filename, "wt");
+#else
+	snprintf(filename, PATH_MAX, "/tmp/%s_XXXXXXX", prefix);
 
-	r = resource_find("test_cfgfiles");
-	TEST_ASSERT_NOT_NULL(r, "missing resource test_cfgfiles");
+	int fd = mkstemp(filename);
+	if (fd < 0)
+		return -1;
 
-	ret = resource_rm_by_tar(r);
-	TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name);
+	f = fdopen(fd, "w");
+#endif
+	if (f == NULL)
+		return -1;
 
-	return 0;
+	count = fwrite(data, sizeof(char), len, f);
+	fclose(f);
+
+	return (count == len) ? 0 : -1;
 }
 
+
 static int
 _test_cfgfile_sample(struct rte_cfgfile *cfgfile)
 {
@@ -87,9 +93,13 @@  static int
 test_cfgfile_sample1(void)
 {
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
 	int ret;
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/sample1.ini", 0);
+	ret = make_tmp_file(filename, "sample1", sample1_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load(filename, 0);
 	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
 
 	ret = _test_cfgfile_sample(cfgfile);
@@ -98,6 +108,8 @@  test_cfgfile_sample1(void)
 	ret = rte_cfgfile_close(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
 
+	remove(filename);
+
 	return 0;
 }
 
@@ -106,15 +118,18 @@  test_cfgfile_sample2(void)
 {
 	struct rte_cfgfile_parameters params;
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
 	int ret;
 
+	ret = make_tmp_file(filename, "sample2", sample2_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
 	/* override comment character */
 	memset(&params, 0, sizeof(params));
 	params.comment_character = '#';
 
-	cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0,
-					       &params);
-	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2.ini");
+	cfgfile = rte_cfgfile_load_with_params(filename, 0, &params);
+	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2");
 
 	ret = _test_cfgfile_sample(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret);
@@ -122,6 +137,8 @@  test_cfgfile_sample2(void)
 	ret = rte_cfgfile_close(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
 
+	remove(filename);
+
 	return 0;
 }
 
@@ -129,10 +146,14 @@  static int
 test_cfgfile_realloc_sections(void)
 {
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
 	int ret;
 	const char *value;
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/realloc_sections.ini", 0);
+	ret = make_tmp_file(filename, "realloc", realloc_sections_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load(filename, 0);
 	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
 
 	ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
@@ -152,9 +173,18 @@  test_cfgfile_realloc_sections(void)
 	TEST_ASSERT(strcmp("value8_section9", value) == 0,
 		    "key unexpected value: %s", value);
 
-	ret = rte_cfgfile_save(cfgfile, "/tmp/cfgfile_save.ini");
-	TEST_ASSERT_SUCCESS(ret, "Failed to save *.ini file");
-	remove("/tmp/cfgfile_save.ini");
+	remove(filename);
+
+	char tmp[PATH_MAX] = "/tmp/";
+#ifdef RTE_EXEC_ENV_WINDOWS
+	ret = GetTempPathA(sizeof(tmp), tmp);
+	TEST_ASSERT(ret > 0, "Failed to get tmp directory");
+#endif
+	snprintf(filename, sizeof(filename), "%s%s", tmp, "cfg_save.ini");
+
+	ret = rte_cfgfile_save(cfgfile, filename);
+	TEST_ASSERT_SUCCESS(ret, "Failed to save to %s", filename);
+	remove(filename);
 
 	ret = rte_cfgfile_close(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
@@ -166,10 +196,16 @@  static int
 test_cfgfile_invalid_section_header(void)
 {
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
+	int ret;
+
+	ret = make_tmp_file(filename, "invalid", invalid_section_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/invalid_section.ini", 0);
+	cfgfile = rte_cfgfile_load(filename, 0);
 	TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
 
+	remove(filename);
 	return 0;
 }
 
@@ -178,15 +214,20 @@  test_cfgfile_invalid_comment(void)
 {
 	struct rte_cfgfile_parameters params;
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
+	int ret;
 
 	/* override comment character with an invalid one */
 	memset(&params, 0, sizeof(params));
 	params.comment_character = '$';
 
-	cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0,
-					       &params);
+	ret = make_tmp_file(filename, "sample2", sample2_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load_with_params(filename, 0, &params);
 	TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
 
+	remove(filename);
 	return 0;
 }
 
@@ -194,10 +235,16 @@  static int
 test_cfgfile_invalid_key_value_pair(void)
 {
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
+	int ret;
+
+	ret = make_tmp_file(filename, "empty_key", empty_key_value_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty_key_value.ini", 0);
+	cfgfile = rte_cfgfile_load(filename, 0);
 	TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
 
+	remove(filename);
 	return 0;
 }
 
@@ -206,11 +253,14 @@  test_cfgfile_empty_key_value_pair(void)
 {
 	struct rte_cfgfile *cfgfile;
 	const char *value;
+	char filename[PATH_MAX];
 	int ret;
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty_key_value.ini",
-				   CFG_FLAG_EMPTY_VALUES);
-	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse empty_key_value.ini");
+	ret = make_tmp_file(filename, "empty_key_value", empty_key_value_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load(filename, CFG_FLAG_EMPTY_VALUES);
+	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse empty_key_value");
 
 	ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
 	TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret);
@@ -227,6 +277,7 @@  test_cfgfile_empty_key_value_pair(void)
 	ret = rte_cfgfile_close(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
 
+	remove(filename);
 	return 0;
 }
 
@@ -234,10 +285,16 @@  static int
 test_cfgfile_missing_section(void)
 {
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
+	int ret;
+
+	ret = make_tmp_file(filename, "missing_section", missing_section_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/missing_section.ini", 0);
+	cfgfile = rte_cfgfile_load(filename, 0);
 	TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
 
+	remove(filename);
 	return 0;
 }
 
@@ -246,10 +303,13 @@  test_cfgfile_global_properties(void)
 {
 	struct rte_cfgfile *cfgfile;
 	const char *value;
+	char filename[PATH_MAX];
 	int ret;
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/missing_section.ini",
-				   CFG_FLAG_GLOBAL_SECTION);
+	ret = make_tmp_file(filename, "missing_section", missing_section_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load(filename, CFG_FLAG_GLOBAL_SECTION);
 	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
 
 	ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
@@ -268,6 +328,7 @@  test_cfgfile_global_properties(void)
 	ret = rte_cfgfile_close(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
 
+	remove(filename);
 	return 0;
 }
 
@@ -275,9 +336,13 @@  static int
 test_cfgfile_empty_file(void)
 {
 	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
 	int ret;
 
-	cfgfile = rte_cfgfile_load(CFG_FILES_ETC "/empty.ini", 0);
+	ret = make_tmp_file(filename, "empty", empty_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load(filename, 0);
 	TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
 
 	ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
@@ -286,49 +351,33 @@  test_cfgfile_empty_file(void)
 	ret = rte_cfgfile_close(cfgfile);
 	TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
 
+	remove(filename);
 	return 0;
 }
 
+static struct
+unit_test_suite test_cfgfile_suite  = {
+	.suite_name = "Test Cfgfile Unit Test Suite",
+	.unit_test_cases = {
+		TEST_CASE(test_cfgfile_sample1),
+		TEST_CASE(test_cfgfile_sample2),
+		TEST_CASE(test_cfgfile_realloc_sections),
+		TEST_CASE(test_cfgfile_invalid_section_header),
+		TEST_CASE(test_cfgfile_invalid_comment),
+		TEST_CASE(test_cfgfile_invalid_key_value_pair),
+		TEST_CASE(test_cfgfile_empty_key_value_pair),
+		TEST_CASE(test_cfgfile_missing_section),
+		TEST_CASE(test_cfgfile_global_properties),
+		TEST_CASE(test_cfgfile_empty_file),
+
+		TEST_CASES_END()
+	}
+};
+
 static int
 test_cfgfile(void)
 {
-	if (test_cfgfile_setup())
-		return -1;
-
-	if (test_cfgfile_sample1())
-		return -1;
-
-	if (test_cfgfile_sample2())
-		return -1;
-
-	if (test_cfgfile_realloc_sections())
-		return -1;
-
-	if (test_cfgfile_invalid_section_header())
-		return -1;
-
-	if (test_cfgfile_invalid_comment())
-		return -1;
-
-	if (test_cfgfile_invalid_key_value_pair())
-		return -1;
-
-	if (test_cfgfile_empty_key_value_pair())
-		return -1;
-
-	if (test_cfgfile_missing_section())
-		return -1;
-
-	if (test_cfgfile_global_properties())
-		return -1;
-
-	if (test_cfgfile_empty_file())
-		return -1;
-
-	if (test_cfgfile_cleanup())
-		return -1;
-
-	return 0;
+	return unit_test_suite_runner(&test_cfgfile_suite);
 }
 
-REGISTER_TEST_COMMAND(cfgfile_autotest, test_cfgfile);
+REGISTER_FAST_TEST(cfgfile_autotest, true, true, test_cfgfile);
diff --git a/app/test/test_cfgfiles/meson.build b/app/test/test_cfgfiles/meson.build
new file mode 100644
index 0000000000..068b61044a
--- /dev/null
+++ b/app/test/test_cfgfiles/meson.build
@@ -0,0 +1,19 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+
+test_cfgfiles = files(
+    'etc/empty.ini',
+    'etc/empty_key_value.ini',
+    'etc/invalid_section.ini',
+    'etc/line_too_long.ini',
+    'etc/missing_section.ini',
+    'etc/realloc_sections.ini',
+    'etc/sample1.ini',
+    'etc/sample2.ini',
+)
+
+# generate the header file used in cfgfile test
+test_cfgfile_h = custom_target('test_cfgfile',
+                          output: 'test_cfgfiles.h',
+                          input: test_cfgfiles,
+                          capture: true,
+                          command: [ header_gen_cmd, '@INPUT@'])