1 /* This FileX test is determined to cover filex_fault_tolerant_file_delete */
2
3
4
5 #ifndef FX_STANDALONE_ENABLE
6 #include "tx_api.h"
7 #else
8 #define _GNU_SOURCE
9 #define _DEFAULT_SOURCE
10 #include <pthread.h>
11 #include <unistd.h>
12 #endif
13 #include "fx_api.h"
14 #include "fx_system.h"
15 #include "fx_fault_tolerant.h"
16 #include <stdio.h>
17 #include "fx_ram_driver_test.h"
18 extern void test_control_return(UINT status);
19 void filex_fault_tolerant_file_delete_test_application_define(void *first_unused_memory);
20
21 #if defined (FX_ENABLE_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT_DATA)
22
23 #define DEMO_STACK_SIZE 4096
24 #define CACHE_SIZE 2048
25 #define FAULT_TOLERANT_SIZE FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
26
27
28
29
30 /* Define the ThreadX and FileX object control blocks... */
31
32 #ifndef FX_STANDALONE_ENABLE
33 static TX_THREAD ftest_0;
34 static TX_THREAD ftest_1;
35 #else
36 static pthread_t ptid1;
37 #endif
38 static FX_MEDIA ram_disk;
39 static FX_FILE my_file;
40 static UCHAR *pointer;
41
42 /* Define the counters used in the test application... */
43
44 #ifndef FX_STANDALONE_ENABLE
45 static UCHAR *cache_buffer;
46 static UCHAR *fault_tolerant_buffer;
47 static UCHAR *thread_buffer;
48 #else
49 static UCHAR cache_buffer[CACHE_SIZE];
50 static UCHAR fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
51 #endif
52 static UINT fat_write_interrupt = FX_FALSE;
53 static CHAR read_buffer[1024];
54 static UINT read_buffer_size = 1024;
55
56 #define TEST_COUNT 3
57
58 /* Define thread prototypes. */
59
60 static void ftest_0_entry(ULONG thread_input);
61 #ifndef FX_STANDALONE_ENABLE
62 static void ftest_1_entry(ULONG thread_input);
63 #else
64 static void * ftest_1_entry(void * thread_input);
65 #endif
66 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
67 extern void test_control_return(UINT status);
68 extern UINT _filex_fault_tolerant_log_check(FX_MEDIA *media_ptr);
69 extern UINT(*driver_write_callback)(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
70 static UINT my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
71
72
73
74 /* Create a terrible driver. */
75 static UINT driver_called_counter = 0;
_fx_terrible_driver(FX_MEDIA * media_ptr)76 static void _fx_terrible_driver(FX_MEDIA *media_ptr)
77 {
78 driver_called_counter++;
79 // printf("\n_fx_terrible_driver has been called %d times.", driver_called_counter);
80 if (driver_called_counter == 1)
81 {
82 media_ptr->fx_media_driver_status = FX_IO_ERROR;
83 return;
84 }
85 (*_fx_ram_driver)(media_ptr);
86 }
87
88 /* Define what the initial system looks like. */
89
90 #ifdef CTEST
test_application_define(void * first_unused_memory)91 void test_application_define(void *first_unused_memory)
92 #else
93 void filex_fault_tolerant_file_delete_test_application_define(void *first_unused_memory)
94 #endif
95 {
96
97
98 #ifndef FX_STANDALONE_ENABLE
99 /* Setup the working pointer. */
100 pointer = (UCHAR *)first_unused_memory;
101
102 /* Create the main thread. */
103 tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
104 pointer, DEMO_STACK_SIZE,
105 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
106 pointer = pointer + DEMO_STACK_SIZE;
107
108 /* Setup memory for the RAM disk and the sector cache. */
109 cache_buffer = pointer;
110 pointer += CACHE_SIZE;
111 fault_tolerant_buffer = pointer;
112 pointer += FAULT_TOLERANT_SIZE;
113 thread_buffer = pointer;
114 pointer += DEMO_STACK_SIZE;
115 #endif
116
117 /* Initialize the FileX system. */
118 fx_system_initialize();
119 #ifdef FX_STANDALONE_ENABLE
120 ftest_0_entry(0);
121 #endif
122 }
123
124
125
126 /* Define the test threads. */
127
ftest_0_entry(ULONG thread_input)128 static void ftest_0_entry(ULONG thread_input)
129 {
130
131 UINT status;
132 ULONG actual;
133 UINT i;
134
135 FX_PARAMETER_NOT_USED(thread_input);
136
137 /* Print out some test information banners. */
138 printf("FileX Test: Fault Tolerant File Delete Test........................");
139
140 /* Loop to test FAT 12, 16, 32. */
141 for (i = 0; i < TEST_COUNT; i++)
142 {
143 if (i == 0)
144 {
145 /* Format the media with FAT12. This needs to be done before opening it! */
146 status = fx_media_format(&ram_disk,
147 _fx_ram_driver, // Driver entry
148 ram_disk_memory_large, // RAM disk memory pointer
149 cache_buffer, // Media buffer pointer
150 CACHE_SIZE, // Media buffer size
151 "MY_RAM_DISK", // Volume Name
152 1, // Number of FATs
153 32, // Directory Entries
154 0, // Hidden sectors
155 256, // Total sectors
156 256, // Sector size
157 8, // Sectors per cluster
158 1, // Heads
159 1); // Sectors per track
160 }
161 else if (i == 1)
162 {
163 /* Format the media with FAT16. This needs to be done before opening it! */
164 status = fx_media_format(&ram_disk,
165 _fx_ram_driver, // Driver entry
166 ram_disk_memory_large, // RAM disk memory pointer
167 cache_buffer, // Media buffer pointer
168 CACHE_SIZE, // Media buffer size
169 "MY_RAM_DISK", // Volume Name
170 1, // Number of FATs
171 32, // Directory Entries
172 0, // Hidden sectors
173 4200 * 8, // Total sectors
174 256, // Sector size
175 8, // Sectors per cluster
176 1, // Heads
177 1); // Sectors per track
178 }
179 else if (i == 2)
180 {
181 /* Format the media with FAT32. This needs to be done before opening it! */
182 status = fx_media_format(&ram_disk,
183 _fx_ram_driver, // Driver entry
184 ram_disk_memory_large, // RAM disk memory pointer
185 cache_buffer, // Media buffer pointer
186 CACHE_SIZE, // Media buffer size
187 "MY_RAM_DISK", // Volume Name
188 1, // Number of FATs
189 32, // Directory Entries
190 0, // Hidden sectors
191 70000 * 8, // Total sectors
192 256, // Sector size
193 8, // Sectors per cluster
194 1, // Heads
195 1); // Sectors per track
196 }
197
198 /* Determine if the format had an error. */
199 if (status)
200 {
201
202 printf("ERROR!\n");
203 test_control_return(1);
204 }
205
206 /* Open the ram_disk. */
207 status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
208
209 /* Check the status. */
210 if (status != FX_SUCCESS)
211 {
212
213 /* Output successful. */
214 printf("SUCCESS!\n");
215 test_control_return(0);
216
217 }
218
219 /* Enable the Fault-tolerant feature. */
220 status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
221
222 /* Check status. */
223 if (status)
224 {
225
226 printf("ERROR!\n");
227 test_control_return(3);
228 }
229
230 /* Create a file called TEST2.TXT in the root directory. */
231 status = fx_file_create(&ram_disk, "TEST2.TXT");
232
233 /* Check the create status. */
234 if (status != FX_SUCCESS)
235 {
236
237 printf("ERROR!\n");
238 test_control_return(16);
239 }
240
241 /* Open the test file. */
242 status = fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
243
244 /* Check the file open status. */
245 if (status != FX_SUCCESS)
246 {
247
248 printf("ERROR!\n");
249 test_control_return(17);
250 }
251
252 /* Write a string to the test file. */
253 status = fx_file_write(&my_file, " EXPRESSLOGIC_TEST\n", 19);
254
255 /* Check the file write status. */
256 if (status != FX_SUCCESS)
257 {
258
259 printf("ERROR!\n");
260 test_control_return(18);
261 }
262
263 /* Seek to the beginning of the test file. */
264 status = fx_file_seek(&my_file, 0);
265
266 /* Check the file seek status. */
267 if (status != FX_SUCCESS)
268 {
269
270 printf("ERROR!\n");
271 test_control_return(19);
272 }
273
274 /* Read the bytes of the test file. */
275 status = fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
276
277 /* Check the file read status. */
278 if ((status != FX_SUCCESS) || (actual != 19))
279 {
280
281 printf("ERROR!\n");
282 test_control_return(20);
283 }
284
285 /* Close the test file. */
286 status = fx_file_close(&my_file);
287
288 /* Check the file close status. */
289 if (status != FX_SUCCESS)
290 {
291
292 printf("ERROR!\n");
293 test_control_return(21);
294 }
295
296 #ifndef FX_STANDALONE_ENABLE
297 /* Create the main thread. */
298 tx_thread_create(&ftest_1, "thread 1", ftest_1_entry, 0,
299 thread_buffer, DEMO_STACK_SIZE,
300 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
301 #endif
302 /* directory_write_interrupt */
303 fat_write_interrupt = FX_FALSE;
304
305 /* Let the other thread run. */
306 #ifndef FX_STANDALONE_ENABLE
307 tx_thread_relinquish();
308 #else
309 pthread_create(&ptid1, NULL, &ftest_1_entry, NULL);
310 usleep(10);
311 pthread_join(ptid1,NULL);
312 #endif
313 /* Delete the thread. */
314 #ifndef FX_STANDALONE_ENABLE
315 tx_thread_delete(&ftest_1);
316 #else
317 pthread_cancel(ptid1);
318 #endif
319 }
320
321 /* Output successful. */
322 printf("SUCCESS!\n");
323 test_control_return(0);
324
325 }
326
327
328 /* Define the test threads. */
329
330 #ifndef FX_STANDALONE_ENABLE
ftest_1_entry(ULONG thread_input)331 static void ftest_1_entry(ULONG thread_input)
332 #else
333 void * ftest_1_entry(void * thread_input)
334 #endif
335 {
336
337 #ifdef FX_STANDALONE_ENABLE
338 UINT oldtype;
339 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
340 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
341 #endif
342 UINT status;
343
344 FX_PARAMETER_NOT_USED(thread_input);
345
346 /* Set the callback function to simulate poweoff operation when write FAT entry. */
347 driver_write_callback = my_driver_write;
348
349 /* Register our terrible dirver to make IO ERROR at a particular time. */
350 ram_disk.fx_media_driver_entry = _fx_terrible_driver;
351
352 /* Create a file called TEST2.TXT in the root directory. */
353 status=fx_file_delete(&ram_disk, "TEST2.TXT");
354 return_value_if_fail(status == FX_IO_ERROR, 6);
355
356 /* Unregister our terrible driver. */
357 ram_disk.fx_media_driver_entry = _fx_ram_driver;
358 }
359
360
my_driver_write(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)361 static UINT my_driver_write(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
362 {
363
364 FX_PARAMETER_NOT_USED(block_ptr);
365
366 /* Interrupt the FAT write operation after record the redo log. */
367 if ((sector_type == FX_FAT_SECTOR) && (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_DONE))
368 {
369
370 /* Set the write interrupt operation. */
371 *operation_ptr = FX_OP_WRITE_INTERRUPT;
372
373 /* Update the flag. */
374 fat_write_interrupt = FX_TRUE;
375
376 /* Clean the callback function. */
377 driver_write_callback = FX_NULL;
378
379 /* Delete the media protection structure if FX_SINGLE_THREAD is not
380 defined. */
381 #ifndef FX_SINGLE_THREAD
382 #ifndef FX_DONT_CREATE_MUTEX
383
384 /* Note that the protection is never released. The mutex delete
385 service will handle all threads waiting access to this media
386 control block. */
387 tx_mutex_delete(&(media_ptr->fx_media_protect));
388 #endif
389 #endif
390
391 /* Clean the media data. */
392 _fx_system_media_opened_ptr = FX_NULL;
393 _fx_system_media_opened_count = 0;
394
395 /* Clean the media. */
396 memset(media_ptr, 0, sizeof(FX_MEDIA));
397
398 /* Simulate poweroff. */
399 /* First terminate the thread to ensure it is ready for deletion. */
400 #ifndef FX_STANDALONE_ENABLE
401 tx_thread_terminate(&ftest_1);
402 #else
403 pthread_cancel(ptid1);
404 #endif
405 }
406
407 /* Return. */
408 return FX_SUCCESS;
409 }
410 #else
411
412 #ifdef CTEST
test_application_define(void * first_unused_memory)413 void test_application_define(void *first_unused_memory)
414 #else
415 void filex_fault_tolerant_file_delete_test_application_define(void *first_unused_memory)
416 #endif
417 {
418
419 FX_PARAMETER_NOT_USED(first_unused_memory);
420
421 /* Print out some test information banners. */
422 printf("FileX Test: Fault Tolerant File Delete Test........................N/A\n");
423
424 test_control_return(255);
425 }
426 #endif
427
428
429