87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package apis
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
dto "github.com/prometheus/client_model/go"
|
|
"github.com/prometheus/common/expfmt"
|
|
"github.com/prometheus/common/model"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
)
|
|
|
|
const zanzanaReconcileLastSuccessMetric = "grafana_zanzana_reconcile_last_success_timestamp_seconds"
|
|
|
|
// AwaitZanzanaReconcileNext waits for a Zanzana reconciliation cycle whose last-success timestamp
|
|
// has been incremented from its current value. This ensures a reconciliation has occurred after
|
|
// this function is called.
|
|
//
|
|
// It is a no-op unless the `zanzana` feature toggle is enabled for the running test env.
|
|
func AwaitZanzanaReconcileNext(t *testing.T, helper *K8sTestHelper) {
|
|
t.Helper()
|
|
|
|
enabled := false
|
|
if helper != nil {
|
|
enabled = helper.GetEnv().FeatureToggles.GetEnabled(context.Background())[featuremgmt.FlagZanzana]
|
|
}
|
|
if helper == nil || !enabled {
|
|
return
|
|
}
|
|
|
|
baselineTimestamp, _ := getZanzanaReconcileLastSuccessTimestampSeconds(t, helper)
|
|
require.EventuallyWithT(t, func(c *assert.CollectT) {
|
|
ts, ok := getZanzanaReconcileLastSuccessTimestampSeconds(t, helper)
|
|
assert.True(c, ok, "expected to find %s in /metrics", zanzanaReconcileLastSuccessMetric)
|
|
if !ok {
|
|
return
|
|
}
|
|
assert.Greater(c, ts, baselineTimestamp, "expected %s (%v) > baseline (%v)", zanzanaReconcileLastSuccessMetric, ts, baselineTimestamp)
|
|
}, 30*time.Second, 50*time.Millisecond)
|
|
}
|
|
|
|
func getZanzanaReconcileLastSuccessTimestampSeconds(t *testing.T, helper *K8sTestHelper) (float64, bool) {
|
|
t.Helper()
|
|
|
|
rsp := DoRequest(helper, RequestParams{
|
|
User: helper.Org1.Admin,
|
|
Path: "/metrics",
|
|
Accept: "text/plain",
|
|
}, &struct{}{})
|
|
if rsp.Response == nil || rsp.Response.StatusCode != http.StatusOK {
|
|
return 0, false
|
|
}
|
|
|
|
parser := expfmt.NewTextParser(model.UTF8Validation)
|
|
metrics, err := parser.TextToMetricFamilies(bytes.NewReader(rsp.Body))
|
|
if err != nil {
|
|
return 0, false
|
|
}
|
|
|
|
metric := metrics[zanzanaReconcileLastSuccessMetric]
|
|
if metric == nil || len(metric.Metric) == 0 {
|
|
return 0, false
|
|
}
|
|
|
|
m := metric.Metric[0]
|
|
switch metric.GetType() {
|
|
case dto.MetricType_GAUGE:
|
|
if m.Gauge == nil {
|
|
return 0, false
|
|
}
|
|
return m.Gauge.GetValue(), true
|
|
case dto.MetricType_UNTYPED:
|
|
if m.Untyped == nil {
|
|
return 0, false
|
|
}
|
|
return m.Untyped.GetValue(), true
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|