Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions common/src/fx_file_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

/* Portions of this file were generated with AI assistance. */


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -1321,6 +1323,7 @@ ULONG replace_clusters = 0; /* The number of clusters to

/* Setup initial parameters. */
search_ptr -> fx_file_total_clusters = file_ptr -> fx_file_total_clusters;
search_ptr -> fx_file_first_physical_cluster = file_ptr -> fx_file_first_physical_cluster;
search_ptr -> fx_file_current_physical_cluster = file_ptr -> fx_file_first_physical_cluster;
search_ptr -> fx_file_current_relative_cluster = 0;
search_ptr -> fx_file_current_logical_sector = ((ULONG)media_ptr -> fx_media_data_sector_start) +
Expand Down
5 changes: 5 additions & 0 deletions test/cmake/regression/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ set(regression_test_cases
${SOURCE_DIR}/filex_file_date_time_set_test.c
${SOURCE_DIR}/filex_file_naming_test.c
${SOURCE_DIR}/filex_file_read_write_test.c
${SOURCE_DIR}/filex_file_open_empty_reader_test.c
${SOURCE_DIR}/filex_file_rename_test.c
${SOURCE_DIR}/filex_file_seek_test.c
${SOURCE_DIR}/filex_file_name_test.c
Expand Down Expand Up @@ -172,6 +173,10 @@ foreach(test_case ${regression_test_cases})
add_test(NAME ${CMAKE_BUILD_TYPE}::${test_name} COMMAND ${test_target})
endforeach()

set_tests_properties(
${CMAKE_BUILD_TYPE}::filex_file_open_empty_reader_test
PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR CODE")

# These two tests write or corrupt large amounts of data on a 900 MB RAM disk and are
# inherently slow (≈95 s and ≈330 s on Windows). Override the default 60-second ctest
# timeout so that they are not mis-reported as failures.
Expand Down
202 changes: 202 additions & 0 deletions test/regression_test/filex_file_open_empty_reader_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/***************************************************************************
* Copyright (c) 2026 Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* AI Disclosure: This file was largely AI-generated by Codex (GPT-6-Sol).
* The AI-generated portions may be considered public domain (CC0-1.0)
* and not subject to the project's licence. The human contributor has
* reviewed and verified that the code is correct.
*
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/

#ifndef FX_STANDALONE_ENABLE
#include "tx_api.h"
#endif
#include "fx_api.h"
#include "fx_ram_driver_test.h"

#define TEST_STACK_SIZE 4096u
#define TEST_CACHE_SIZE 4096u
#define TEST_SECTOR_SIZE 512u

#ifndef FX_STANDALONE_ENABLE
static TX_THREAD test_thread;
static UCHAR *test_cache;
#else
static UCHAR test_cache[TEST_CACHE_SIZE];
#endif

static UCHAR *test_disk_memory;
static FX_MEDIA test_media;
static FX_FILE write_file;
static FX_FILE read_file;
static FX_FILE fast_read_file;
static UCHAR write_data[2u * TEST_SECTOR_SIZE];
static UCHAR read_data[TEST_SECTOR_SIZE];

VOID _fx_ram_driver(FX_MEDIA *media_ptr);
void test_control_return(UINT status);

/* Check that both readers can seek after the first cluster is allocated. */
static UINT check_read_handle(FX_FILE *file_ptr)
{
ULONG actual_size;
UINT index;
UINT status;

if ((file_ptr -> fx_file_first_physical_cluster == 0u) ||
(file_ptr -> fx_file_first_physical_cluster != write_file.fx_file_first_physical_cluster))
{
return(1u);
}

status = fx_file_seek(file_ptr, TEST_SECTOR_SIZE);
if (status != FX_SUCCESS)
{
return(2u);
}

status = fx_file_read(file_ptr, read_data, sizeof(read_data), &actual_size);
if ((status != FX_SUCCESS) || (actual_size != sizeof(read_data)))
{
return(3u);
}

for (index = 0u; index < sizeof(read_data); index++)
{
if (read_data[index] != (UCHAR)'a')
{
return(4u);
}
}

return(FX_SUCCESS);
}

/* Exercise a writer and two readers of the same initially empty file. */
static UINT run_case(VOID)
{
UINT index;
UINT status;

status = fx_media_format(&test_media, _fx_ram_driver, test_disk_memory,
test_cache, TEST_CACHE_SIZE, "RAM DISK", 1u, 32u,
0u, 512u, TEST_SECTOR_SIZE, 8u, 1u, 1u);
if (status != FX_SUCCESS)
{
return(5u);
}

status = fx_media_open(&test_media, "RAM DISK", _fx_ram_driver,
test_disk_memory, test_cache, TEST_CACHE_SIZE);
if (status != FX_SUCCESS)
{
return(6u);
}

status = fx_file_create(&test_media, "TEST.TXT");
if (status != FX_SUCCESS)
{
return(7u);
}

status = fx_file_open(&test_media, &write_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
if (status != FX_SUCCESS)
{
return(8u);
}

status = fx_file_open(&test_media, &read_file, "TEST.TXT", FX_OPEN_FOR_READ);
if (status != FX_SUCCESS)
{
return(9u);
}

status = fx_file_open(&test_media, &fast_read_file, "TEST.TXT", FX_OPEN_FOR_READ_FAST);
if (status != FX_SUCCESS)
{
return(10u);
}

for (index = 0u; index < sizeof(write_data); index++)
{
write_data[index] = (UCHAR)'a';
}

status = fx_file_write(&write_file, write_data, sizeof(write_data));
if (status != FX_SUCCESS)
{
return(11u);
}

status = check_read_handle(&read_file);
if (status == FX_SUCCESS)
{
status = check_read_handle(&fast_read_file);
}
if (status != FX_SUCCESS)
{
return(status);
}

status = fx_file_close(&fast_read_file);
if (status != FX_SUCCESS)
{
return(12u);
}

status = fx_file_close(&read_file);
if (status != FX_SUCCESS)
{
return(13u);
}

status = fx_file_close(&write_file);
if (status != FX_SUCCESS)
{
return(14u);
}

status = fx_media_close(&test_media);
if (status != FX_SUCCESS)
{
return(15u);
}

return(FX_SUCCESS);
}

/* Run the regression from a ThreadX thread or standalone test context. */
static VOID test_thread_entry(ULONG input)
{
FX_PARAMETER_NOT_USED(input);
test_control_return(run_case());
}

/* Supply the application entry point used by the regression runner. */
void test_application_define(void *first_unused_memory)
{
#ifndef FX_STANDALONE_ENABLE
UCHAR *pointer;

pointer = (UCHAR *)first_unused_memory;
pointer += TEST_STACK_SIZE;
test_cache = pointer;
pointer += TEST_CACHE_SIZE;
test_disk_memory = pointer;

fx_system_initialize();
(VOID)tx_thread_create(&test_thread, "empty-file reader", test_thread_entry,
0u, first_unused_memory, TEST_STACK_SIZE,
4u, 4u, TX_NO_TIME_SLICE, TX_AUTO_START);
#else
FX_PARAMETER_NOT_USED(first_unused_memory);
test_disk_memory = ram_disk_memory;
fx_system_initialize();
test_thread_entry(0u);
#endif
}
Loading