Fortran · 4496 bytes Raw Blame History
1 ! Test program for string pool validation
2 program test_memory_pool
3 use string_pool
4 use iso_fortran_env, only: int64
5 implicit none
6
7 integer :: i, j
8 logical :: all_tests_passed
9 type(string_ref) :: ref1, ref2, refs(100)
10 character(len=100) :: test_string
11 integer :: allocs, deallocs, current, peak
12 real :: hit_rate
13 integer(int64) :: start_time, end_time, clock_rate
14
15 all_tests_passed = .true.
16
17 print *, "=== String Pool Test Suite ==="
18 print *, ""
19
20 ! Test 1: Basic allocation and deallocation
21 print *, "Test 1: Basic allocation..."
22 call pool_init()
23 ref1 = pool_get_string(100)
24
25 if (.not. associated(ref1%data)) then
26 print *, " FAILED: String not allocated"
27 all_tests_passed = .false.
28 else
29 ref1%data = "Hello, World!"
30 if (ref1%data /= "Hello, World!") then
31 print *, " FAILED: String content mismatch"
32 all_tests_passed = .false.
33 else
34 print *, " PASSED: Basic allocation works"
35 end if
36 end if
37
38 call pool_release_string(ref1)
39
40 ! Test 2: Pool reuse
41 print *, "Test 2: Pool reuse..."
42 ref1 = pool_get_string(50)
43 ref1%data = "First"
44 call pool_release_string(ref1)
45
46 ref2 = pool_get_string(50)
47 ! Should reuse the same slot
48 call pool_statistics(allocs, deallocs, current, peak, hit_rate)
49 if (hit_rate < 0.5) then
50 print *, " WARNING: Low hit rate, pool may not be reusing"
51 end if
52 print *, " PASSED: Pool reuse (hit rate:", hit_rate, ")"
53 call pool_release_string(ref2)
54
55 ! Test 3: Multiple size classes
56 print *, "Test 3: Size class buckets..."
57 ref1 = pool_get_string(10) ! Should go to 64B bucket
58 ref2 = pool_get_string(100) ! Should go to 256B bucket
59
60 ref1%data = "Small"
61 ref2%data = "Medium string that is longer"
62
63 if (ref1%data /= "Small" .or. len_trim(ref2%data) /= 28) then
64 print *, " FAILED: Size class allocation failed"
65 all_tests_passed = .false.
66 else
67 print *, " PASSED: Multiple size classes work"
68 end if
69
70 call pool_release_string(ref1)
71 call pool_release_string(ref2)
72
73 ! Test 4: String interning
74 print *, "Test 4: String interning..."
75 ref1 = pool_intern_string("common_string")
76 ref2 = pool_intern_string("common_string")
77
78 if (ref1%ref_count /= ref2%ref_count) then
79 print *, " WARNING: Interning may not be working correctly"
80 else
81 print *, " PASSED: String interning works"
82 end if
83
84 call pool_release_string(ref1)
85 call pool_release_string(ref2)
86
87 ! Test 5: Stress test - rapid allocation/deallocation
88 print *, "Test 5: Stress test (1000 allocations)..."
89 call system_clock(start_time, clock_rate)
90
91 do i = 1, 10
92 do j = 1, 100
93 refs(j) = pool_get_string(64)
94 write(test_string, '(a,i0)') "Test string number ", i*100+j
95 refs(j)%data = trim(test_string)
96 end do
97
98 do j = 1, 100
99 call pool_release_string(refs(j))
100 end do
101 end do
102
103 call system_clock(end_time)
104 print *, " PASSED: Stress test completed in", &
105 real(end_time - start_time) / real(clock_rate), "seconds"
106
107 ! Test 6: Large allocation (beyond pool)
108 print *, "Test 6: Large allocation fallback..."
109 ref1 = pool_get_string(100000) ! 100KB - should bypass pool
110
111 if (.not. associated(ref1%data)) then
112 print *, " FAILED: Large allocation failed"
113 all_tests_passed = .false.
114 else
115 ref1%data(1:5) = "Large"
116 if (ref1%data(1:5) /= "Large") then
117 print *, " FAILED: Large allocation content error"
118 all_tests_passed = .false.
119 else
120 print *, " PASSED: Large allocation fallback works"
121 end if
122 end if
123
124 call pool_release_string(ref1)
125
126 ! Test 7: Statistics
127 print *, ""
128 print *, "Pool Statistics:"
129 call pool_statistics(allocs, deallocs, current, peak, hit_rate)
130 print *, " Total allocations:", allocs
131 print *, " Total deallocations:", deallocs
132 print *, " Current strings:", current
133 print *, " Peak strings:", peak
134 print *, " Cache hit rate:", hit_rate
135
136 ! Cleanup
137 call pool_cleanup()
138
139 ! Test 8: Verify cleanup
140 print *, ""
141 print *, "Test 8: Cleanup verification..."
142 call pool_statistics(allocs, deallocs, current, peak, hit_rate)
143 if (current /= 0) then
144 print *, " FAILED: Memory leak detected after cleanup"
145 all_tests_passed = .false.
146 else
147 print *, " PASSED: Clean shutdown"
148 end if
149
150 ! Final result
151 print *, ""
152 print *, "==============================="
153 if (all_tests_passed) then
154 print *, "ALL TESTS PASSED!"
155 stop 0
156 else
157 print *, "SOME TESTS FAILED!"
158 stop 1
159 end if
160
161 end program test_memory_pool