|WARNING| [v2,4/4] test/cfgfile: test for long lines in file
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Mon Aug 17 17:19:07 CEST 2026
Test-Label: ai-code-review
Test-Status: WARNING
https://dpdk.org/patch/167875
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-08-17
# DPDK Patch Review
## Patch 1/4: test/cfgfile: improve coverage for listing APIs
### Errors
None.
### Warnings
None.
### Info
This patch adds comprehensive test coverage for listing APIs. The code is well-structured and follows DPDK test patterns correctly. The sentinel value checks (0x5a pattern) are a good defensive testing practice to verify array bounds are respected.
---
## Patch 2/4: test/cfgfile: validate config creation APIs
### Errors
**Resource leak on error path (line ~210):**
The `cfgfile` is created but not freed on the error paths before the first save.
If any of the `rte_cfgfile_add_section()` or `rte_cfgfile_add_entry()` calls fail, the function returns early via `TEST_ASSERT_SUCCESS()` without closing `cfgfile`, leaking the allocated structure.
**Suggested fix:**
```c
cfgfile = rte_cfgfile_create(0);
TEST_ASSERT_NOT_NULL(cfgfile, "Failed to create cfgfile");
ret = rte_cfgfile_add_section(cfgfile, "section1");
if (ret != 0) {
rte_cfgfile_close(cfgfile);
TEST_ASSERT_SUCCESS(ret, "Failed to add section1");
}
ret = rte_cfgfile_add_entry(cfgfile, "section1", "key1", "value1");
if (ret != 0) {
rte_cfgfile_close(cfgfile);
TEST_ASSERT_SUCCESS(ret, "Failed to add section1 key1");
}
/* ... similar for other add operations ... */
```
Or restructure to use a cleanup label:
```c
ret = rte_cfgfile_add_section(cfgfile, "section1");
if (ret != 0)
goto cleanup;
/* ... */
cleanup:
rte_cfgfile_close(cfgfile);
TEST_ASSERT_SUCCESS(ret, "Failed operation");
```
**Resource leak on error path (line ~236):**
Similarly, the `loaded` cfgfile is not closed if any of the validation assertions fail after it is loaded.
Add cleanup for `loaded` on error paths or restructure with a cleanup label.
**File descriptor leak (line ~231):**
If `rte_cfgfile_save()` succeeds but `rte_cfgfile_close()` fails, or if loading fails, the temporary file is not removed (the `remove(filename)` is only reached at the end of the function).
Move file cleanup to an error path or use a cleanup label.
### Warnings
None beyond the errors above.
---
## Patch 3/4: test/cfgfile: verify file modification API
### Errors
**Resource leak on error path (line ~507, ~517):**
The `cfgfile` is loaded but not closed if `rte_cfgfile_has_entry()`, `rte_cfgfile_set_entry()`, `rte_cfgfile_add_entry()`, or `rte_cfgfile_save()` fail.
Each early return via `TEST_ASSERT*` leaks the cfgfile handle.
**Suggested fix:**
Add cleanup on all error paths, similar to the pattern in Patch 2.
**Resource leak on error path (line ~533):**
The `loaded` cfgfile is not closed if any of the assertions after loading fail (value checks, etc.).
**File descriptor leak:**
The temporary file is not removed if any assertion fails before the final `remove(filename)`.
### Warnings
None beyond the errors above.
---
## Patch 4/4: test/cfgfile: test for long lines in file
### Errors
None. This patch is correct.
### Warnings
None.
---
## Summary
**Patches 2 and 3** have **resource leak errors** on multiple error paths where `rte_cfgfile` handles and temporary files are not cleaned up when assertions fail. The TEST_ASSERT macros cause early return, skipping the cleanup code at the end of the function.
**Recommended fix pattern** for all affected test functions:
Use a cleanup label and `goto` to ensure resources are always released, even on assertion failure. Or check each return value explicitly and clean up before calling TEST_ASSERT.
Example:
```c
static int
test_cfgfile_create_add_save_reload(void)
{
struct rte_cfgfile *cfgfile = NULL;
struct rte_cfgfile *loaded = NULL;
const char *value;
char filename[PATH_MAX];
int ret;
int test_result = 0;
cfgfile = rte_cfgfile_create(0);
if (cfgfile == NULL) {
test_result = -1;
goto cleanup;
}
ret = rte_cfgfile_add_section(cfgfile, "section1");
if (ret != 0) {
test_result = -1;
goto cleanup;
}
/* ... similar for all operations ... */
ret = make_tmp_file(filename, "create_save", "");
if (ret != 0) {
test_result = -1;
goto cleanup;
}
ret = rte_cfgfile_save(cfgfile, filename);
if (ret != 0) {
test_result = -1;
remove(filename);
goto cleanup;
}
rte_cfgfile_close(cfgfile);
cfgfile = NULL;
loaded = rte_cfgfile_load(filename, 0);
if (loaded == NULL) {
test_result = -1;
remove(filename);
goto cleanup;
}
/* ... validation checks ... */
value = rte_cfgfile_get_entry(loaded, "section1", "key1");
if (strcmp("value1", value) != 0) {
test_result = -1;
goto cleanup;
}
/* ... more checks ... */
cleanup:
if (cfgfile != NULL)
rte_cfgfile_close(cfgfile);
if (loaded != NULL)
rte_cfgfile_close(loaded);
if (filename[0] != '\0')
remove(filename);
TEST_ASSERT_SUCCESS(test_result, "Test failed");
return 0;
}
```
**Patch 1** and **Patch 4** are correct and have no issues.
More information about the test-report
mailing list