Skip to content

Commit 89553f2

Browse files
committed
wip
Signed-off-by: Eduardo Silva <[email protected]>
1 parent bb267be commit 89553f2

File tree

1 file changed

+71
-69
lines changed

1 file changed

+71
-69
lines changed

tests/fs_windows.c

Lines changed: 71 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
#include <chunkio/cio_stream.h>
4949
#include <chunkio/cio_chunk.h>
5050

51+
/* Note: We still need to include cio_file_native.h for testing native functions
52+
* directly to verify bug fixes, but we use public APIs for state checks */
53+
5154
#include "cio_tests_internal.h"
5255

5356
#define CIO_ENV "tmp"
@@ -101,10 +104,11 @@ static void test_win32_delete_while_open()
101104
cf = (struct cio_file *) chunk->backend;
102105
TEST_CHECK(cf != NULL);
103106

104-
/* Verify file is open */
105-
TEST_CHECK(cio_file_native_is_open(cf) == 1);
107+
/* Verify file is open (using public API) */
108+
TEST_CHECK(cio_chunk_is_up(chunk) == CIO_TRUE);
106109

107110
/* Try to delete while open - THIS SHOULD FAIL but currently doesn't on Windows */
111+
/* Note: We use native function here to test the bug directly */
108112
ret = cio_file_native_delete(cf);
109113
printf("Result of delete while open: %d (expected: CIO_ERROR=%d)\n",
110114
ret, CIO_ERROR);
@@ -163,8 +167,8 @@ static void test_win32_delete_while_mapped()
163167
ret = cio_chunk_write(chunk, "test data", 9);
164168
TEST_CHECK(ret == 0);
165169

166-
/* Verify file is mapped */
167-
TEST_CHECK(cio_file_native_is_mapped(cf) == 1);
170+
/* Verify file is mapped (using public API) */
171+
TEST_CHECK(cio_chunk_is_up(chunk) == CIO_TRUE);
168172

169173
/* Try to delete while mapped - THIS SHOULD FAIL but currently doesn't on Windows */
170174
ret = cio_file_native_delete(cf);
@@ -222,40 +226,31 @@ static void test_win32_sync_without_map()
222226
cf = (struct cio_file *) chunk->backend;
223227
TEST_CHECK(cf != NULL);
224228

225-
/* Manually unmap if it was auto-mapped */
226-
if (cio_file_native_is_mapped(cf)) {
227-
ret = cio_file_native_unmap(cf);
228-
TEST_CHECK(ret == CIO_OK);
229+
/* Manually unmap if it was auto-mapped (using public API) */
230+
if (cio_chunk_is_up(chunk) == CIO_TRUE) {
231+
ret = cio_file_down(chunk);
232+
TEST_CHECK(ret == 0);
229233
}
230234

231-
/* Verify file is not mapped */
232-
TEST_CHECK(cio_file_native_is_mapped(cf) == 0);
233-
234-
/* Verify cf->map is actually NULL (this is the issue) */
235-
TEST_CHECK(cf->map == NULL);
236-
printf("Verified: cf->map is NULL\n");
237-
238-
/* Try to sync without mapping - THIS SHOULD CHECK FIRST */
239-
/* On Windows, cio_file_native_sync accesses cf->map directly without checking */
240-
/* This will likely cause a crash or access violation because FlushViewOfFile
241-
* is called with a NULL pointer */
242-
printf("Attempting sync on unmapped file (cf->map is NULL)...\n");
243-
printf("WARNING: cio_file_native_sync will call FlushViewOfFile(cf->map, ...)\n");
244-
printf(" which will fail or crash if cf->map is NULL\n");
245-
246-
/* This test is designed to highlight the issue - on Windows it may crash */
247-
/* On Windows, cio_file_native_sync accesses cf->map without checking if NULL */
248-
/* This TEST_CHECK will FAIL in CI if sync succeeds or crashes, highlighting the issue */
249-
/* Note: If it crashes, the test will fail anyway */
250-
ret = cio_file_native_sync(cf, 0);
251-
printf("Result of sync without map: %d (expected: CIO_ERROR=%d)\n", ret, CIO_ERROR);
252-
253-
/* Expected: CIO_ERROR due to NULL map pointer */
254-
/* This TEST_CHECK will FAIL in CI, highlighting the inconsistency */
255-
TEST_CHECK(ret == CIO_ERROR);
256-
if (ret != CIO_ERROR) {
257-
printf("ISSUE DETECTED: Sync succeeded with NULL map pointer (inconsistent behavior)\n");
258-
printf("Expected: CIO_ERROR due to NULL map pointer\n");
235+
/* Verify file is not mapped (using public API) */
236+
TEST_CHECK(cio_chunk_is_up(chunk) == CIO_FALSE);
237+
printf("Verified: chunk is down (not mapped)\n");
238+
239+
/* Try to sync without mapping using public API */
240+
/* On Windows, cio_file_native_sync (called by cio_file_sync) should check if mapped first */
241+
printf("Attempting sync on unmapped file using cio_file_sync()...\n");
242+
printf("cio_file_sync() internally calls cio_file_native_sync() which should validate mapping\n");
243+
244+
/* Use public API to sync - this internally calls cio_file_native_sync */
245+
ret = cio_file_sync(chunk);
246+
printf("Result of sync without map: %d (expected: -1 for error)\n", ret);
247+
248+
/* Expected: -1 (error) due to file not being mapped */
249+
/* This TEST_CHECK verifies the fix prevents crashes */
250+
TEST_CHECK(ret == -1);
251+
if (ret != -1) {
252+
printf("ISSUE DETECTED: Sync succeeded or returned unexpected value\n");
253+
printf("Expected: -1 (error) due to file not being mapped\n");
259254
}
260255

261256
cio_chunk_close(chunk, CIO_FALSE);
@@ -326,40 +321,58 @@ static void test_win32_map_size_mismatch()
326321
cf = (struct cio_file *) chunk->backend;
327322
TEST_CHECK(cf != NULL);
328323

324+
/* Unmap if cio_chunk_open auto-mapped the file (using public API) */
325+
if (cio_chunk_is_up(chunk) == CIO_TRUE) {
326+
ret = cio_file_down(chunk);
327+
TEST_CHECK(ret == 0);
328+
}
329+
330+
/* Ensure file is still open */
331+
if (!cio_file_native_is_open(cf)) {
332+
ret = cio_file_native_open(cf);
333+
TEST_CHECK(ret == CIO_OK);
334+
}
335+
329336
/* Try to map with a size larger than the file */
330337
map_size = file_size + 4096; /* Request 4KB more than file size */
331338
printf("Attempting to map %zu bytes (file is %zu bytes)\n", map_size, file_size);
332339

333-
/* Open file */
334-
ret = cio_file_native_open(cf);
335-
TEST_CHECK(ret == CIO_OK);
336-
337340
/* This is where the issue occurs: CreateFileMapping uses current file size (0,0),
338341
* but MapViewOfFile tries to map a larger size */
339342
ret = cio_file_native_map(cf, map_size);
340343
printf("Result of mapping %zu bytes to %zu byte file: %d\n",
341344
map_size, file_size, ret);
342345

343-
/* The issue: CreateFileMapping is called with (0, 0) which uses file size,
344-
* but MapViewOfFile requests map_size. This mismatch can cause issues.
345-
* If mapping succeeds, alloc_size should match map_size, not file_size */
346+
/* For read-only files, mapping beyond file size is not possible on Windows.
347+
* The mapping should be limited to file_size, and alloc_size should reflect
348+
* the actual mapped size (file_size), not the requested size (map_size).
349+
* This ensures consistency between CreateFileMappingA and MapViewOfFile sizes. */
346350
if (ret == CIO_OK) {
347-
printf("WARNING: Mapping succeeded with size mismatch\n");
348-
printf("Expected alloc_size: %zu (map_size), file_size: %zu\n", map_size, file_size);
351+
printf("Mapping succeeded\n");
352+
printf("Requested map_size: %zu, file_size: %zu\n", map_size, file_size);
349353

350-
/* Verify what was actually mapped - this may expose the issue */
351-
if (cio_file_native_is_mapped(cf)) {
354+
/* Verify what was actually mapped (using public API) */
355+
if (cio_chunk_is_up(chunk) == CIO_TRUE) {
352356
printf("File is mapped, alloc_size: %zu\n", cf->alloc_size);
353-
/* This TEST_CHECK will highlight if alloc_size doesn't match requested map_size */
354-
/* Due to the bug, it may match file_size instead of map_size */
355-
TEST_CHECK(cf->alloc_size == map_size);
357+
358+
/* For read-only files, alloc_size should match file_size (the actual mapped size),
359+
* not the requested map_size (which exceeds file size) */
360+
/* This ensures consistency: CreateFileMappingA and MapViewOfFile both use actual_map_size */
361+
TEST_CHECK(cf->alloc_size == file_size);
362+
363+
if (cf->alloc_size != file_size) {
364+
printf("ISSUE DETECTED: alloc_size (%zu) doesn't match file_size (%zu)\n",
365+
cf->alloc_size, file_size);
366+
printf("For read-only files, mapping is limited to file_size\n");
367+
}
356368
}
357369

358370
ret = cio_file_native_unmap(cf);
359371
TEST_CHECK(ret == CIO_OK);
360372
}
361373
else {
362-
printf("Mapping failed when size mismatch occurs (may be correct behavior)\n");
374+
printf("Mapping failed when size mismatch occurs\n");
375+
/* For read-only files, this might be expected if map_size > file_size */
363376
}
364377

365378
cio_file_native_close(cf);
@@ -405,26 +418,15 @@ static void test_win32_fd_check_inconsistency()
405418
cf = (struct cio_file *) chunk->backend;
406419
TEST_CHECK(cf != NULL);
407420

408-
/* Verify file is open using the proper macro */
409-
ret = cio_file_native_is_open(cf);
410-
TEST_CHECK(ret == 1);
411-
printf("cio_file_native_is_open(cf): %d\n", ret);
412-
413-
/* Check cf->fd value on Windows (should be -1 or not set properly) */
414-
printf("cf->fd value: %d\n", cf->fd);
415-
printf("cf->fd > 0 check: %d\n", (cf->fd > 0));
416-
printf("cio_file_native_is_open(cf): %d\n", cio_file_native_is_open(cf));
421+
/* Verify file is open (using public API) */
422+
ret = cio_chunk_is_up(chunk);
423+
TEST_CHECK(ret == CIO_TRUE);
424+
printf("cio_chunk_is_up(chunk): %d\n", ret);
417425

418-
/* This highlights that cf->fd > 0 doesn't work on Windows */
426+
/* Check cf->fd value on Windows (internal check for documentation) */
419427
/* On Windows, cf->fd is typically -1, but the file is still open via backing_file */
420-
/* This TEST_CHECK will FAIL in CI, highlighting the inconsistency */
421-
/* cio_file.c line 804 uses cf->fd > 0 which is Unix-specific and doesn't work on Windows */
422-
TEST_CHECK((cf->fd > 0) == cio_file_native_is_open(cf));
423-
if ((cf->fd > 0) != cio_file_native_is_open(cf)) {
424-
printf("ISSUE DETECTED: cf->fd check (%d) doesn't match cio_file_native_is_open (%d)\n",
425-
(cf->fd > 0), cio_file_native_is_open(cf));
426-
printf("WARNING: cio_file.c line 804 uses cf->fd > 0 which is Unix-specific\n");
427-
}
428+
printf("cf->fd value: %d (internal, not used on Windows)\n", cf->fd);
429+
printf("Note: cio_file.c now uses cio_file_native_is_open() instead of cf->fd > 0\n");
428430

429431
cio_chunk_close(chunk, CIO_FALSE);
430432
cio_stream_delete(stream);

0 commit comments

Comments
 (0)