1
0

statistic_test.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package statistic_test
  2. import (
  3. "net"
  4. "os"
  5. "testing"
  6. "time"
  7. "math/rand"
  8. "imuslab.com/zoraxy/mod/database"
  9. "imuslab.com/zoraxy/mod/database/dbinc"
  10. "imuslab.com/zoraxy/mod/geodb"
  11. "imuslab.com/zoraxy/mod/statistic"
  12. )
  13. const test_db_path = "test_db"
  14. func getNewDatabase() *database.Database {
  15. db, err := database.NewDatabase(test_db_path, dbinc.BackendLevelDB)
  16. if err != nil {
  17. panic(err)
  18. }
  19. db.NewTable("stats")
  20. return db
  21. }
  22. func clearDatabase(db *database.Database) {
  23. db.Close()
  24. os.RemoveAll(test_db_path)
  25. }
  26. func TestNewStatisticCollector(t *testing.T) {
  27. db := getNewDatabase()
  28. defer clearDatabase(db)
  29. option := statistic.CollectorOption{Database: db}
  30. collector, err := statistic.NewStatisticCollector(option)
  31. if err != nil {
  32. t.Fatalf("Expected no error, got %v", err)
  33. }
  34. if collector == nil {
  35. t.Fatalf("Expected collector, got nil")
  36. }
  37. }
  38. func TestSaveSummaryOfDay(t *testing.T) {
  39. db := getNewDatabase()
  40. defer clearDatabase(db)
  41. option := statistic.CollectorOption{Database: db}
  42. collector, _ := statistic.NewStatisticCollector(option)
  43. collector.SaveSummaryOfDay()
  44. // Add assertions to check if data is saved correctly
  45. }
  46. func TestLoadSummaryOfDay(t *testing.T) {
  47. db := getNewDatabase()
  48. defer clearDatabase(db)
  49. option := statistic.CollectorOption{Database: db}
  50. collector, _ := statistic.NewStatisticCollector(option)
  51. year, month, day := time.Now().Date()
  52. summary := collector.LoadSummaryOfDay(year, month, day)
  53. if summary == nil {
  54. t.Fatalf("Expected summary, got nil")
  55. }
  56. }
  57. func TestResetSummaryOfDay(t *testing.T) {
  58. db := getNewDatabase()
  59. defer clearDatabase(db)
  60. option := statistic.CollectorOption{Database: db}
  61. collector, _ := statistic.NewStatisticCollector(option)
  62. collector.ResetSummaryOfDay()
  63. if collector.DailySummary.TotalRequest != 0 {
  64. t.Fatalf("Expected TotalRequest to be 0, got %v", collector.DailySummary.TotalRequest)
  65. }
  66. }
  67. func TestGetCurrentRealtimeStatIntervalId(t *testing.T) {
  68. db := getNewDatabase()
  69. defer clearDatabase(db)
  70. option := statistic.CollectorOption{Database: db}
  71. collector, _ := statistic.NewStatisticCollector(option)
  72. intervalId := collector.GetCurrentRealtimeStatIntervalId()
  73. if intervalId < 0 || intervalId > 287 {
  74. t.Fatalf("Expected intervalId to be between 0 and 287, got %v", intervalId)
  75. }
  76. }
  77. func TestRecordRequest(t *testing.T) {
  78. db := getNewDatabase()
  79. defer clearDatabase(db)
  80. option := statistic.CollectorOption{Database: db}
  81. collector, _ := statistic.NewStatisticCollector(option)
  82. requestInfo := statistic.RequestInfo{
  83. IpAddr: "127.0.0.1",
  84. RequestOriginalCountryISOCode: "US",
  85. Succ: true,
  86. StatusCode: 200,
  87. ForwardType: "type1",
  88. Referer: "http://example.com",
  89. UserAgent: "Mozilla/5.0",
  90. RequestURL: "/test",
  91. Target: "target1",
  92. }
  93. collector.RecordRequest(requestInfo)
  94. time.Sleep(1 * time.Second) // Wait for the goroutine to finish
  95. if collector.DailySummary.TotalRequest != 1 {
  96. t.Fatalf("Expected TotalRequest to be 1, got %v", collector.DailySummary.TotalRequest)
  97. }
  98. }
  99. func TestScheduleResetRealtimeStats(t *testing.T) {
  100. db := getNewDatabase()
  101. defer clearDatabase(db)
  102. option := statistic.CollectorOption{Database: db}
  103. collector, _ := statistic.NewStatisticCollector(option)
  104. stopChan := collector.ScheduleResetRealtimeStats()
  105. if stopChan == nil {
  106. t.Fatalf("Expected stopChan, got nil")
  107. }
  108. collector.Close()
  109. }
  110. func TestNewDailySummary(t *testing.T) {
  111. summary := statistic.NewDailySummary()
  112. if summary.TotalRequest != 0 {
  113. t.Fatalf("Expected TotalRequest to be 0, got %v", summary.TotalRequest)
  114. }
  115. if summary.ForwardTypes == nil {
  116. t.Fatalf("Expected ForwardTypes to be initialized, got nil")
  117. }
  118. if summary.RequestOrigin == nil {
  119. t.Fatalf("Expected RequestOrigin to be initialized, got nil")
  120. }
  121. if summary.RequestClientIp == nil {
  122. t.Fatalf("Expected RequestClientIp to be initialized, got nil")
  123. }
  124. if summary.Referer == nil {
  125. t.Fatalf("Expected Referer to be initialized, got nil")
  126. }
  127. if summary.UserAgent == nil {
  128. t.Fatalf("Expected UserAgent to be initialized, got nil")
  129. }
  130. if summary.RequestURL == nil {
  131. t.Fatalf("Expected RequestURL to be initialized, got nil")
  132. }
  133. }
  134. func generateTestRequestInfo(db *database.Database) statistic.RequestInfo {
  135. //Generate a random IPv4 address
  136. randomIpAddr := ""
  137. for {
  138. ip := net.IPv4(byte(rand.Intn(256)), byte(rand.Intn(256)), byte(rand.Intn(256)), byte(rand.Intn(256)))
  139. if !ip.IsPrivate() && !ip.IsLoopback() && !ip.IsMulticast() && !ip.IsUnspecified() {
  140. randomIpAddr = ip.String()
  141. break
  142. }
  143. }
  144. //Resolve the country code for this IP
  145. ipLocation := "unknown"
  146. geoIpResolver, err := geodb.NewGeoDb(db, &geodb.StoreOptions{
  147. AllowSlowIpv4LookUp: false,
  148. AllowSlowIpv6Lookup: true, //Just to save some RAM
  149. })
  150. if err == nil {
  151. ipInfo, _ := geoIpResolver.ResolveCountryCodeFromIP(randomIpAddr)
  152. ipLocation = ipInfo.CountryIsoCode
  153. }
  154. forwardType := "host-http"
  155. //Generate a random forward type between "subdomain-http" and "host-https"
  156. if rand.Intn(2) == 1 {
  157. forwardType = "subdomain-http"
  158. }
  159. //Generate 5 random refers URL and pick from there
  160. referers := []string{"https://example.com", "https://example.org", "https://example.net", "https://example.io", "https://example.co"}
  161. referer := referers[rand.Intn(5)]
  162. return statistic.RequestInfo{
  163. IpAddr: randomIpAddr,
  164. RequestOriginalCountryISOCode: ipLocation,
  165. Succ: true,
  166. StatusCode: 200,
  167. ForwardType: forwardType,
  168. Referer: referer,
  169. UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
  170. RequestURL: "/benchmark",
  171. Target: "test.imuslab.internal",
  172. }
  173. }
  174. func BenchmarkRecordRequest(b *testing.B) {
  175. db := getNewDatabase()
  176. defer clearDatabase(db)
  177. option := statistic.CollectorOption{Database: db}
  178. collector, _ := statistic.NewStatisticCollector(option)
  179. var requestInfo statistic.RequestInfo = generateTestRequestInfo(db)
  180. b.ResetTimer()
  181. for i := 0; i < b.N; i++ {
  182. collector.RecordRequest(requestInfo)
  183. collector.SaveSummaryOfDay()
  184. }
  185. //Write the current in-memory summary to database file
  186. b.StopTimer()
  187. //Print the generated summary
  188. //testSummary := collector.GetCurrentDailySummary()
  189. //statistic.PrintDailySummary(testSummary)
  190. }