filex_file_write_available_cluster_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /* This FileX test concentrates on the available clusters after file seek and write operation. */
  2. /* A fix-me is in this file. */
  3. #ifndef FX_STANDALONE_ENABLE
  4. #include "tx_api.h"
  5. #endif
  6. #include "fx_api.h"
  7. #include "fx_utility.h"
  8. #include "fx_ram_driver_test.h"
  9. #include "fx_fault_tolerant.h"
  10. #include <stdio.h>
  11. #define DEMO_STACK_SIZE 4096
  12. #define CACHE_SIZE 128*128
  13. #ifdef FX_ENABLE_FAULT_TOLERANT
  14. #define FAULT_TOLERANT_SIZE FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
  15. #else
  16. #define FAULT_TOLERANT_SIZE 0
  17. #endif
  18. /* Define the ThreadX and FileX object control blocks... */
  19. #ifndef FX_STANDALONE_ENABLE
  20. static TX_THREAD ftest_0;
  21. #endif
  22. static FX_MEDIA ram_disk;
  23. static FX_FILE my_file;
  24. /* Define the counters used in the test application... */
  25. struct step
  26. {
  27. ULONG offset;
  28. UINT seek;
  29. UINT size;
  30. };
  31. #ifndef FX_STANDALONE_ENABLE
  32. static UCHAR *ram_disk_memory;
  33. static UCHAR *cache_buffer;
  34. #else
  35. static UCHAR cache_buffer[CACHE_SIZE];
  36. #endif
  37. static UCHAR test_buffer[4096];
  38. #ifdef FX_ENABLE_FAULT_TOLERANT
  39. static UCHAR fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
  40. #endif /* FX_ENABLE_FAULT_TOLERANT */
  41. static struct step steps[] =
  42. {
  43. {0, FX_SEEK_FORWARD, 1136},
  44. {4 * sizeof(test_buffer), FX_SEEK_FORWARD, sizeof(test_buffer)},
  45. {112, FX_SEEK_END, sizeof(test_buffer)},
  46. {(2 * sizeof(test_buffer)), FX_SEEK_BACK, sizeof(test_buffer)},
  47. };
  48. /* Define thread prototypes. */
  49. void filex_file_write_available_cluster_application_define(void *first_unused_memory);
  50. static void ftest_0_entry(ULONG thread_input);
  51. VOID _fx_ram_driver(FX_MEDIA *media_ptr);
  52. void test_control_return(UINT status);
  53. /* Define what the initial system looks like. */
  54. #ifdef CTEST
  55. void test_application_define(void *first_unused_memory)
  56. #else
  57. void filex_file_write_available_cluster_application_define(void *first_unused_memory)
  58. #endif
  59. {
  60. #ifndef FX_STANDALONE_ENABLE
  61. UCHAR *pointer;
  62. /* Setup the working pointer. */
  63. pointer = (UCHAR *) first_unused_memory;
  64. /* Create the main thread. */
  65. tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
  66. pointer, DEMO_STACK_SIZE,
  67. 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
  68. pointer = pointer + DEMO_STACK_SIZE;
  69. /* Setup memory for the RAM disk and the sector cache. */
  70. cache_buffer = pointer;
  71. pointer = pointer + CACHE_SIZE;
  72. ram_disk_memory = pointer;
  73. #endif
  74. /* Initialize the FileX system. */
  75. fx_system_initialize();
  76. #ifdef FX_STANDALONE_ENABLE
  77. ftest_0_entry(0);
  78. #endif
  79. }
  80. /* Define the test threads. */
  81. static void ftest_0_entry(ULONG thread_input)
  82. {
  83. UINT status;
  84. #ifdef FX_ENABLE_FAULT_TOLERANT
  85. UINT enable_fault_tolerant_this_time = 0;
  86. UINT do_it_again = 0;
  87. ULONG actual;
  88. #endif /* FX_ENABLE_FAULT_TOLERANT */
  89. ULONG used_clusters;
  90. ULONG total_bytes;
  91. ULONG total_clusters;
  92. ULONG i, j;
  93. FX_PARAMETER_NOT_USED(thread_input);
  94. /* Print out some test information banners. */
  95. printf("FileX Test: File write available cluster test......................");
  96. #ifdef FX_ENABLE_FAULT_TOLERANT
  97. TEST_START:
  98. #endif /* FX_ENABLE_FAULT_TOLERANT */
  99. /* Format the media. This needs to be done before opening it! */
  100. status = fx_media_format(&ram_disk,
  101. _fx_ram_driver, // Driver entry
  102. ram_disk_memory, // RAM disk memory pointer
  103. cache_buffer, // Media buffer pointer
  104. CACHE_SIZE, // Media buffer size
  105. "MY_RAM_DISK", // Volume Name
  106. 1, // Number of FATs
  107. 32, // Directory Entries
  108. 0, // Hidden sectors
  109. 512, // Total sectors
  110. 512, // Sector size
  111. 8, // Sectors per cluster
  112. 1, // Heads
  113. 1); // Sectors per track
  114. status += fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, cache_buffer, CACHE_SIZE);
  115. return_if_fail( status == FX_SUCCESS);
  116. #ifdef FX_ENABLE_FAULT_TOLERANT
  117. if ( enable_fault_tolerant_this_time)
  118. {
  119. /* Enable the Fault-tolerant feature. */
  120. status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
  121. return_if_fail( status == FX_SUCCESS);
  122. }
  123. #endif /* FX_ENABLE_FAULT_TOLERANT */
  124. /* Create a file called TEST.TXT in the root directory. */
  125. status = fx_file_create(&ram_disk, "TEST.TXT");
  126. return_if_fail( status == FX_SUCCESS);
  127. /* Open the test file. */
  128. status = fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
  129. return_if_fail( status == FX_SUCCESS);
  130. total_clusters = ram_disk.fx_media_available_clusters;
  131. /* Run test steps. */
  132. total_bytes = 9216;
  133. for (j = 0; j < 100; j++)
  134. {
  135. i = j & 0x03;
  136. fx_file_relative_seek (&my_file, steps[i].offset, steps[i].seek);
  137. fx_file_write (&my_file, test_buffer, steps[i].size);
  138. if (i == 3)
  139. {
  140. /* Check available clusters. */
  141. used_clusters = total_bytes / 4096 + 1;
  142. return_if_fail( total_clusters == ram_disk.fx_media_available_clusters + used_clusters);
  143. /* Increase 8080 bytes each round. */
  144. total_bytes += 8080;
  145. }
  146. }
  147. #ifdef FX_ENABLE_FAULT_TOLERANT
  148. if ( enable_fault_tolerant_this_time)
  149. {
  150. /* Make IO error while looking for copy_head_cluster by _fx_utility_FAT_entry_read. */
  151. _fx_utility_fat_entry_read_error_request = 1;
  152. status = fx_file_relative_seek( &my_file, steps[0].offset, steps[0].seek);
  153. status += fx_file_write( &my_file, test_buffer, steps[0].size);
  154. return_if_fail( status == FX_IO_ERROR);
  155. /* Make IO error while looking for copy_tail_cluster by _fx_utility_FAT_entry_read. */
  156. _fx_utility_fat_entry_read_error_request = 94;
  157. status = fx_file_relative_seek( &my_file, steps[3].offset, steps[3].seek);
  158. status += fx_file_write( &my_file, test_buffer, steps[3].size);
  159. return_if_fail( status == FX_IO_ERROR);
  160. /* Make IO error while copying sectors in replaced clusters at the back in fx_file_write.c.*/
  161. _fx_ram_driver_io_error_request = 17;
  162. status = fx_file_relative_seek( &my_file, steps[3].offset, steps[3].seek);
  163. status += fx_file_write( &my_file, test_buffer, steps[3].size);
  164. return_if_fail( status == FX_IO_ERROR);
  165. /* Make IO error while writing back the current logical sector at Line 1599 in fx_file_write.c. */
  166. _fx_ram_driver_io_error_request = 18;
  167. status = fx_file_relative_seek( &my_file, steps[3].offset, steps[3].seek);
  168. status += fx_file_write( &my_file, test_buffer, steps[3].size);
  169. return_if_fail( status == FX_IO_ERROR);
  170. #if !defined(FX_ENABLE_FAULT_TOLERANT) && !defined(FX_DISABLE_CACHE)
  171. /*Make IO error while copying sectors in replaced clusters at the front in fx_file_write.c.*/
  172. _fx_ram_driver_io_error_request = 3;
  173. status = fx_file_relative_seek( &my_file, steps[3].offset, steps[3].seek);
  174. status += fx_file_write( &my_file, test_buffer, steps[3].size);
  175. return_if_fail( status == FX_IO_ERROR);
  176. #endif
  177. /* Make IO error while writing back the current logical sector at Line 1215 in fx_file_write.c. */
  178. _fx_ram_driver_io_error_request = 4;
  179. status = fx_file_relative_seek( &my_file, steps[3].offset, steps[3].seek);
  180. status += fx_file_write( &my_file, test_buffer, steps[3].size);
  181. return_if_fail( status == FX_IO_ERROR);
  182. /* Make IO error while getting the cluster next to the copy tail. */
  183. _fx_utility_fat_entry_read_error_request = 75;
  184. status = fx_file_relative_seek( &my_file, steps[3].offset, steps[3].seek);
  185. status += fx_file_write( &my_file, test_buffer, steps[3].size);
  186. /* Make IO error while _fx_file_write is calling _fx_fault_tolerant_set_FAT__chain. */
  187. _fx_ram_driver_io_error_request = 1;
  188. status = fx_file_relative_seek( &my_file, steps[0].offset, steps[0].seek);
  189. status += fx_file_write( &my_file, test_buffer, steps[0].size);
  190. return_if_fail( status == FX_IO_ERROR);
  191. /* Backup original data. */
  192. actual = my_file.fx_file_first_physical_cluster;
  193. /* Please fix me:
  194. * The following code is determing to cover a branch in fx_file_write.c, which need to get three condition:
  195. * 1. fx_file_total_clusters - fx_file_current_relative_cluster > 0
  196. * 2. fx_file_current_logical_offset >= fx_media_bytes_per_sector
  197. * 3. fx_file_current_relative_sector >= fx_media_sectors_per_cluster - 1
  198. *
  199. * In other words, it need to set fx_file_current_logical_offset at the end of a cluster which is in the middle of a file.
  200. * I manually modify FILE_STRUCT and satify the condition for coverage. Should this branch be removed?
  201. */
  202. /* Produce wrong first_physical_cluster. */
  203. status = fx_file_relative_seek( &my_file, steps[0].offset, steps[0].seek);
  204. my_file.fx_file_first_physical_cluster = 0;
  205. status += fx_file_write( &my_file, test_buffer, steps[0].size);
  206. return_if_fail( status == FX_NOT_FOUND);
  207. status = fx_file_relative_seek( &my_file, steps[0].offset, steps[0].seek);
  208. my_file.fx_file_first_physical_cluster = ram_disk.fx_media_fat_reserved;
  209. status += fx_file_write( &my_file, test_buffer, steps[0].size);
  210. return_if_fail( status == FX_NOT_FOUND);
  211. /* Restore data we just modified. */
  212. my_file.fx_file_first_physical_cluster = actual;
  213. if ( do_it_again)
  214. {
  215. goto EXTRA_TEST;
  216. }
  217. /* Attempt to cover the branch that offset is at the end of a sector but not the end of a file. */
  218. /* No head cluster need to be replaced. */
  219. status = fx_file_relative_seek( &my_file, steps[2].offset, steps[2].seek);
  220. my_file.fx_file_current_logical_offset = 512;
  221. status += fx_file_write( &my_file, test_buffer, steps[2].size);
  222. /* Attempt to cover the branch that offset is at the end of a cluster but not the end of a file. */
  223. /* No head cluster need to be replaced. */
  224. status = fx_file_relative_seek( &my_file, steps[2].offset, steps[2].seek);
  225. my_file.fx_file_current_logical_offset = 512;
  226. my_file.fx_file_current_relative_sector = 7;
  227. my_file.fx_file_total_clusters = 50;
  228. status += fx_file_write( &my_file, test_buffer, steps[2].size);
  229. /* Close the file. */
  230. status = fx_file_close(&my_file);
  231. status += fx_media_close( &ram_disk);
  232. return_if_fail( status == FX_SUCCESS);
  233. do_it_again = 1;
  234. goto TEST_START;
  235. EXTRA_TEST:
  236. /* Covered the branch dealing with the condition that offset is at the end of a cluster but not the end of a file. */
  237. /* Head cluster need to be replaced is existed. */
  238. status = fx_file_relative_seek( &my_file, steps[2].offset, steps[2].seek);
  239. my_file.fx_file_current_logical_offset = 512;
  240. my_file.fx_file_current_relative_sector = 7;
  241. status += fx_file_write( &my_file, test_buffer, steps[2].size);
  242. }
  243. #endif
  244. /* Close the file. */
  245. status = fx_file_close(&my_file);
  246. status += fx_media_close( &ram_disk);
  247. return_if_fail( status == FX_SUCCESS);
  248. #ifdef FX_ENABLE_FAULT_TOLERANT
  249. if ( enable_fault_tolerant_this_time == 0)
  250. {
  251. enable_fault_tolerant_this_time = 1;
  252. goto TEST_START;
  253. }
  254. #endif
  255. #if defined(FX_ENABLE_FAULT_TOLERANT) && !defined(FX_DISABLE_CACHE)
  256. FX_CACHED_SECTOR cache_entry;
  257. ram_disk.fx_media_sector_cache_hashed = 0;
  258. ram_disk.fx_media_memory_buffer = test_buffer;
  259. ram_disk.fx_media_sector_cache_end = test_buffer;
  260. ram_disk.fx_media_fault_tolerant_enabled = 1;
  261. ram_disk.fx_media_fault_tolerant_state |= FX_FAULT_TOLERANT_STATE_STARTED;
  262. ram_disk.fx_media_sector_cache_list_ptr = &cache_entry;
  263. ram_disk.fx_media_sector_cache_size = 1;
  264. cache_entry.fx_cached_sector_memory_buffer = NULL;
  265. cache_entry.fx_cached_sector_next_used = NULL;
  266. _fx_utility_logical_sector_write(&ram_disk, (ULONG64)3, test_buffer, 0, FX_DATA_SECTOR);
  267. #endif /* defined(FX_ENABLE_FAULT_TOLERANT) && !defined(FX_DISABLE_CACHE) */
  268. printf("SUCCESS!\n");
  269. test_control_return(0);
  270. }