From patchwork Tue Aug 13 15:57:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 143117 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0B1A5457B3; Tue, 13 Aug 2024 18:01:24 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8D22140E64; Tue, 13 Aug 2024 18:00:58 +0200 (CEST) Received: from mail-pj1-f43.google.com (mail-pj1-f43.google.com [209.85.216.43]) by mails.dpdk.org (Postfix) with ESMTP id 766F740E2B for ; Tue, 13 Aug 2024 18:00:54 +0200 (CEST) Received: by mail-pj1-f43.google.com with SMTP id 98e67ed59e1d1-2cf213128a1so3792264a91.2 for ; Tue, 13 Aug 2024 09:00:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1723564853; x=1724169653; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mWi8RPbpbOR8pS1/K/fbEHgA9x94e+BFs1LtR8NiWDg=; b=XgnpRGKmo/m/KxxLkAnfwe2zaM6+LB23QARdb5KucHmHyrxXVX+R/KtUK8A4DLafxQ HETl+8sL4IvWtIfvn1F+4MTulxPmaRw/xf/cRgy2bDf94fTmBLi0JQMGJ48W5DzgMKwf BgBmIb7rZ4ic94yicB6QiuEvy3F1mdodD9KWyoSwNRzGQK6howBFKQrkNeV5gBJR3ri2 i3X80YS5s42zLEC7kJDWZQIdgxNe50XYMYShAuNFQFqANN0Y9th+gph4hzaPQQ53kW7m hqRwf1yM9wDRoa5ig31dvnqmsZ0jFY2Qqsbj8llIFWrWQzor1u9/hWNs9xA2yD4Sxj2z Y4mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723564853; x=1724169653; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mWi8RPbpbOR8pS1/K/fbEHgA9x94e+BFs1LtR8NiWDg=; b=lmIdNttgquNFBPPaUFMCL6AqxGrKFpOp/2DcCuraQccPDegeLDywc7dMffSrMPZLux vqtoj6RdMsJMV3ViRoQ4lnTgwWQSo7U2E4pmIVQft/t/aPZ4teixYE6qbFhq7NGyqiaO nbWrx5xIxqBbXDSDD83tFcje0qWXGp/L+/jadq1OD7fAaJSdDXhWy54J2Rle8ZH8Jt3+ auOoYN+zb5yKivsLwQ/WE6eZXUIcsV64zogqHcB4ZYk0fOoiEusIskFcMke2Uch0phrQ S6LEbuQe8r5/gEBndLQKIiOCGGZMZWE4uUR3TgBog1UOhWcn7nZV5q2IfPWjUPJDwv3Z jaiQ== X-Gm-Message-State: AOJu0YwppSJ0uQ7n/PbWkGJOz4UJyujxoRA8JyX3e+Yu8ftVvYACFXIz m91ZTFXv7Ux4mLmU7oMINb0wgalZEDPP7cqA5xNISDPqmZz6jQo6OQbmQJk3qj+LGoZ3zZswi9f Dql0= X-Google-Smtp-Source: AGHT+IGJNwBYETg+TCOpLtkw0APjB6qY+Wc4T07q/bdCBqVUGwjbvS7KCM5A/PrthHBG94mfmXCmYw== X-Received: by 2002:a17:90a:7448:b0:2d1:b49d:7f2 with SMTP id 98e67ed59e1d1-2d392548219mr4627639a91.22.1723564853341; Tue, 13 Aug 2024 09:00:53 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2d1fcfe487esm7482612a91.42.2024.08.13.09.00.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Aug 2024 09:00:52 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger , Bruce Richardson , Cristian Dumitrescu Subject: [PATCH v6 4/4] test: restore cfgfile tests Date: Tue, 13 Aug 2024 08:57:55 -0700 Message-ID: <20240813160039.5861-5-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240813160039.5861-1-stephen@networkplumber.org> References: <20240730225520.83314-1-stephen@networkplumber.org> <20240813160039.5861-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org 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 Acked-by: Bruce Richardson --- 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 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 = '' # 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 #include #include -#include +#include + +#ifdef RTE_EXEC_ENV_WINDOWS +#include +#endif #include #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(¶ms, 0, sizeof(params)); params.comment_character = '#'; - cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0, - ¶ms); - TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2.ini"); + cfgfile = rte_cfgfile_load_with_params(filename, 0, ¶ms); + 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(¶ms, 0, sizeof(params)); params.comment_character = '$'; - cfgfile = rte_cfgfile_load_with_params(CFG_FILES_ETC "/sample2.ini", 0, - ¶ms); + 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, ¶ms); 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..348c78c7d9 --- /dev/null +++ b/app/test/test_cfgfiles/meson.build @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: BSD-3-Clause + +test_cfgfiles = files( + 'empty.ini', + 'empty_key_value.ini', + 'invalid_section.ini', + 'line_too_long.ini', + 'missing_section.ini', + 'realloc_sections.ini', + 'sample1.ini', + '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@'])