package boomer import ( "testing" ) func TestLogRequest(t *testing.T) { newStats := newRequestStats() newStats.logRequest("http", "success", 2, 30) newStats.logRequest("http", "success", 3, 40) newStats.logRequest("http", "success", 2, 40) newStats.logRequest("http", "success", 1, 20) entry := newStats.get("success", "http") if entry.NumRequests != 4 { t.Error("numRequests is wrong, expected: 4, got:", entry.NumRequests) } if entry.MinResponseTime != 1 { t.Error("minResponseTime is wrong, expected: 1, got:", entry.MinResponseTime) } if entry.MaxResponseTime != 3 { t.Error("maxResponseTime is wrong, expected: 3, got:", entry.MaxResponseTime) } if entry.TotalResponseTime != 8 { t.Error("totalResponseTime is wrong, expected: 8, got:", entry.TotalResponseTime) } if entry.TotalContentLength != 130 { t.Error("totalContentLength is wrong, expected: 130, got:", entry.TotalContentLength) } // check newStats.total if newStats.total.NumRequests != 4 { t.Error("newStats.total.numRequests is wrong, expected: 4, got:", newStats.total.NumRequests) } if newStats.total.MinResponseTime != 1 { t.Error("newStats.total.minResponseTime is wrong, expected: 1, got:", newStats.total.MinResponseTime) } if newStats.total.MaxResponseTime != 3 { t.Error("newStats.total.maxResponseTime is wrong, expected: 3, got:", newStats.total.MaxResponseTime) } if newStats.total.TotalResponseTime != 8 { t.Error("newStats.total.totalResponseTime is wrong, expected: 8, got:", newStats.total.TotalResponseTime) } if newStats.total.TotalContentLength != 130 { t.Error("newStats.total.totalContentLength is wrong, expected: 130, got:", newStats.total.TotalContentLength) } } func BenchmarkLogRequest(b *testing.B) { newStats := newRequestStats() for i := 0; i < b.N; i++ { newStats.logRequest("http", "success", 2, 30) } } func TestRoundedResponseTime(t *testing.T) { newStats := newRequestStats() newStats.logRequest("http", "success", 147, 1) newStats.logRequest("http", "success", 3432, 1) newStats.logRequest("http", "success", 58760, 1) entry := newStats.get("success", "http") responseTimes := entry.ResponseTimes if len(responseTimes) != 3 { t.Error("len(responseTimes) is wrong, expected: 3, got:", len(responseTimes)) } if val, ok := responseTimes[150]; !ok || val != 1 { t.Error("Rounded response time should be", 150) } if val, ok := responseTimes[3400]; !ok || val != 1 { t.Error("Rounded response time should be", 3400) } if val, ok := responseTimes[59000]; !ok || val != 1 { t.Error("Rounded response time should be", 59000) } } func TestLogError(t *testing.T) { newStats := newRequestStats() newStats.logError("http", "failure", "500 error") newStats.logError("http", "failure", "400 error") newStats.logError("http", "failure", "400 error") entry := newStats.get("failure", "http") if entry.NumFailures != 3 { t.Error("numFailures is wrong, expected: 3, got:", entry.NumFailures) } if newStats.total.NumFailures != 3 { t.Error("newStats.total.numFailures is wrong, expected: 3, got:", newStats.total.NumFailures) } // md5("httpfailure500 error") = 547c38e4e4742c1c581f9e2809ba4f55 err500 := newStats.errors["547c38e4e4742c1c581f9e2809ba4f55"] if err500.errMsg != "500 error" { t.Error("Error message is wrong, expected: 500 error, got:", err500.errMsg) } if err500.occurrences != 1 { t.Error("Error occurrences is wrong, expected: 1, got:", err500.occurrences) } // md5("httpfailure400 error") = f391c310401ad8e10e929f2ee1a614e4 err400 := newStats.errors["f391c310401ad8e10e929f2ee1a614e4"] if err400.errMsg != "400 error" { t.Error("Error message is wrong, expected: 400 error, got:", err400.errMsg) } if err400.occurrences != 2 { t.Error("Error occurrences is wrong, expected: 2, got:", err400.occurrences) } } func BenchmarkLogError(b *testing.B) { newStats := newRequestStats() for i := 0; i < b.N; i++ { // LogError use md5 to calculate hash keys, it may slow down the only goroutine, // which consumes both requestSuccessChannel and requestFailureChannel. newStats.logError("http", "failure", "500 error") } } func TestClearAll(t *testing.T) { newStats := newRequestStats() newStats.logRequest("http", "success", 1, 20) newStats.clearAll() if newStats.total.NumRequests != 0 { t.Error("After clearAll(), newStats.total.numRequests is wrong, expected: 0, got:", newStats.total.NumRequests) } } func TestClearAllByChannel(t *testing.T) { newStats := newRequestStats() newStats.logRequest("http", "success", 1, 20) newStats.clearAll() if newStats.total.NumRequests != 0 { t.Error("After clearAll(), newStats.total.numRequests is wrong, expected: 0, got:", newStats.total.NumRequests) } } func TestSerializeStats(t *testing.T) { newStats := newRequestStats() newStats.logRequest("http", "success", 1, 20) serialized := newStats.serializeStats() if len(serialized) != 1 { t.Error("The length of serialized results is wrong, expected: 1, got:", len(serialized)) return } first := serialized[0] entry, err := deserializeStatsEntry(first) if err != nil { t.Fail() } if entry.Name != "success" { t.Error("The name is wrong, expected:", "success", "got:", entry.Name) } if entry.Method != "http" { t.Error("The method is wrong, expected:", "http", "got:", entry.Method) } if entry.NumRequests != int64(1) { t.Error("The num_requests is wrong, expected:", 1, "got:", entry.NumRequests) } if entry.NumFailures != int64(0) { t.Error("The num_failures is wrong, expected:", 0, "got:", entry.NumFailures) } } func TestSerializeErrors(t *testing.T) { newStats := newRequestStats() newStats.logError("http", "failure", "500 error") newStats.logError("http", "failure", "400 error") newStats.logError("http", "failure", "400 error") serialized := newStats.serializeErrors() if len(serialized) != 2 { t.Error("The length of serialized results is wrong, expected: 2, got:", len(serialized)) return } for key, value := range serialized { if key == "f391c310401ad8e10e929f2ee1a614e4" { err := value["error"].(string) if err != "400 error" { t.Error("expected: 400 error, got:", err) } occurrences := value["occurrences"].(int64) if occurrences != int64(2) { t.Error("expected: 2, got:", occurrences) } } } } func TestCollectReportData(t *testing.T) { newStats := newRequestStats() newStats.logRequest("http", "success", 2, 30) newStats.logError("http", "failure", "500 error") result := newStats.collectReportData() if _, ok := result["stats"]; !ok { t.Error("Key stats not found") } if _, ok := result["stats_total"]; !ok { t.Error("Key stats not found") } if _, ok := result["errors"]; !ok { t.Error("Key stats not found") } }