diff --git a/exporter_test.go b/exporter_test.go new file mode 100644 index 0000000..82411ed --- /dev/null +++ b/exporter_test.go @@ -0,0 +1,132 @@ +package main + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "testing" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/stretchr/testify/assert" +) + +// Тест: успешное обновление метрик через /update +func TestJSONHandler_ValidRequest(t *testing.T) { + exporter := NewMetricsExporter() + server := httptest.NewServer(http.HandlerFunc(exporter.JSONHandler)) + defer server.Close() + + // JSON-запрос + requestData := MetricRequest{ + ID: "test_api", + Name: "Test API", + URL: "http://localhost/api", + Method: "GET", + Type: "gauge", + Metrics: map[string]float64{ + "response_time": 200.5, + }, + } + + // Маршалим JSON и проверяем ошибку + jsonData, err := json.Marshal(requestData) + assert.NoError(t, err, "Ошибка при маршалинге JSON") + + // Отправляем запрос + resp, err := http.Post(server.URL, "application/json", bytes.NewBuffer(jsonData)) + assert.NoError(t, err, "Ошибка при отправке запроса на /update") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + // Проверяем тело ответа + body, err := io.ReadAll(resp.Body) + assert.NoError(t, err, "Ошибка чтения тела ответа") + assert.Equal(t, "Metrics updated", string(body)) +} + +// Тест: успешная обработка некорректного JSON +func TestJSONHandler_InvalidJSON(t *testing.T) { + exporter := NewMetricsExporter() + server := httptest.NewServer(http.HandlerFunc(exporter.JSONHandler)) + defer server.Close() + + // Отправляем некорректный JSON + resp, err := http.Post(server.URL, "application/json", bytes.NewBuffer([]byte("{invalid json}"))) + assert.NoError(t, err) + assert.Equal(t, http.StatusBadRequest, resp.StatusCode) +} + +// Тест: проверка создания и обновления Gauge метрики +func TestUpdateMetric_Gauge(t *testing.T) { + exporter := NewMetricsExporter() + + request := MetricRequest{ + ID: "test", + Name: "Test Gauge", + URL: "http://test.com", + Method: "GET", + Type: "gauge", + Metrics: map[string]float64{ + "load": 75.5, + }, + } + + // Вызываем обновление метрики + exporter.UpdateMetric(request) + + // Проверяем, что метрика существует + metric, exists := exporter.gaugeMetrics["vks_test_load"] + assert.True(t, exists, "Метрика должна быть зарегистрирована") + assert.NotNil(t, metric, "Метрика не должна быть nil") +} + +// Тест: проверка создания и увеличения Counter метрики +func TestUpdateMetric_Counter(t *testing.T) { + exporter := NewMetricsExporter() + + request := MetricRequest{ + ID: "test", + Name: "Test Counter", + URL: "http://test.com", + Method: "POST", + Type: "counter", + Metrics: map[string]float64{ + "requests": 1, + }, + } + + // Вызываем обновление метрики дважды + exporter.UpdateMetric(request) + exporter.UpdateMetric(request) + + // Проверяем, что метрика существует + metric, exists := exporter.counterMetrics["vks_test_requests"] + assert.True(t, exists, "Метрика должна быть зарегистрирована") + assert.NotNil(t, metric, "Метрика не должна быть nil") +} + +// Тест: получение метрик по /metrics +func TestMetricsEndpoint(t *testing.T) { + // Регистрируем метрику + gauge := prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "test_metric", + Help: "Test metric for /metrics endpoint", + }) + customRegistry.MustRegister(gauge) + gauge.Set(50.5) + + server := httptest.NewServer(promhttp.HandlerFor(customRegistry, promhttp.HandlerOpts{})) + defer server.Close() + + // Делаем GET-запрос к /metrics + resp, err := http.Get(server.URL) + assert.NoError(t, err, "Ошибка при запросе к /metrics") + assert.Equal(t, http.StatusOK, resp.StatusCode) + + // Проверяем, что в ответе есть test_metric + body, err := io.ReadAll(resp.Body) + assert.NoError(t, err, "Ошибка чтения тела ответа") + assert.Contains(t, string(body), "test_metric") +} diff --git a/go.mod b/go.mod index a1a517a..01d5b40 100644 --- a/go.mod +++ b/go.mod @@ -2,16 +2,23 @@ module exporter go 1.23.5 -require github.com/prometheus/client_golang v1.20.5 +require ( + github.com/prometheus/client_golang v1.20.5 + github.com/stretchr/testify v1.9.0 +) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/kr/text v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect golang.org/x/sys v0.22.0 // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d5318cf..253bc52 100644 --- a/go.sum +++ b/go.sum @@ -2,14 +2,23 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= @@ -18,7 +27,16 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 8f23270..b692611 100644 --- a/main.go +++ b/main.go @@ -199,4 +199,4 @@ func main() { } } -//TODO: сделать переменные окружения, настроить канал, сделать тесты +//TODO: сделать переменные окружения, настроить канал, дописать тесты diff --git a/test_api.txt b/test_api.txt new file mode 100644 index 0000000..e4c2e7f --- /dev/null +++ b/test_api.txt @@ -0,0 +1,12 @@ +curl -X POST -H "Content-Type: application/json" -d '{ + "id": "gauge_test", + "name": "Gauge Metric", + "url": "http://127.0.0.1:8081/gauge", + "method": "GET", + "type": "gauge", + "metrics": { + "temperature": 36.6 + } +}' "http://localhost:9101/update" + +curl http://localhost:9101/metrics \ No newline at end of file diff --git a/test_data.txt b/test_data.txt deleted file mode 100644 index e87b3a2..0000000 --- a/test_data.txt +++ /dev/null @@ -1,11 +0,0 @@ -curl -X POST -H "Content-Type: application/json" -d '{ - "id": "mock_api_2", - "name": "Mock /ping", - "url": "http://127.0.0.1:8081/ping", - "method": "GET", - "type": "gauge", - "metrics": { - "response_time": 120.5, - "status_code": 200 - } -}' http://localhost:9101/update