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") }