Fortran · 6624 bytes Raw Blame History
1 ! ==============================================================================
2 ! Test program for Phase 6 - Parser with memory pooling
3 ! ==============================================================================
4 program test_parser_pooled
5 use string_pool
6 use memory_dashboard
7 use pooled_types
8 use parser_pooled
9 use iso_fortran_env, only: output_unit
10 implicit none
11
12 type(pooled_pipeline_t) :: pipeline
13 type(pooled_command_t) :: test_cmd
14 integer :: i, j
15 character(len=256) :: test_commands(10)
16 logical :: test_passed
17 integer :: total_allocs, total_deallocs, current_strings, peak_strings
18 real :: hit_rate
19 character(:), pointer :: token_ptr
20
21 test_passed = .true.
22
23 print *, "=== Phase 6 Parser Memory Pooling Test Suite ==="
24 print *, "Testing parser module with zero-copy memory pooling"
25 print *
26
27 ! Initialize the pool and dashboard
28 call pool_init()
29 call dashboard_init(verbose=.false.)
30
31 ! Define test commands
32 test_commands(1) = "ls -la /tmp"
33 test_commands(2) = "echo 'Hello World'"
34 test_commands(3) = "cat file.txt | grep pattern"
35 test_commands(4) = "export VAR=value && echo $VAR"
36 test_commands(5) = "for i in 1 2 3; do echo $i; done"
37 test_commands(6) = "if [ -f file ]; then echo exists; fi"
38 test_commands(7) = "command1 > output.txt 2>&1"
39 test_commands(8) = "cat << EOF > file.txt"
40 test_commands(9) = "function test() { echo test; }"
41 test_commands(10) = "ls -la | head -n 10 | tail -n 5"
42
43 ! Test 1: Parse simple commands
44 print *, "Test 1: Parsing simple commands with pooled memory..."
45 do i = 1, 3
46 print *, " Parsing: ", trim(test_commands(i))
47 call parse_pipeline_pooled(test_commands(i), pipeline)
48
49 if (pipeline%num_commands > 0) then
50 print *, " Commands parsed:", pipeline%num_commands
51 do j = 1, pipeline%commands(1)%num_tokens
52 token_ptr => get_pooled_token(pipeline%commands(1), j)
53 if (associated(token_ptr)) then
54 print *, " Token", j, ":", trim(token_ptr)
55 end if
56 end do
57 else
58 print *, " FAILED: No commands parsed"
59 test_passed = .false.
60 end if
61
62 call release_pipeline_pooled(pipeline)
63 end do
64
65 ! Test 2: Check memory statistics
66 print *, ""
67 print *, "Test 2: Checking parser memory statistics..."
68 call pool_statistics(total_allocs, total_deallocs, current_strings, peak_strings, hit_rate)
69 print *, " Total allocations:", total_allocs
70 print *, " Total deallocations:", total_deallocs
71 print *, " Current strings:", current_strings
72 print *, " Peak strings:", peak_strings
73
74 if (current_strings == 0) then
75 print *, " PASSED: No memory leaks (all strings released)"
76 else
77 print *, " WARNING:", current_strings, "strings still allocated"
78 end if
79
80 ! Test 3: Parse complex commands
81 print *, ""
82 print *, "Test 3: Parsing complex commands..."
83 do i = 4, 7
84 print *, " Parsing: ", trim(test_commands(i))
85 call parse_pipeline_pooled(test_commands(i), pipeline)
86
87 if (pipeline%num_commands > 0) then
88 print *, " Commands in pipeline:", pipeline%num_commands
89 ! Check redirections
90 if (i == 7) then ! command1 > output.txt 2>&1
91 if (pipeline%commands(1)%output_file%pool_index /= 0) then
92 print *, " Output redirection detected"
93 end if
94 end if
95 end if
96
97 call release_pipeline_pooled(pipeline)
98 end do
99
100 ! Test 4: Stress test with rapid allocations
101 print *, ""
102 print *, "Test 4: Stress testing parser with rapid operations..."
103 do j = 1, 100
104 do i = 1, 10
105 call parse_pipeline_pooled(test_commands(mod(i-1, 10) + 1), pipeline)
106 call release_pipeline_pooled(pipeline)
107 end do
108 end do
109 print *, " Completed 1000 parse/release cycles"
110
111 ! Test 5: Test direct pooled command operations
112 print *, ""
113 print *, "Test 5: Testing pooled command operations..."
114 call init_pooled_command(test_cmd)
115
116 ! Allocate and set tokens
117 call allocate_pooled_tokens(test_cmd, 5, 64)
118 call set_pooled_token(test_cmd, 1, "test")
119 call set_pooled_token(test_cmd, 2, "-flag")
120 call set_pooled_token(test_cmd, 3, "arg1")
121 call set_pooled_token(test_cmd, 4, "arg2")
122 call set_pooled_token(test_cmd, 5, "arg3")
123
124 ! Set some string fields
125 call set_pooled_string(test_cmd%input_file, "input.txt")
126 call set_pooled_string(test_cmd%output_file, "output.txt")
127 call set_pooled_string(test_cmd%heredoc_delimiter, "EOF")
128
129 ! Verify values
130 token_ptr => get_pooled_token(test_cmd, 1)
131 if (associated(token_ptr) .and. trim(token_ptr) == "test") then
132 print *, " PASSED: Token storage working"
133 else
134 print *, " FAILED: Token storage not working"
135 test_passed = .false.
136 end if
137
138 token_ptr => get_pooled_string(test_cmd%output_file)
139 if (associated(token_ptr) .and. trim(token_ptr) == "output.txt") then
140 print *, " PASSED: String field storage working"
141 else
142 print *, " FAILED: String field storage not working"
143 test_passed = .false.
144 end if
145
146 ! Clean up test command
147 call release_pooled_command(test_cmd)
148
149 ! Display dashboard
150 print *, ""
151 print *, "=== Parser Module Statistics ==="
152 call dashboard_display(detailed=.true.)
153
154 ! Final statistics
155 print *, ""
156 print *, "=== Final Memory Check ==="
157 call pool_statistics(total_allocs, total_deallocs, current_strings, peak_strings, hit_rate)
158 print *, "Total allocations:", total_allocs
159 print *, "Total deallocations:", total_deallocs
160 print *, "Leaked strings:", current_strings
161 print *, "Peak usage:", peak_strings
162 print *, "Cache hit rate:", int(hit_rate * 100), "%"
163
164 ! Export statistics
165 call dashboard_export_csv("parser_memory_stats.csv")
166 print *, ""
167 print *, "Statistics exported to parser_memory_stats.csv"
168
169 ! Clean up
170 call dashboard_cleanup()
171 call pool_cleanup()
172
173 ! Summary
174 print *, ""
175 if (test_passed .and. current_strings == 0) then
176 print *, "=== ALL TESTS PASSED ==="
177 print *, "Parser successfully integrated with memory pooling!"
178 print *, ""
179 print *, "Key achievements:"
180 print *, " ✓ Zero-copy string storage for tokens"
181 print *, " ✓ Pooled memory for all parser strings"
182 print *, " ✓ Dashboard tracking integration"
183 print *, " ✓ No memory leaks detected"
184 print *, " ✓ Cache hit rate:", int(hit_rate * 100), "%"
185 print *, ""
186 print *, "The parser module is now using pooled memory efficiently!"
187 else
188 print *, "=== SOME TESTS FAILED ==="
189 if (current_strings > 0) then
190 print *, "Memory leak detected:", current_strings, "strings not released"
191 end if
192 print *, "Please review the implementation"
193 end if
194
195 end program test_parser_pooled