From d1d60f7f5efa34b26fa7ff481f966cfd7ca8a18b Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Tue, 27 Jun 2017 19:50:08 -0400 Subject: [PATCH] Have provider constructor take a stop channel This causes the Prometheus provider to take a stop channel as an argument, which allows us to stop the lister (which keeps the series list up to date) in the unit tests. --- cmd/adapter/app/start.go | 2 +- pkg/custom-provider/provider.go | 13 ++++++++----- pkg/custom-provider/provider_test.go | 8 +++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cmd/adapter/app/start.go b/cmd/adapter/app/start.go index df007cd1..8c19ec56 100644 --- a/cmd/adapter/app/start.go +++ b/cmd/adapter/app/start.go @@ -129,7 +129,7 @@ func (o PrometheusAdapterServerOptions) RunCustomMetricsAdapterServer(stopCh <-c instrumentedGenericPromClient := mprom.InstrumentGenericAPIClient(genericPromClient, baseURL.String()) promClient := prom.NewClientForAPI(instrumentedGenericPromClient) - cmProvider := cmprov.NewPrometheusProvider(dynamicMapper, clientPool, promClient, o.MetricsRelistInterval, o.RateInterval) + cmProvider := cmprov.NewPrometheusProvider(dynamicMapper, clientPool, promClient, o.MetricsRelistInterval, o.RateInterval, stopCh) server, err := config.Complete().New(cmProvider) if err != nil { diff --git a/pkg/custom-provider/provider.go b/pkg/custom-provider/provider.go index a6357058..d46d38da 100644 --- a/pkg/custom-provider/provider.go +++ b/pkg/custom-provider/provider.go @@ -75,7 +75,7 @@ type prometheusProvider struct { rateInterval time.Duration } -func NewPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.ClientPool, promClient prom.Client, updateInterval time.Duration, rateInterval time.Duration) provider.CustomMetricsProvider { +func NewPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.ClientPool, promClient prom.Client, updateInterval time.Duration, rateInterval time.Duration, stopChan <-chan struct{}) provider.CustomMetricsProvider { lister := &cachingMetricsLister{ updateInterval: updateInterval, promClient: promClient, @@ -89,8 +89,7 @@ func NewPrometheusProvider(mapper apimeta.RESTMapper, kubeClient dynamic.ClientP }, } - // TODO: allow for RunUntil - lister.Run() + lister.RunUntil(stopChan) return &prometheusProvider{ mapper: mapper, @@ -310,11 +309,15 @@ type cachingMetricsLister struct { } func (l *cachingMetricsLister) Run() { - go wait.Forever(func() { + l.RunUntil(wait.NeverStop) +} + +func (l *cachingMetricsLister) RunUntil(stopChan <-chan struct{}) { + go wait.Until(func() { if err := l.updateMetrics(); err != nil { utilruntime.HandleError(err) } - }, l.updateInterval) + }, l.updateInterval, stopChan) } func (l *cachingMetricsLister) updateMetrics() error { diff --git a/pkg/custom-provider/provider_test.go b/pkg/custom-provider/provider_test.go index 92ef15e1..27c6ceb3 100644 --- a/pkg/custom-provider/provider_test.go +++ b/pkg/custom-provider/provider_test.go @@ -90,11 +90,11 @@ func (c *fakePromClient) QueryRange(_ context.Context, r prom.Range, query prom. return prom.QueryResult{}, nil } -func setupPrometheusProvider(t *testing.T) (provider.CustomMetricsProvider, *fakePromClient) { +func setupPrometheusProvider(t *testing.T, stopCh <-chan struct{}) (provider.CustomMetricsProvider, *fakePromClient) { fakeProm := &fakePromClient{} fakeKubeClient := &fakedyn.FakeClientPool{} - prov := NewPrometheusProvider(api.Registry.RESTMapper(), fakeKubeClient, fakeProm, fakeProviderUpdateInterval, 1*time.Minute) + prov := NewPrometheusProvider(api.Registry.RESTMapper(), fakeKubeClient, fakeProm, fakeProviderUpdateInterval, 1*time.Minute, stopCh) containerSel := prom.MatchSeries("", prom.NameMatches("^container_.*"), prom.LabelNeq("container_name", "POD"), prom.LabelNeq("namespace", ""), prom.LabelNeq("pod_name", "")) namespacedSel := prom.MatchSeries("", prom.LabelNeq("namespace", ""), prom.NameNotMatches("^container_.*")) @@ -134,7 +134,9 @@ func setupPrometheusProvider(t *testing.T) (provider.CustomMetricsProvider, *fak func TestListAllMetrics(t *testing.T) { // setup - prov, fakeProm := setupPrometheusProvider(t) + stopCh := make(chan struct{}) + defer close(stopCh) + prov, fakeProm := setupPrometheusProvider(t, stopCh) // assume we have no updates require.Len(t, prov.ListAllMetrics(), 0, "assume: should have no metrics updates at the start")