|
1 | 1 | package analyticsservice
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "fmt" |
4 | 5 | "reflect"
|
5 | 6 | "sync"
|
6 | 7 | "testing"
|
@@ -81,13 +82,94 @@ func TestSafeTargetAnalytics(t *testing.T) {
|
81 | 82 | }
|
82 | 83 |
|
83 | 84 | func TestSafeSeenTargets(t *testing.T) {
|
84 |
| - s := newSafeSeenTargets() |
| 85 | + // Initialize with a small maxSize for testing |
| 86 | + maxSize := 3 |
| 87 | + s := newSafeSeenTargets(maxSize, 0).(SafeSeenTargetsCache[string, bool]) |
| 88 | + |
85 | 89 | testData := map[string]bool{
|
86 | 90 | "target1": true,
|
87 | 91 | "target21": true,
|
88 | 92 | "target3": true,
|
89 |
| - "target4": true, |
90 | 93 | }
|
91 | 94 |
|
92 |
| - testMapOperations[string, bool](t, s, testData) |
| 95 | + // Insert items and ensure limit is not exceeded |
| 96 | + for key, value := range testData { |
| 97 | + s.set(key, value) |
| 98 | + } |
| 99 | + |
| 100 | + if s.isLimitExceeded() { |
| 101 | + t.Errorf("Limit should not have been exceeded yet") |
| 102 | + } |
| 103 | + |
| 104 | + // Add one more item to exceed the limit |
| 105 | + s.setWithLimit("target4", true) |
| 106 | + |
| 107 | + // Ensure limitExceeded is true after exceeding the limit |
| 108 | + if !s.isLimitExceeded() { |
| 109 | + t.Errorf("Limit should be exceeded after adding target4") |
| 110 | + } |
| 111 | + |
| 112 | + // Ensure that new items are not added once the limit is exceeded |
| 113 | + s.setWithLimit("target5", true) |
| 114 | + if _, exists := s.get("target5"); exists { |
| 115 | + t.Errorf("target5 should not have been added as the limit was exceeded") |
| 116 | + } |
| 117 | + |
| 118 | + // Clear the map and ensure limit is reset |
| 119 | + s.clear() |
| 120 | + |
| 121 | + if s.isLimitExceeded() { |
| 122 | + t.Errorf("Limit should have been reset after clearing the map") |
| 123 | + } |
| 124 | + |
| 125 | + // Add items again after clearing |
| 126 | + s.setWithLimit("target6", true) |
| 127 | + if _, exists := s.get("target6"); !exists { |
| 128 | + t.Errorf("target6 should have been added after clearing the map") |
| 129 | + } |
| 130 | + |
| 131 | + // Concurrency test |
| 132 | + t.Run("ConcurrencyTest", func(t *testing.T) { |
| 133 | + var wg sync.WaitGroup |
| 134 | + concurrencyLevel := 100 |
| 135 | + |
| 136 | + // Re-initialize the map for concurrency testing |
| 137 | + s = newSafeSeenTargets(100, 0).(SafeSeenTargetsCache[string, bool]) |
| 138 | + |
| 139 | + // Concurrently set keys |
| 140 | + for i := 0; i < concurrencyLevel; i++ { |
| 141 | + wg.Add(1) |
| 142 | + go func(i int) { |
| 143 | + defer wg.Done() |
| 144 | + key := "target" + fmt.Sprint(i) |
| 145 | + s.setWithLimit(key, true) |
| 146 | + }(i) |
| 147 | + } |
| 148 | + |
| 149 | + // Concurrently get keys |
| 150 | + for i := 0; i < concurrencyLevel; i++ { |
| 151 | + wg.Add(1) |
| 152 | + go func(i int) { |
| 153 | + defer wg.Done() |
| 154 | + key := "target" + fmt.Sprint(i) |
| 155 | + s.get(key) |
| 156 | + }(i) |
| 157 | + } |
| 158 | + |
| 159 | + // Concurrently clear the map |
| 160 | + for i := 0; i < concurrencyLevel/2; i++ { |
| 161 | + wg.Add(1) |
| 162 | + go func() { |
| 163 | + defer wg.Done() |
| 164 | + s.clear() |
| 165 | + }() |
| 166 | + } |
| 167 | + |
| 168 | + wg.Wait() |
| 169 | + |
| 170 | + // Ensure the map is cleared after the concurrency operations |
| 171 | + if s.size() > 0 { |
| 172 | + t.Errorf("Map size should be 0 after clearing, got %d", s.size()) |
| 173 | + } |
| 174 | + }) |
93 | 175 | }
|
0 commit comments