1
0

searcher_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package searcher
  2. import (
  3. "testing"
  4. "time"
  5. )
  6. // TestOptimizedSearchCache tests the basic functionality of the optimized search cache
  7. func TestOptimizedSearchCache(t *testing.T) {
  8. cache := NewOptimizedSearchCache(100)
  9. defer cache.Close()
  10. req := &SearchRequest{
  11. Query: "test",
  12. Limit: 10,
  13. Offset: 0,
  14. }
  15. result := &SearchResult{
  16. TotalHits: 5,
  17. Hits: []*SearchHit{
  18. {ID: "doc1", Score: 1.0},
  19. {ID: "doc2", Score: 0.9},
  20. },
  21. }
  22. // Test cache miss
  23. cached := cache.Get(req)
  24. if cached != nil {
  25. t.Error("expected cache miss")
  26. }
  27. // Test cache put
  28. cache.Put(req, result, 1*time.Minute)
  29. // Test cache hit
  30. cached = cache.Get(req)
  31. if cached == nil {
  32. t.Error("expected cache hit")
  33. }
  34. if !cached.FromCache {
  35. t.Error("result should be marked as from cache")
  36. }
  37. // Test stats
  38. stats := cache.GetStats()
  39. if stats == nil {
  40. t.Error("stats should not be nil")
  41. }
  42. t.Logf("Cache stats: Size=%d, HitRate=%.2f", stats.Size, stats.HitRate)
  43. }
  44. func TestBasicSearcherConfig(t *testing.T) {
  45. config := DefaultSearcherConfig()
  46. if config.MaxConcurrency <= 0 {
  47. t.Error("MaxConcurrency should be greater than 0")
  48. }
  49. if config.CacheSize <= 0 {
  50. t.Error("CacheSize should be greater than 0")
  51. }
  52. if !config.EnableCache {
  53. t.Error("EnableCache should be true by default")
  54. }
  55. }
  56. func TestQueryBuilderValidation(t *testing.T) {
  57. qb := NewQueryBuilderService()
  58. // Test valid request
  59. validReq := &SearchRequest{
  60. Query: "test",
  61. Limit: 10,
  62. Offset: 0,
  63. }
  64. err := qb.ValidateSearchRequest(validReq)
  65. if err != nil {
  66. t.Errorf("valid request should not have validation error: %v", err)
  67. }
  68. // Test invalid request - negative limit
  69. invalidReq := &SearchRequest{
  70. Limit: -1,
  71. }
  72. err = qb.ValidateSearchRequest(invalidReq)
  73. if err == nil {
  74. t.Error("negative limit should cause validation error")
  75. }
  76. }
  77. func TestQueryBuilderCountriesFilter(t *testing.T) {
  78. qb := NewQueryBuilderService()
  79. tests := []struct {
  80. name string
  81. countries []string
  82. wantError bool
  83. }{
  84. {
  85. name: "single country filter",
  86. countries: []string{"CN"},
  87. wantError: false,
  88. },
  89. {
  90. name: "multiple countries filter",
  91. countries: []string{"CN", "US", "FR"},
  92. wantError: false,
  93. },
  94. {
  95. name: "empty countries filter",
  96. countries: []string{},
  97. wantError: false,
  98. },
  99. {
  100. name: "nil countries filter",
  101. countries: nil,
  102. wantError: false,
  103. },
  104. }
  105. for _, tt := range tests {
  106. t.Run(tt.name, func(t *testing.T) {
  107. req := &SearchRequest{
  108. Query: "",
  109. Countries: tt.countries,
  110. Limit: 10,
  111. Offset: 0,
  112. }
  113. query, err := qb.BuildQuery(req)
  114. if tt.wantError && err == nil {
  115. t.Errorf("expected error but got none")
  116. return
  117. }
  118. if !tt.wantError && err != nil {
  119. t.Errorf("unexpected error: %v", err)
  120. return
  121. }
  122. if !tt.wantError {
  123. if query == nil {
  124. t.Error("query should not be nil")
  125. }
  126. }
  127. })
  128. }
  129. }
  130. func TestSearchRequestDefaults(t *testing.T) {
  131. req := &SearchRequest{}
  132. // These should be the default values
  133. if req.SortOrder == "" {
  134. req.SortOrder = SortOrderDesc // Default sort order
  135. }
  136. if req.Limit == 0 {
  137. req.Limit = 50 // Default limit
  138. }
  139. if req.Timeout == 0 {
  140. req.Timeout = 30 * time.Second // Default timeout
  141. }
  142. // Verify defaults are set
  143. if req.SortOrder != SortOrderDesc {
  144. t.Error("default sort order should be desc")
  145. }
  146. if req.Limit != 50 {
  147. t.Error("default limit should be 50")
  148. }
  149. }
  150. func TestCacheMiddleware(t *testing.T) {
  151. cache := NewOptimizedSearchCache(100)
  152. defer cache.Close()
  153. middleware := NewCacheMiddleware(cache, 5*time.Minute)
  154. if !middleware.IsEnabled() {
  155. t.Error("middleware should be enabled by default")
  156. }
  157. // Disable and test
  158. middleware.Disable()
  159. if middleware.IsEnabled() {
  160. t.Error("middleware should be disabled")
  161. }
  162. // Re-enable
  163. middleware.Enable()
  164. if !middleware.IsEnabled() {
  165. t.Error("middleware should be enabled")
  166. }
  167. }
  168. func TestQueryBuilder(t *testing.T) {
  169. qb := NewQueryBuilderService()
  170. // Test basic query building
  171. req := &SearchRequest{
  172. Query: "test",
  173. IPAddresses: []string{"192.168.1.1"},
  174. StatusCodes: []int{200, 404},
  175. }
  176. query, err := qb.BuildQuery(req)
  177. if err != nil {
  178. t.Errorf("BuildQuery should not error: %v", err)
  179. }
  180. if query == nil {
  181. t.Error("BuildQuery should return a query")
  182. }
  183. }
  184. func TestSuggestionQuery(t *testing.T) {
  185. qb := NewQueryBuilderService()
  186. // Test suggestion query building
  187. query, err := qb.BuildSuggestionQuery("test", "message")
  188. if err != nil {
  189. t.Errorf("BuildSuggestionQuery should not error: %v", err)
  190. }
  191. if query == nil {
  192. t.Error("BuildSuggestionQuery should return a query")
  193. }
  194. // Test empty text
  195. _, err = qb.BuildSuggestionQuery("", "message")
  196. if err == nil {
  197. t.Error("BuildSuggestionQuery should error for empty text")
  198. }
  199. }