From: Martina Ferrari <tina@debian.org>
Date: Fri, 14 Feb 2025 02:37:24 +0000
Subject: Avoid various resources-related test failures

Skip or adjust tests know to fail in certain architectures due to memory
exhaustion, CPU contention, or timing.

Co-authored-by: Daniel Swarbrick <dswarbrick@debian.org>
Forwarded: not-needed
Bug: https://github.com/prometheus/prometheus/issues/10869
Last-Update: 2025-02-17
---
 cmd/promtool/unittest_test.go     |  3 +++
 promql/promql_test.go             |  3 +++
 tsdb/agent/db_test.go             |  4 ++++
 tsdb/db_test.go                   | 12 ++++++++----
 tsdb/head_test.go                 |  8 ++++++++
 util/testutil/deb_test_helpers.go | 30 ++++++++++++++++++++++++++++++
 6 files changed, 56 insertions(+), 4 deletions(-)
 create mode 100644 util/testutil/deb_test_helpers.go

diff --git a/cmd/promtool/unittest_test.go b/cmd/promtool/unittest_test.go
index 2dbd5a4..634bdff 100644
--- a/cmd/promtool/unittest_test.go
+++ b/cmd/promtool/unittest_test.go
@@ -19,9 +19,11 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"github.com/prometheus/prometheus/promql/promqltest"
+	"github.com/prometheus/prometheus/util/testutil"
 )
 
 func TestRulesUnitTest(t *testing.T) {
+	testutil.Skip32bit(t)
 	type args struct {
 		files []string
 	}
@@ -135,6 +137,7 @@ func TestRulesUnitTest(t *testing.T) {
 }
 
 func TestRulesUnitTestRun(t *testing.T) {
+	testutil.Skip32bit(t)
 	type args struct {
 		run   []string
 		files []string
diff --git a/promql/promql_test.go b/promql/promql_test.go
index 7bafc02..cdfaddf 100644
--- a/promql/promql_test.go
+++ b/promql/promql_test.go
@@ -25,6 +25,7 @@ import (
 	"github.com/prometheus/prometheus/promql"
 	"github.com/prometheus/prometheus/promql/promqltest"
 	"github.com/prometheus/prometheus/util/teststorage"
+	"github.com/prometheus/prometheus/util/testutil"
 )
 
 func newTestEngine() *promql.Engine {
@@ -37,6 +38,8 @@ func TestEvaluations(t *testing.T) {
 
 // Run a lot of queries at the same time, to check for race conditions.
 func TestConcurrentRangeQueries(t *testing.T) {
+	testutil.SkipSlow(t)
+
 	stor := teststorage.New(t)
 	defer stor.Close()
 	opts := promql.EngineOpts{
diff --git a/tsdb/agent/db_test.go b/tsdb/agent/db_test.go
index a7dae32..3a8c0f4 100644
--- a/tsdb/agent/db_test.go
+++ b/tsdb/agent/db_test.go
@@ -405,6 +405,10 @@ func TestFullTruncateWAL(t *testing.T) {
 }
 
 func TestPartialTruncateWAL(t *testing.T) {
+	// Test appears to delete variable number of series, depending on
+	// performance / load of host's CPU, resulting in unpredictable result.
+	testutil.SkipOn(t, []string{"mipsle", "mips64le", "riscv64"}, "Skipping flaky test")
+
 	const (
 		numDatapoints = 1000
 		numSeries     = 800
diff --git a/tsdb/db_test.go b/tsdb/db_test.go
index 69c9f60..f5413ea 100644
--- a/tsdb/db_test.go
+++ b/tsdb/db_test.go
@@ -3723,6 +3723,8 @@ func testChunkQuerierShouldNotPanicIfHeadChunkIsTruncatedWhileReadingQueriedChun
 }
 
 func TestQuerierShouldNotFailIfOOOCompactionOccursAfterRetrievingQuerier(t *testing.T) {
+	testutil.SkipOn(t, []string{"riscv64"}, "Skip test on riscv64")
+
 	opts := DefaultOptions()
 	opts.OutOfOrderTimeWindow = 3 * DefaultBlockDuration
 	db := openTestDB(t, opts, nil)
@@ -3774,7 +3776,7 @@ func TestQuerierShouldNotFailIfOOOCompactionOccursAfterRetrievingQuerier(t *test
 
 	// Give CompactOOOHead time to start work.
 	// If it does not wait for querierCreatedBeforeCompaction to be closed, then the query will return incorrect results or fail.
-	time.Sleep(time.Second)
+	time.Sleep(3 * time.Second)
 	require.False(t, compactionComplete.Load(), "compaction completed before reading chunks or closing querier created before compaction")
 
 	// Get another querier. This one should only use the compacted blocks from disk and ignore the chunks that will be garbage collected.
@@ -3809,7 +3811,7 @@ func TestQuerierShouldNotFailIfOOOCompactionOccursAfterRetrievingQuerier(t *test
 
 	require.False(t, compactionComplete.Load(), "compaction completed before closing querier created before compaction")
 	require.NoError(t, querierCreatedBeforeCompaction.Close())
-	require.Eventually(t, compactionComplete.Load, time.Second, 10*time.Millisecond, "compaction should complete after querier created before compaction was closed, and not wait for querier created after compaction")
+	require.Eventually(t, compactionComplete.Load, 10*time.Second, 100*time.Millisecond, "compaction should complete after querier created before compaction was closed, and not wait for querier created after compaction")
 
 	// Use the querier created after compaction and confirm it returns the expected results (ie. from the disk block created from OOO head and in-order head) without error.
 	testQuerier(querierCreatedAfterCompaction)
@@ -3872,7 +3874,7 @@ func TestQuerierShouldNotFailIfOOOCompactionOccursAfterSelecting(t *testing.T) {
 
 	// Give CompactOOOHead time to start work.
 	// If it does not wait for the querier to be closed, then the query will return incorrect results or fail.
-	time.Sleep(time.Second)
+	time.Sleep(3 * time.Second)
 	require.False(t, compactionComplete.Load(), "compaction completed before reading chunks or closing querier")
 
 	// Collect the iterator for the series.
@@ -3963,7 +3965,7 @@ func TestQuerierShouldNotFailIfOOOCompactionOccursAfterRetrievingIterators(t *te
 
 	// Give CompactOOOHead time to start work.
 	// If it does not wait for the querier to be closed, then the query will return incorrect results or fail.
-	time.Sleep(time.Second)
+	time.Sleep(3 * time.Second)
 	require.False(t, compactionComplete.Load(), "compaction completed before reading chunks or closing querier")
 
 	// Check that we can still successfully read all samples.
@@ -6747,6 +6749,8 @@ func testHistogramAppendAndQueryHelper(t *testing.T, floatHistogram bool) {
 }
 
 func TestQueryHistogramFromBlocksWithCompaction(t *testing.T) {
+	testutil.Skip32bit(t)
+
 	minute := func(m int) int64 { return int64(m) * time.Minute.Milliseconds() }
 
 	testBlockQuerying := func(t *testing.T, blockSeries ...[]storage.Series) {
diff --git a/tsdb/head_test.go b/tsdb/head_test.go
index bb437ab..46f4ee9 100644
--- a/tsdb/head_test.go
+++ b/tsdb/head_test.go
@@ -715,6 +715,8 @@ func TestHead_ReadWAL(t *testing.T) {
 }
 
 func TestHead_WALMultiRef(t *testing.T) {
+	testutil.Skip32bit(t)
+
 	head, w := newTestHead(t, 1000, wlog.CompressionNone, false)
 
 	require.NoError(t, head.Init(0))
@@ -1337,6 +1339,8 @@ func TestDeleteUntilCurMax(t *testing.T) {
 }
 
 func TestDeletedSamplesAndSeriesStillInWALAfterCheckpoint(t *testing.T) {
+	testutil.Skip32bit(t)
+
 	numSamples := 10000
 
 	// Enough samples to cause a checkpoint.
@@ -2170,6 +2174,8 @@ func TestWblRepair_DecodingError(t *testing.T) {
 }
 
 func TestHeadReadWriterRepair(t *testing.T) {
+	testutil.Skip32bit(t)
+
 	dir := t.TempDir()
 
 	const chunkRange = 1000
@@ -3668,6 +3674,8 @@ func TestHistogramInWALAndMmapChunk(t *testing.T) {
 }
 
 func TestChunkSnapshot(t *testing.T) {
+	testutil.Skip32bit(t)
+
 	head, _ := newTestHead(t, 120*4, wlog.CompressionNone, false)
 	defer func() {
 		head.opts.EnableMemorySnapshotOnShutdown = false
diff --git a/util/testutil/deb_test_helpers.go b/util/testutil/deb_test_helpers.go
new file mode 100644
index 0000000..0cbaa45
--- /dev/null
+++ b/util/testutil/deb_test_helpers.go
@@ -0,0 +1,30 @@
+package testutil
+
+import (
+	"math/bits"
+	"runtime"
+	"testing"
+)
+
+func Skip32bit(t *testing.T) {
+	t.Helper()
+
+	if bits.UintSize == 32 {
+		t.Skip("Skipping test on 32-bit arch")
+	}
+}
+
+func SkipSlow(t *testing.T) {
+	t.Helper()
+	SkipOn(t, []string{"386", "arm", "mipsle", "riscv64"}, "Skipping CPU-intensive test on slow arch")
+}
+
+func SkipOn(t *testing.T, arches []string, msg string) {
+	t.Helper()
+
+	for _, arch := range arches {
+		if runtime.GOARCH == arch {
+			t.Skip(msg)
+		}
+	}
+}
