Skip to content

libc: add dirent tests#475

Merged
lukkrusz merged 2 commits into
masterfrom
lukkrusz/dirent_test
Jul 16, 2026
Merged

libc: add dirent tests#475
lukkrusz merged 2 commits into
masterfrom
lukkrusz/dirent_test

Conversation

@lukkrusz

@lukkrusz lukkrusz commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Adds a test coverage for dirent.h functions.

Description

The coverage includes:

  • readdir()
  • closedir()
  • opendir()
  • rewinddir()

Ensures the functions are POSIX compliant.

Motivation and Context

Ensures a fuller test coverage of libc functions

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (refactoring, style fixes, git/CI config, submodule management, no code logic changes)

How Has This Been Tested?

  • Already covered by automatic testing.
  • New test added: (add PR link here).
  • Tested by hand on: ia32-generic-qemu.

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly. (libc: update dirent documentation phoenix-rtos-doc#257)
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

  • This PR needs additional PRs to work (list the PRs, preferably in merge-order).
  • I will merge this PR by myself when appropriate.

Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive suite of POSIX-compliant tests for directory operations, including opendir, closedir, readdir, and rewinddir. The feedback identifies critical issues in the test implementation, specifically potential buffer overflows in readdir and closedir due to missing bounds checks and undersized buffers for directory names. Additionally, a redundant test definition was identified in the Makefile.

Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/Makefile Outdated
Comment thread libc/dirent/closedir.c Outdated
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from 6ffcd5b to 0bbefdc Compare April 27, 2026 12:32
Comment thread libc/dirent/readdir.c Outdated
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch 2 times, most recently from 54efad0 to feaac4b Compare April 27, 2026 13:06
@lukkrusz

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive test suite for POSIX dirent.h functions, including opendir, closedir, readdir, and rewinddir. The review identified several critical issues: potential out-of-bounds access and buffer overflows in opendir.c, incorrect process handling after a failed fork() in readdir.c, and a potential NULL pointer dereference during cleanup in test_create_directories. Additionally, improvements were suggested for the d_ino_in helper to avoid false positives when checking inode numbers.

Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
@github-actions

github-actions Bot commented Apr 27, 2026

Copy link
Copy Markdown

Unit Test Results

11 307 tests  +418   10 600 ✅ +381   54m 44s ⏱️ + 1m 1s
   690 suites + 11      707 💤 + 37 
     1 files   ±  0        0 ❌ ±  0 

Results for commit 4818906. ± Comparison against base commit cf7a946.

♻️ This comment has been updated with latest results.

@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from feaac4b to fb28d68 Compare April 27, 2026 13:51
@lukkrusz

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive test suite for POSIX.1-2017 dirent.h functions, including opendir(), closedir(), readdir(), and rewinddir(). The tests cover various scenarios such as empty and non-empty directories, permission handling, symlink loops, and thread safety. Review feedback identifies a potential buffer overflow in a test error message, suggests containing test-generated directories within a managed path to ensure proper cleanup, recommends consistent use of assertion macros for directory creation, and proposes expanding CI target coverage to include architectures mentioned in the PR description.

Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/test.yaml
Comment thread libc/dirent/readdir.c Outdated
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from fb28d68 to 5f5a34c Compare April 28, 2026 09:25
@lukkrusz

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds a comprehensive test suite for POSIX directory functions (opendir, closedir, readdir, and rewinddir) to the Phoenix-RTOS libc, along with helper macros and CI integration. Feedback focuses on improving code safety and readability by suggesting snprintf over sprintf, removing redundant type casts in memory management, and fixing a typo in the source comments.

Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/opendir.c
Comment thread libc/dirent/opendir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
Comment thread libc/dirent/readdir.c Outdated
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch 3 times, most recently from c3383bd to 69a6434 Compare April 28, 2026 12:42
@lukkrusz
lukkrusz marked this pull request as ready for review April 28, 2026 13:00
@lukkrusz
lukkrusz marked this pull request as draft April 28, 2026 13:08
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from 69a6434 to f9e4718 Compare April 28, 2026 14:08
@lukkrusz
lukkrusz marked this pull request as ready for review April 29, 2026 08:04
Comment thread libc/dirent/dirent_helper_functions.h Outdated
#include <string.h>


#define TEST_MKDIR_ASSERTED(path, mode) TEST_ASSERT_TRUE_MESSAGE(mkdir(path, mode) != -1 || errno == EEXIST, strerror(errno))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses EEXIST, but not include <errno.h>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. It's now included, thanks

Comment thread libc/dirent/opendir.c Outdated
sprintf(dirPath, MAIN_DIR "/%d", i);

TEST_MKDIR_ASSERTED(dirPath, S_IRUSR);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the assertion fails, the test exits and previously created directories are not removed. TEST_TEAR_DOWN will not remove them since rmdir only removes empty directories. Similar issue in other tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread libc/dirent/opendir.c Outdated
{
errno = 0;

TEST_ASSERT_EQUAL_INT(0, test_create_directories(20));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_create_directories is only called here and that's the only thing this test does. Is there a reason to move the logic to a separate function rather than placing it in the test directly like in other tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, moved the code to the case where it should've been

Comment thread libc/dirent/dirent_helper_functions.h Outdated
#include <unity.h>


#define TEST_MKDIR_ASSERTED(path, mode) TEST_ASSERT_TRUE_MESSAGE(mkdir(path, mode) != -1 || errno == EEXIST, strerror(errno))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will succeed if the path already exists, even if it's not a directory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, now it only passes if the directory is newly made - up for a debate, but I think the strict approach is better

Comment thread libc/dirent/opendir.c Outdated
strcpy(mutualLoop, MAIN_DIR "/D1");

/* Create a path to a valid symloop */
/* Posix says that symloops up to */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment seems incomplete.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment thread libc/dirent/opendir.c Outdated

/* Add a few layers of symloops, so it is too deep (selfLoop is not empty at this point) */
for (int i = 0; i < symloopMax / 2 - 1; ++i) {
if (strlen(selfLoop) + 10 >= PATH_MAX || strlen(mutualLoop) + 10 >= PATH_MAX) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear where the number 10 comes from, maybe use a named constant or add a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment thread libc/dirent/readdir.c Outdated
Comment on lines +53 to +72
TEST_MKDIR_ASSERTED(MAIN_DIR, 0700);

mkdir(MAIN_DIR "/dir1", S_IRUSR | S_IWUSR | S_IXUSR);
mkdir(MAIN_DIR "/dir2", S_IRUSR | S_IWUSR | S_IXUSR);

mkdir(MAIN_DIR "/dir1/nest1", S_IRUSR);
mkdir(MAIN_DIR "/dir1/nest2", S_IRUSR);

mkdir(MAIN_DIR "/dir2/nest1", S_IRUSR);
mkdir(MAIN_DIR "/dir2/nest2", S_IRUSR);

int files[] = {
creat(MAIN_DIR "/file1.txt", S_IRUSR),
creat(MAIN_DIR "/file2.dat", S_IRUSR),
creat(MAIN_DIR "/file3.json", S_IRUSR)
};

close(files[0]);
close(files[1]);
close(files[2]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Success of MAIN_DIR creation is asserted but the rest of the setup my fail silently.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment thread libc/dirent/readdir.c
Comment thread libc/dirent/rewinddir.c
Comment thread libc/dirent/rewinddir.c Outdated
Comment on lines +295 to +298
rewinddir(dp);

void *ret = readdir(dp);
(void)ret;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the result of readdir after rewinddir not checked?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was assumed to be NULL but now I put an assertion in place. Thanks

Comment thread libc/dirent/closedir.c Outdated
Comment on lines +36 to +39
errno = 0;
TEST_MKDIR_ASSERTED(MAIN_DIR, S_IRWXU);
errno = 0;
TEST_MKDIR_ASSERTED(MAIN_DIR "/dir1", S_IRUSR);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here errno is set before TEST_MKDIR_ASSERTED while in other test groups it's not. I don't think it's necessary here because the macro is only checking errno if mkdir fails.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, fixed

@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from 61debf2 to adff8e7 Compare June 12, 2026 10:52
Comment thread libc/dirent/opendir.c Outdated
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from adff8e7 to 23ce160 Compare June 12, 2026 10:55
Comment thread libc/dirent/rewinddir.c Outdated
Comment thread libc/dirent/rewinddir.c Outdated
Comment thread libc/dirent/rewinddir.c Outdated
@lukkrusz
lukkrusz marked this pull request as draft June 12, 2026 10:58
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch 2 times, most recently from 884f938 to 4371302 Compare June 12, 2026 13:42
@lukkrusz
lukkrusz marked this pull request as ready for review June 12, 2026 13:52
@lukkrusz
lukkrusz requested a review from wmlynik June 12, 2026 13:52
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch 2 times, most recently from 79aaff4 to 40f2647 Compare June 30, 2026 10:06
KArkadiusz and others added 2 commits July 16, 2026 09:49
Some tests needed refactoring and logic fixes, and
proper clean-ups.
There were also a couple of gaps in the coverage
of the test suite that had to be filled.

JIRA: CI-359

Assisted-by: Claude Opus 4.8
@lukkrusz
lukkrusz force-pushed the lukkrusz/dirent_test branch from 40f2647 to 4818906 Compare July 16, 2026 07:49
@lukkrusz
lukkrusz merged commit d99e40e into master Jul 16, 2026
47 checks passed
@lukkrusz
lukkrusz deleted the lukkrusz/dirent_test branch July 16, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants