From e232db1d188c34205cc042fc67d91f33da7e94b0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Sun, 26 Jan 2020 17:18:47 +0000 Subject: [PATCH] testutil: Moving all e2e utils to separate package, added TB union. Signed-off-by: Bartlomiej Plotka --- cmd/thanos/main_test.go | 11 ++- pkg/block/block_test.go | 17 +++-- pkg/block/index_test.go | 3 +- pkg/block/indexheader/header_test.go | 7 +- pkg/compact/compact_e2e_test.go | 3 +- pkg/promclient/promclient_e2e_test.go | 11 +-- pkg/query/api/v1_test.go | 3 +- pkg/shipper/shipper_e2e_test.go | 3 +- pkg/store/bucket.go | 2 +- pkg/store/bucket_e2e_test.go | 5 +- pkg/store/bucket_test.go | 9 ++- pkg/store/prometheus_test.go | 13 ++-- pkg/store/tsdb_test.go | 11 +-- pkg/testutil/{ => e2eutil}/copy.go | 5 +- pkg/testutil/{ => e2eutil}/port.go | 2 +- pkg/testutil/{ => e2eutil}/prometheus.go | 7 +- pkg/testutil/{ => e2eutil}/sysprocattr.go | 2 +- .../{ => e2eutil}/sysprocattr_linux.go | 2 +- pkg/testutil/testorbench.go | 75 +++++++++++++++++++ pkg/testutil/testorbench_test.go | 46 ++++++++++++ test/e2e/spinup_test.go | 10 +-- test/e2e/store_gateway_test.go | 7 +- 22 files changed, 194 insertions(+), 60 deletions(-) rename pkg/testutil/{ => e2eutil}/copy.go (89%) rename pkg/testutil/{ => e2eutil}/port.go (95%) rename pkg/testutil/{ => e2eutil}/prometheus.go (98%) rename pkg/testutil/{ => e2eutil}/sysprocattr.go (91%) rename pkg/testutil/{ => e2eutil}/sysprocattr_linux.go (94%) create mode 100644 pkg/testutil/testorbench.go create mode 100644 pkg/testutil/testorbench_test.go diff --git a/cmd/thanos/main_test.go b/cmd/thanos/main_test.go index 839c125e07..1917a79f20 100644 --- a/cmd/thanos/main_test.go +++ b/cmd/thanos/main_test.go @@ -9,9 +9,6 @@ import ( "os" "path" "path/filepath" - - "github.com/thanos-io/thanos/pkg/block/metadata" - "testing" "time" @@ -21,10 +18,12 @@ import ( promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/block" + "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/compact" "github.com/thanos-io/thanos/pkg/compact/downsample" "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestCleanupIndexCacheFolder(t *testing.T) { @@ -41,7 +40,7 @@ func TestCleanupIndexCacheFolder(t *testing.T) { // Upload one compaction lvl = 2 block, one compaction lvl = 1. // We generate index cache files only for lvl > 1 blocks. { - id, err := testutil.CreateBlock( + id, err := e2eutil.CreateBlock( ctx, dir, []labels.Labels{{{Name: "a", Value: "1"}}}, @@ -59,7 +58,7 @@ func TestCleanupIndexCacheFolder(t *testing.T) { testutil.Ok(t, block.Upload(ctx, logger, bkt, path.Join(dir, id.String()))) } { - id, err := testutil.CreateBlock( + id, err := e2eutil.CreateBlock( ctx, dir, []labels.Labels{{{Name: "a", Value: "1"}}}, @@ -102,7 +101,7 @@ func TestCleanupDownsampleCacheFolder(t *testing.T) { bkt := inmem.NewBucket() var id ulid.ULID { - id, err = testutil.CreateBlock( + id, err = e2eutil.CreateBlock( ctx, dir, []labels.Labels{{{Name: "a", Value: "1"}}}, diff --git a/pkg/block/block_test.go b/pkg/block/block_test.go index 38b649afe2..e6bdfc8ce1 100644 --- a/pkg/block/block_test.go +++ b/pkg/block/block_test.go @@ -17,6 +17,7 @@ import ( "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "github.com/oklog/ulid" ) @@ -77,7 +78,7 @@ func TestUpload(t *testing.T) { defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() bkt := inmem.NewBucket() - b1, err := testutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + b1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, @@ -105,7 +106,7 @@ func TestUpload(t *testing.T) { testutil.NotOk(t, err) testutil.Assert(t, strings.HasSuffix(err.Error(), "/meta.json: no such file or directory"), "") } - testutil.Copy(t, path.Join(tmpDir, b1.String(), MetaFilename), path.Join(tmpDir, "test", b1.String(), MetaFilename)) + e2eutil.Copy(t, path.Join(tmpDir, b1.String(), MetaFilename), path.Join(tmpDir, "test", b1.String(), MetaFilename)) { // Missing chunks. err := Upload(ctx, log.NewNopLogger(), bkt, path.Join(tmpDir, "test", b1.String())) @@ -116,7 +117,7 @@ func TestUpload(t *testing.T) { testutil.Equals(t, 1, len(bkt.Objects())) } testutil.Ok(t, os.MkdirAll(path.Join(tmpDir, "test", b1.String(), ChunksDirname), os.ModePerm)) - testutil.Copy(t, path.Join(tmpDir, b1.String(), ChunksDirname, "000001"), path.Join(tmpDir, "test", b1.String(), ChunksDirname, "000001")) + e2eutil.Copy(t, path.Join(tmpDir, b1.String(), ChunksDirname, "000001"), path.Join(tmpDir, "test", b1.String(), ChunksDirname, "000001")) { // Missing index file. err := Upload(ctx, log.NewNopLogger(), bkt, path.Join(tmpDir, "test", b1.String())) @@ -126,7 +127,7 @@ func TestUpload(t *testing.T) { // Only debug meta.json present. testutil.Equals(t, 1, len(bkt.Objects())) } - testutil.Copy(t, path.Join(tmpDir, b1.String(), IndexFilename), path.Join(tmpDir, "test", b1.String(), IndexFilename)) + e2eutil.Copy(t, path.Join(tmpDir, b1.String(), IndexFilename), path.Join(tmpDir, "test", b1.String(), IndexFilename)) testutil.Ok(t, os.Remove(path.Join(tmpDir, "test", b1.String(), MetaFilename))) { // Missing meta.json file. @@ -137,7 +138,7 @@ func TestUpload(t *testing.T) { // Only debug meta.json present. testutil.Equals(t, 1, len(bkt.Objects())) } - testutil.Copy(t, path.Join(tmpDir, b1.String(), MetaFilename), path.Join(tmpDir, "test", b1.String(), MetaFilename)) + e2eutil.Copy(t, path.Join(tmpDir, b1.String(), MetaFilename), path.Join(tmpDir, "test", b1.String(), MetaFilename)) { // Full block. testutil.Ok(t, Upload(ctx, log.NewNopLogger(), bkt, path.Join(tmpDir, "test", b1.String()))) @@ -156,7 +157,7 @@ func TestUpload(t *testing.T) { } { // Upload with no external labels should be blocked. - b2, err := testutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + b2, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, @@ -182,7 +183,7 @@ func TestDelete(t *testing.T) { bkt := inmem.NewBucket() { - b1, err := testutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + b1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, @@ -199,7 +200,7 @@ func TestDelete(t *testing.T) { testutil.Equals(t, 1, len(bkt.Objects())) } { - b2, err := testutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + b2, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, diff --git a/pkg/block/index_test.go b/pkg/block/index_test.go index 57860461b7..7be4e75ea1 100644 --- a/pkg/block/index_test.go +++ b/pkg/block/index_test.go @@ -17,6 +17,7 @@ import ( "github.com/prometheus/prometheus/tsdb/index" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestRewrite(t *testing.T) { @@ -26,7 +27,7 @@ func TestRewrite(t *testing.T) { testutil.Ok(t, err) defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() - b, err := testutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + b, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, diff --git a/pkg/block/indexheader/header_test.go b/pkg/block/indexheader/header_test.go index 932071482c..c0cc76d3f8 100644 --- a/pkg/block/indexheader/header_test.go +++ b/pkg/block/indexheader/header_test.go @@ -25,6 +25,7 @@ import ( "github.com/thanos-io/thanos/pkg/objstore/filesystem" "github.com/thanos-io/thanos/pkg/runutil" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestReaders(t *testing.T) { @@ -39,7 +40,7 @@ func TestReaders(t *testing.T) { defer func() { testutil.Ok(t, bkt.Close()) }() // Create block index version 2. - id1, err := testutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + id1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, @@ -69,7 +70,7 @@ func TestReaders(t *testing.T) { m, err := metadata.Read("./testdata/index_format_v1") testutil.Ok(t, err) - testutil.Copy(t, "./testdata/index_format_v1", filepath.Join(tmpDir, m.ULID.String())) + e2eutil.Copy(t, "./testdata/index_format_v1", filepath.Join(tmpDir, m.ULID.String())) _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(tmpDir, m.ULID.String()), metadata.Thanos{ Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), @@ -264,7 +265,7 @@ func prepareIndexV2Block(t testing.TB, tmpDir string, bkt objstore.Bucket) *meta m, err := metadata.Read("./testdata/index_format_v2") testutil.Ok(t, err) - testutil.Copy(t, "./testdata/index_format_v2", filepath.Join(tmpDir, m.ULID.String())) + e2eutil.Copy(t, "./testdata/index_format_v2", filepath.Join(tmpDir, m.ULID.String())) _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(tmpDir, m.ULID.String()), metadata.Thanos{ Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), diff --git a/pkg/compact/compact_e2e_test.go b/pkg/compact/compact_e2e_test.go index 80dba2a795..56869e5bdc 100644 --- a/pkg/compact/compact_e2e_test.go +++ b/pkg/compact/compact_e2e_test.go @@ -30,6 +30,7 @@ import ( "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/objstore/objtesting" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestSyncer_GarbageCollect_e2e(t *testing.T) { @@ -383,7 +384,7 @@ func createAndUpload(t testing.TB, bkt objstore.Bucket, blocks []blockgenSpec) ( if b.numSamples == 0 { id, err = createEmptyBlock(prepareDir, b.mint, b.maxt, b.extLset, b.res) } else { - id, err = testutil.CreateBlock(ctx, prepareDir, b.series, b.numSamples, b.mint, b.maxt, b.extLset, b.res) + id, err = e2eutil.CreateBlock(ctx, prepareDir, b.series, b.numSamples, b.mint, b.maxt, b.extLset, b.res) } testutil.Ok(t, err) diff --git a/pkg/promclient/promclient_e2e_test.go b/pkg/promclient/promclient_e2e_test.go index 61f5a5e85a..f692ef11fe 100644 --- a/pkg/promclient/promclient_e2e_test.go +++ b/pkg/promclient/promclient_e2e_test.go @@ -20,10 +20,11 @@ import ( "github.com/prometheus/prometheus/pkg/timestamp" "github.com/thanos-io/thanos/pkg/runutil" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestIsWALFileAccessible_e2e(t *testing.T) { - testutil.ForeachPrometheus(t, func(t testing.TB, p *testutil.Prometheus) { + e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) { testutil.Ok(t, p.Start()) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) @@ -36,7 +37,7 @@ func TestIsWALFileAccessible_e2e(t *testing.T) { } func TestExternalLabels_e2e(t *testing.T) { - testutil.ForeachPrometheus(t, func(t testing.TB, p *testutil.Prometheus) { + e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) { testutil.Ok(t, p.SetConfig(` global: external_labels: @@ -59,7 +60,7 @@ global: } func TestConfiguredFlags_e2e(t *testing.T) { - testutil.ForeachPrometheus(t, func(t testing.TB, p *testutil.Prometheus) { + e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) { testutil.Ok(t, p.Start()) u, err := url.Parse(fmt.Sprintf("http://%s", p.Addr())) @@ -78,12 +79,12 @@ func TestConfiguredFlags_e2e(t *testing.T) { } func TestSnapshot_e2e(t *testing.T) { - testutil.ForeachPrometheus(t, func(t testing.TB, p *testutil.Prometheus) { + e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) { now := time.Now() ctx := context.Background() // Create artificial block. - id, err := testutil.CreateBlockWithTombstone( + id, err := e2eutil.CreateBlockWithTombstone( ctx, p.Dir(), []labels.Labels{labels.FromStrings("a", "b")}, diff --git a/pkg/query/api/v1_test.go b/pkg/query/api/v1_test.go index 80b602bec7..481754f3ac 100644 --- a/pkg/query/api/v1_test.go +++ b/pkg/query/api/v1_test.go @@ -45,6 +45,7 @@ import ( "github.com/thanos-io/thanos/pkg/query" "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestEndpoints(t *testing.T) { @@ -85,7 +86,7 @@ func TestEndpoints(t *testing.T) { }, } - db, err := testutil.NewTSDB() + db, err := e2eutil.NewTSDB() defer func() { testutil.Ok(t, db.Close()) }() testutil.Ok(t, err) diff --git a/pkg/shipper/shipper_e2e_test.go b/pkg/shipper/shipper_e2e_test.go index 2b17e460e7..19695426f2 100644 --- a/pkg/shipper/shipper_e2e_test.go +++ b/pkg/shipper/shipper_e2e_test.go @@ -16,6 +16,7 @@ import ( "time" "github.com/thanos-io/thanos/pkg/objstore/inmem" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "github.com/go-kit/kit/log" "github.com/oklog/ulid" @@ -172,7 +173,7 @@ func TestShipper_SyncBlocks_e2e(t *testing.T) { } func TestShipper_SyncBlocksWithMigrating_e2e(t *testing.T) { - testutil.ForeachPrometheus(t, func(t testing.TB, p *testutil.Prometheus) { + e2eutil.ForeachPrometheus(t, func(t testing.TB, p *e2eutil.Prometheus) { dir, err := ioutil.TempDir("", "shipper-e2e-test") testutil.Ok(t, err) defer func() { diff --git a/pkg/store/bucket.go b/pkg/store/bucket.go index bdeaaf2f9e..8b09feafc9 100644 --- a/pkg/store/bucket.go +++ b/pkg/store/bucket.go @@ -1703,7 +1703,7 @@ type partitioner interface { // Partition partitions length entries into n <= length ranges that cover all // input ranges // It supports overlapping ranges. - // NOTE: It expects range to be sorted by start time. + // NOTE: It expects range to be ted by start time. Partition(length int, rng func(int) (uint64, uint64)) []part } diff --git a/pkg/store/bucket_e2e_test.go b/pkg/store/bucket_e2e_test.go index 77bd8dd21a..6bdc6a5950 100644 --- a/pkg/store/bucket_e2e_test.go +++ b/pkg/store/bucket_e2e_test.go @@ -26,6 +26,7 @@ import ( storecache "github.com/thanos-io/thanos/pkg/store/cache" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) var ( @@ -100,9 +101,9 @@ func prepareTestBlocks(t testing.TB, now time.Time, count int, dir string, bkt o // Create two blocks per time slot. Only add 10 samples each so only one chunk // gets created each. This way we can easily verify we got 10 chunks per series below. - id1, err := testutil.CreateBlock(ctx, dir, series[:4], 10, mint, maxt, extLset, 0) + id1, err := e2eutil.CreateBlock(ctx, dir, series[:4], 10, mint, maxt, extLset, 0) testutil.Ok(t, err) - id2, err := testutil.CreateBlock(ctx, dir, series[4:], 10, mint, maxt, extLset, 0) + id2, err := e2eutil.CreateBlock(ctx, dir, series[4:], 10, mint, maxt, extLset, 0) testutil.Ok(t, err) dir1, dir2 := filepath.Join(dir, id1.String()), filepath.Join(dir, id2.String()) diff --git a/pkg/store/bucket_test.go b/pkg/store/bucket_test.go index 216adedc09..a277f392cf 100644 --- a/pkg/store/bucket_test.go +++ b/pkg/store/bucket_test.go @@ -35,6 +35,7 @@ import ( "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "gopkg.in/yaml.v2" ) @@ -502,19 +503,19 @@ func TestBucketStore_Sharding(t *testing.T) { bkt := inmem.NewBucket() series := []labels.Labels{labels.FromStrings("a", "1", "b", "1")} - id1, err := testutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r1"}}, 0) + id1, err := e2eutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r1"}}, 0) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, filepath.Join(dir, id1.String()))) - id2, err := testutil.CreateBlock(ctx, dir, series, 10, 1000, 2000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r1"}}, 0) + id2, err := e2eutil.CreateBlock(ctx, dir, series, 10, 1000, 2000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r1"}}, 0) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, filepath.Join(dir, id2.String()))) - id3, err := testutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "b"}, {Name: "region", Value: "r1"}}, 0) + id3, err := e2eutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "b"}, {Name: "region", Value: "r1"}}, 0) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, filepath.Join(dir, id3.String()))) - id4, err := testutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r2"}}, 0) + id4, err := e2eutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r2"}}, 0) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, filepath.Join(dir, id4.String()))) diff --git a/pkg/store/prometheus_test.go b/pkg/store/prometheus_test.go index d2bb97b06c..703d52f687 100644 --- a/pkg/store/prometheus_test.go +++ b/pkg/store/prometheus_test.go @@ -17,6 +17,7 @@ import ( "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/chunkenc" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/store/storepb" @@ -37,7 +38,7 @@ func testPrometheusStoreSeriesE2e(t *testing.T, prefix string) { defer leaktest.CheckTimeout(t, 10*time.Second)() - p, err := testutil.NewPrometheusOnPath(prefix) + p, err := e2eutil.NewPrometheusOnPath(prefix) testutil.Ok(t, err) defer func() { testutil.Ok(t, p.Stop()) }() @@ -189,7 +190,7 @@ func TestPrometheusStore_SeriesLabels_e2e(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - p, err := testutil.NewPrometheus() + p, err := e2eutil.NewPrometheus() testutil.Ok(t, err) defer func() { testutil.Ok(t, p.Stop()) }() @@ -291,7 +292,7 @@ func TestPrometheusStore_SeriesLabels_e2e(t *testing.T) { func TestPrometheusStore_LabelValues_e2e(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - p, err := testutil.NewPrometheus() + p, err := e2eutil.NewPrometheus() testutil.Ok(t, err) defer func() { testutil.Ok(t, p.Stop()) }() @@ -327,7 +328,7 @@ func TestPrometheusStore_LabelValues_e2e(t *testing.T) { func TestPrometheusStore_ExternalLabelValues_e2e(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - p, err := testutil.NewPrometheus() + p, err := e2eutil.NewPrometheus() testutil.Ok(t, err) defer func() { testutil.Ok(t, p.Stop()) }() @@ -367,7 +368,7 @@ func TestPrometheusStore_ExternalLabelValues_e2e(t *testing.T) { func TestPrometheusStore_Series_MatchExternalLabel_e2e(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - p, err := testutil.NewPrometheus() + p, err := e2eutil.NewPrometheus() testutil.Ok(t, err) defer func() { testutil.Ok(t, p.Stop()) }() @@ -503,7 +504,7 @@ func testSeries_SplitSamplesIntoChunksWithMaxSizeOfUint16_e2e(t *testing.T, appe func TestPrometheusStore_Series_SplitSamplesIntoChunksWithMaxSizeOfUint16_e2e(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - p, err := testutil.NewPrometheus() + p, err := e2eutil.NewPrometheus() testutil.Ok(t, err) defer func() { testutil.Ok(t, p.Stop()) }() diff --git a/pkg/store/tsdb_test.go b/pkg/store/tsdb_test.go index d8ef8eda0c..1c256f6b22 100644 --- a/pkg/store/tsdb_test.go +++ b/pkg/store/tsdb_test.go @@ -14,6 +14,7 @@ import ( "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) func TestTSDBStore_Info(t *testing.T) { @@ -22,7 +23,7 @@ func TestTSDBStore_Info(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - db, err := testutil.NewTSDB() + db, err := e2eutil.NewTSDB() defer func() { testutil.Ok(t, db.Close()) }() testutil.Ok(t, err) @@ -43,7 +44,7 @@ func TestTSDBStore_Series(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - db, err := testutil.NewTSDB() + db, err := e2eutil.NewTSDB() defer func() { testutil.Ok(t, db.Close()) }() testutil.Ok(t, err) @@ -169,7 +170,7 @@ func TestTSDBStore_LabelNames(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - db, err := testutil.NewTSDB() + db, err := e2eutil.NewTSDB() defer func() { testutil.Ok(t, db.Close()) }() testutil.Ok(t, err) @@ -224,7 +225,7 @@ func TestTSDBStore_LabelValues(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - db, err := testutil.NewTSDB() + db, err := e2eutil.NewTSDB() defer func() { testutil.Ok(t, db.Close()) }() testutil.Ok(t, err) @@ -279,7 +280,7 @@ func TestTSDBStore_LabelValues(t *testing.T) { func TestTSDBStore_Series_SplitSamplesIntoChunksWithMaxSizeOfUint16_e2e(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - db, err := testutil.NewTSDB() + db, err := e2eutil.NewTSDB() defer func() { testutil.Ok(t, db.Close()) }() testutil.Ok(t, err) diff --git a/pkg/testutil/copy.go b/pkg/testutil/e2eutil/copy.go similarity index 89% rename from pkg/testutil/copy.go rename to pkg/testutil/e2eutil/copy.go index f90dc68bbf..d31c6e9fd5 100644 --- a/pkg/testutil/copy.go +++ b/pkg/testutil/e2eutil/copy.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package testutil +package e2eutil import ( "io" @@ -10,10 +10,11 @@ import ( "testing" "github.com/pkg/errors" + "github.com/thanos-io/thanos/pkg/testutil" ) func Copy(t testing.TB, src, dst string) { - Ok(t, copyRecursive(src, dst)) + testutil.Ok(t, copyRecursive(src, dst)) } func copyRecursive(src, dst string) error { diff --git a/pkg/testutil/port.go b/pkg/testutil/e2eutil/port.go similarity index 95% rename from pkg/testutil/port.go rename to pkg/testutil/e2eutil/port.go index 482ced0858..986f1c7d7f 100644 --- a/pkg/testutil/port.go +++ b/pkg/testutil/e2eutil/port.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package testutil +package e2eutil import "net" diff --git a/pkg/testutil/prometheus.go b/pkg/testutil/e2eutil/prometheus.go similarity index 98% rename from pkg/testutil/prometheus.go rename to pkg/testutil/e2eutil/prometheus.go index 10f34b8a56..56972041ce 100644 --- a/pkg/testutil/prometheus.go +++ b/pkg/testutil/e2eutil/prometheus.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package testutil +package e2eutil import ( "context" @@ -26,6 +26,7 @@ import ( "github.com/prometheus/prometheus/tsdb" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/runutil" + "github.com/thanos-io/thanos/pkg/testutil" "golang.org/x/sync/errgroup" ) @@ -98,10 +99,10 @@ func ForeachPrometheus(t *testing.T, testFn func(t testing.TB, p *Prometheus)) { for _, ver := range strings.Split(vers, " ") { if ok := t.Run(ver, func(t *testing.T) { p, err := newPrometheus(ver, "") - Ok(t, err) + testutil.Ok(t, err) testFn(t, p) - Ok(t, p.Stop()) + testutil.Ok(t, p.Stop()) }); !ok { return } diff --git a/pkg/testutil/sysprocattr.go b/pkg/testutil/e2eutil/sysprocattr.go similarity index 91% rename from pkg/testutil/sysprocattr.go rename to pkg/testutil/e2eutil/sysprocattr.go index 98d8755ce4..cc982a5bd3 100644 --- a/pkg/testutil/sysprocattr.go +++ b/pkg/testutil/e2eutil/sysprocattr.go @@ -3,7 +3,7 @@ // +build !linux -package testutil +package e2eutil import "syscall" diff --git a/pkg/testutil/sysprocattr_linux.go b/pkg/testutil/e2eutil/sysprocattr_linux.go similarity index 94% rename from pkg/testutil/sysprocattr_linux.go rename to pkg/testutil/e2eutil/sysprocattr_linux.go index f7c59a0b50..dd77ed32a1 100644 --- a/pkg/testutil/sysprocattr_linux.go +++ b/pkg/testutil/e2eutil/sysprocattr_linux.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package testutil +package e2eutil import "syscall" diff --git a/pkg/testutil/testorbench.go b/pkg/testutil/testorbench.go new file mode 100644 index 0000000000..dcfbff11ed --- /dev/null +++ b/pkg/testutil/testorbench.go @@ -0,0 +1,75 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package testutil + +import ( + "testing" +) + +// TB represents union of test and benchmark. +// This allows the same test suite to be run by both benchmark and test, helping to reuse more code. +// The reason is that usually benchmarks are not being run on CI, especially for short tests, so you need to recreate +// usually similar tests for `Test(t *testing.T)` methods. Example of usage is presented here: +// +// func TestTestOrBench(t *testing.T) { +// tb := NewTB(t) +// tb.Run("1", func(tb TB) { testorbenchComplexTest(tb) }) +// tb.Run("2", func(tb TB) { testorbenchComplexTest(tb) }) +// } +// +// func BenchmarkTestOrBench(b *testing.B) { +// tb := NewTB(t) +// tb.Run("1", func(tb TB) { testorbenchComplexTest(tb) }) +// tb.Run("2", func(tb TB) { testorbenchComplexTest(tb) }) +// } +type TB interface { + testing.TB + IsBenchmark() bool + Run(name string, f func(t TB)) bool + N() int + ResetTimer() +} + +// tb implements TB as well as testing.TB interfaces. +type tb struct { + testing.TB +} + +// NewTB creates tb from testing.TB. +func NewTB(t testing.TB) TB { return &tb{TB: t} } + +// Run benchmarks/tests f as a subbenchmark/subtest with the given name. It reports +// whether there were any failures. +// +// A subbenchmark/subtest is like any other benchmark/test. +func (t *tb) Run(name string, f func(t TB)) bool { + if b, ok := t.TB.(*testing.B); ok { + return b.Run(name, func(nested *testing.B) { f(&tb{TB: nested}) }) + } + if t, ok := t.TB.(*testing.T); ok { + return t.Run(name, func(nested *testing.T) { f(&tb{TB: nested}) }) + } + panic("not a benchmark and not a test") +} + +// N returns number of iterations to do for benchmark, 1 in case of test. +func (t *tb) N() int { + if b, ok := t.TB.(*testing.B); ok { + return b.N + } + return 1 +} + +// ResetTimer resets a timer, if it's a benchmark, noop otherwise. +func (t *tb) ResetTimer() { + if b, ok := t.TB.(*testing.B); ok { + b.ResetTimer() + } +} + +// IsBenchmark returns true if it's a benchmark. +func (t *tb) IsBenchmark() bool { + _, ok := t.TB.(*testing.B) + return ok +} diff --git a/pkg/testutil/testorbench_test.go b/pkg/testutil/testorbench_test.go new file mode 100644 index 0000000000..787e98fe66 --- /dev/null +++ b/pkg/testutil/testorbench_test.go @@ -0,0 +1,46 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package testutil + +import "testing" + +func TestTestOrBench(t *testing.T) { + tb := NewTB(t) + tb.Run("1", func(tb TB) { testorbenchComplexTest(tb) }) + tb.Run("2", func(tb TB) { testorbenchComplexTest(tb) }) +} + +func BenchmarkTestOrBench(b *testing.B) { + tb := NewTB(b) + tb.Run("1", func(tb TB) { testorbenchComplexTest(tb) }) + tb.Run("2", func(tb TB) { testorbenchComplexTest(tb) }) +} + +func testorbenchComplexTest(tb TB) { + tb.Run("a", func(tb TB) { + tb.Run("aa", func(tb TB) { + tb.ResetTimer() + for i := 0; i < tb.N(); i++ { + if !tb.IsBenchmark() { + if tb.N() != 1 { + tb.FailNow() + } + } + } + }) + }) + tb.Run("b", func(tb TB) { + tb.Run("bb", func(tb TB) { + tb.ResetTimer() + for i := 0; i < tb.N(); i++ { + if !tb.IsBenchmark() { + if tb.N() != 1 { + tb.FailNow() + } + } + } + }) + }) + +} diff --git a/test/e2e/spinup_test.go b/test/e2e/spinup_test.go index 46e4ae2295..ad0f57b6c4 100644 --- a/test/e2e/spinup_test.go +++ b/test/e2e/spinup_test.go @@ -25,7 +25,7 @@ import ( "github.com/thanos-io/thanos/pkg/receive" "github.com/thanos-io/thanos/pkg/runutil" "github.com/thanos-io/thanos/pkg/store/storepb" - "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "google.golang.org/grpc" ) @@ -94,7 +94,7 @@ func newCmdExec(cmd *exec.Cmd) *cmdExec { func (c *cmdExec) Start(stdout io.Writer, stderr io.Writer) error { c.Stderr = stderr c.Stdout = stdout - c.SysProcAttr = testutil.SysProcAttr() + c.SysProcAttr = e2eutil.SysProcAttr() return c.Cmd.Start() } @@ -138,7 +138,7 @@ func prometheus(http address, config string) *prometheusScheduler { return nil, errors.Wrap(err, "creating prom config failed") } - return newCmdExec(exec.Command(testutil.PrometheusBinary(), + return newCmdExec(exec.Command(e2eutil.PrometheusBinary(), "--config.file", promDir+"/prometheus.yml", "--storage.tsdb.path", promDir, "--storage.tsdb.max-block-duration", "2h", @@ -299,7 +299,7 @@ receivers: if err := ioutil.WriteFile(dir+"/config.yaml", []byte(config), 0666); err != nil { return nil, errors.Wrap(err, "creating alertmanager config file failed") } - return newCmdExec(exec.Command(testutil.AlertmanagerBinary(), + return newCmdExec(exec.Command(e2eutil.AlertmanagerBinary(), "--config.file", dir+"/config.yaml", "--web.listen-address", http.HostPort(), "--cluster.listen-address", "", @@ -418,7 +418,7 @@ func minio(http address, config s3.Config) *serverScheduler { return nil, errors.Wrap(err, "creating minio dir failed") } - cmd := exec.Command(testutil.MinioBinary(), + cmd := exec.Command(e2eutil.MinioBinary(), "server", "--address", http.HostPort(), dbDir, diff --git a/test/e2e/store_gateway_test.go b/test/e2e/store_gateway_test.go index d30bb184ff..484fbec325 100644 --- a/test/e2e/store_gateway_test.go +++ b/test/e2e/store_gateway_test.go @@ -22,6 +22,7 @@ import ( "github.com/thanos-io/thanos/pkg/promclient" "github.com/thanos-io/thanos/pkg/runutil" "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" yaml "gopkg.in/yaml.v2" ) @@ -79,13 +80,13 @@ func TestStoreGateway(t *testing.T) { extLset3 := labels.FromStrings("ext1", "value2", "replica", "3") now := time.Now() - id1, err := testutil.CreateBlock(ctx, dir, series, 10, timestamp.FromTime(now), timestamp.FromTime(now.Add(2*time.Hour)), extLset, 0) + id1, err := e2eutil.CreateBlock(ctx, dir, series, 10, timestamp.FromTime(now), timestamp.FromTime(now.Add(2*time.Hour)), extLset, 0) testutil.Ok(t, err) - id2, err := testutil.CreateBlock(ctx, dir, series, 10, timestamp.FromTime(now), timestamp.FromTime(now.Add(2*time.Hour)), extLset2, 0) + id2, err := e2eutil.CreateBlock(ctx, dir, series, 10, timestamp.FromTime(now), timestamp.FromTime(now.Add(2*time.Hour)), extLset2, 0) testutil.Ok(t, err) - id3, err := testutil.CreateBlock(ctx, dir, series, 10, timestamp.FromTime(now), timestamp.FromTime(now.Add(2*time.Hour)), extLset3, 0) + id3, err := e2eutil.CreateBlock(ctx, dir, series, 10, timestamp.FromTime(now), timestamp.FromTime(now.Add(2*time.Hour)), extLset3, 0) testutil.Ok(t, err) l := log.NewLogfmtLogger(os.Stdout)