Repository: prometheus/prometheus
File: scrape/manager_test.go (Go)

Code before:
			return nil
		}
		return errors.New("expected histogram samples, got none")
	}), "after 1 minute")

	// Verify that samples were ingested (proving both features work together).
	app.mtx.Lock()
	defer app.mtx.Unlock()

	var got []histogramSample
	for _, h := range app.resultHistograms {
		if h.metric.Get(model.MetricNameLabel) == mName {
			got = append(got, h)
		}
	}

	// With CT zero ingestion enabled and a created timestamp present, we expect 2 samples:
	// one zero sample and one actual sample.
	require.Len(t, got, 2, "expected 2 histogram samples (zero sample + actual sample)")
	require.Equal(t, histogram.Histogram{}, *got[0].h, "first sample should be zero sample")
	require.NotEqual(t, 0.0, got[1].h.Sum, "second sample should have non-zero sum")

	// The test successfully completes, proving that both ConvertClassicHistogramsToNHCBEnabled
	// and EnableCreatedTimestampZeroIngestion can work together without the error that was
	// previously thrown. The original issue #15137 about losing exemplars during CT parsing
	// in OpenMetrics format has been fixed independently in the parser layer.
}

func applyConfig(
	t *testing.T,
	config string,
	scrapeManager *Manager,
	discoveryManager *discovery.Manager,
) {
	t.Helper()

	cfg := loadConfiguration(t, config)
	require.NoError(t, scrapeManager.ApplyConfig(cfg))

	c := make(map[string]discovery.Configs)
	scfgs, err := cfg.GetScrapeConfigs()
	require.NoError(t, err)
	for _, v := range scfgs {
		c[v.JobName] = v.ServiceDiscoveryConfigs
	}
	require.NoError(t, discoveryManager.ApplyConfig(c))
}

func runManagers(t *testing.T, ctx context.Context, opts *Options, app storage.Appendable) (*discovery.Manager, *Manager) {
	t.Helper()


Review comment (suggestion):
I feel this is redundant, let's remove it.
```suggestion
```

Code after:
		defer scrapeManager.mtxScrape.Unlock()
		_, exists := scrapeManager.scrapePools["test"]
		return exists
	}, 5*time.Second, 100*time.Millisecond, "scrape pool should be created for job 'test'")

	// Helper function to get matching histograms to avoid race conditions.
	getMatchingHistograms := func() []histogramSample {
		app.mtx.Lock()
		defer app.mtx.Unlock()

		var got []histogramSample
		for _, h := range app.resultHistograms {
			if h.metric.Get(model.MetricNameLabel) == mName {
				got = append(got, h)
			}
		}
		return got
	}

	require.Eventually(t, func() bool {
		return len(getMatchingHistograms()) > 0
	}, 1*time.Minute, 100*time.Millisecond, "expected histogram samples, got none")

	// Verify that samples were ingested (proving both features work together).
	got := getMatchingHistograms()

	// With CT zero ingestion enabled and a created timestamp present, we expect 2 samples:
	// one zero sample and one actual sample.
	require.Len(t, got, 2, "expected 2 histogram samples (zero sample + actual sample)")
	require.Equal(t, histogram.Histogram{}, *got[0].h, "first sample should be zero sample")
	require.InDelta(t, expectedHistogramSum, got[1].h.Sum, 1e-9, "second sample should retain the expected sum")
	require.Len(t, app.resultExemplars, 2, "expected 2 exemplars from histogram buckets")
}

func applyConfig(
	t *testing.T,
	config string,
	scrapeManager *Manager,
	discoveryManager *discovery.Manager,
) {
	t.Helper()

	cfg := loadConfiguration(t, config)
	require.NoError(t, scrapeManager.ApplyConfig(cfg))

	c := make(map[string]discovery.Configs)
	scfgs, err := cfg.GetScrapeConfigs()
	require.NoError(t, err)
	for _, v := range scfgs {
		c[v.JobName] = v.ServiceDiscoveryConfigs
	}