From 4fb47dbb544f84d63852d2c646bc20d5f76e04fc Mon Sep 17 00:00:00 2001 From: Kartikay <120778728+kartikaysaxena@users.noreply.github.com> Date: Mon, 10 Feb 2025 21:51:27 +0000 Subject: [PATCH] separate targets for cover Signed-off-by: Kartikay <120778728+kartikaysaxena@users.noreply.github.com> --- magefiles/test.go | 296 ++++++++++++++++++++++++++++++++++++---------- magefiles/util.go | 21 +++- 2 files changed, 249 insertions(+), 68 deletions(-) diff --git a/magefiles/test.go b/magefiles/test.go index 330b726753..fdebc695c4 100644 --- a/magefiles/test.go +++ b/magefiles/test.go @@ -15,48 +15,113 @@ type Test mg.Namespace var emptyEnv map[string]string -// All Runs all test suites and generates a combined coverage report +// All Runs all test suites func (t Test) All() error { ds := Testds{} c := Testcons{} mg.Deps(t.Unit, t.Integration, t.Steelthread, t.Image, t.Analyzers, ds.Crdb, ds.Postgres, ds.Spanner, ds.Mysql, c.Crdb, c.Spanner, c.Postgres, c.Mysql) + return nil +} + +// All Runs all test suites and generates a combined coverage report +func (t Test) AllCover() error { + ds := Testds{} + c := Testcons{} + mg.Deps(t.UnitCover, t.IntegrationCover, t.SteelthreadCover, t.ImageCover, t.AnalyzersCover, + ds.CrdbCover, ds.PostgresCover, ds.SpannerCover, ds.MysqlCover, + c.CrdbCover, c.SpannerCover, c.PostgresCover, c.MysqlCover) return combineCoverage() } // UnitCover Runs the unit tests and generates a coverage report func (t Test) UnitCover() error { - if err := t.Unit(); err != nil { + if err := t.unit(true); err != nil { return err } fmt.Println("Running coverage...") - return sh.RunV("go", "tool", "cover", "-html=coverage-unit.txt") + return nil } // Unit Runs the unit tests func (t Test) Unit() error { + return t.unit(false) +} + +func (Test) unit(coverage bool) error { fmt.Println("running unit tests") args := []string{"-tags", "ci,skipintegrationtests", "-race", "-timeout", "10m", "-count=1"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./..."))) + } return goTest("./...", args...) } +// Image Run tests that run the built image and generates a coverage report +func (t Test) ImageCover() error { + if err := t.image(true); err != nil { + return err + } + return nil +} + // Image Run tests that run the built image func (Test) Image() error { mg.Deps(Build{}.Testimage) return goDirTest("./cmd/spicedb", "./...", "-tags", "docker,image") } -// Integration Run integration tests -func (Test) Integration() error { - mg.Deps(checkDocker) - return goTest("./internal/services/integrationtesting/...", "-tags", "ci,docker", "-timeout", "15m") +func (Test) image(coverage bool) error { + mg.Deps(Build{}.Testimage) + args := []string{"-tags", "docker,image"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./..."))) + } + return goDirTest("./cmd/spicedb", "./...", args...) } -// Steelthread Run steelthread tests -func (Test) Steelthread() error { +// IntegrationCover Runs the integration tests and generates a coverage report +func (t Test) IntegrationCover() error { + if err := t.integration(true); err != nil { + return err + } + return nil +} + +// Integration Runs the integration tests +func (t Test) Integration() error { + return t.integration(false) +} + +func (Test) integration(coverage bool) error { + args := []string{"-tags", "ci,docker", "-timeout", "15m"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/services/integrationtesting/..."))) + } + return goTest("./internal/services/integrationtesting/...", args...) +} + +// SteelthreadCover Runs the steelthread tests and generates a coverage report +func (t Test) SteelthreadCover() error { + if err := t.steelthread(true); err != nil { + return err + } + return nil +} + +// Steelthread Runs the steelthread tests +func (t Test) Steelthread() error { + return t.steelthread(false) +} + +func (Test) steelthread(coverage bool) error { fmt.Println("running steel thread tests") - return goTest("./internal/services/steelthreadtesting/...", "-tags", "steelthread,docker,image", "-timeout", "15m", "-v") + args := []string{"-tags", "steelthread,docker,image", "-timeout", "15m", "-v"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/services/steelthreadtesting/..."))) + } + return goTest("./internal/services/steelthreadtesting/...", args...) } // RegenSteelthread Regenerate the steelthread tests @@ -67,9 +132,25 @@ func (Test) RegenSteelthread() error { }), WithArgs("test", "./internal/services/steelthreadtesting/...", "-tags", "steelthread,docker,image", "-timeout", "15m", "-v"))("go") } +// AnalyzersCover Runs the analyzer tests and generates a coverage report +func (t Test) AnalyzersCover() error { + if err := t.analyzers(true); err != nil { + return err + } + return nil +} + // Analyzers Run the analyzer unit tests -func (Test) Analyzers() error { - return goDirTest("./tools/analyzers", "./...") +func (t Test) Analyzers() error { + return t.analyzers(false) +} + +func (Test) analyzers(coverage bool) error { + args := []string{} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./..."))) + } + return goDirTest("./tools/analyzers", "./...", args...) } // Wasm Run wasm browser tests @@ -87,39 +168,96 @@ func (Test) Wasm() error { type Testds mg.Namespace -// Crdb Run datastore tests for crdb -func (tds Testds) Crdb() error { - return tds.crdb("") +// CrdbCover Runs the CRDB datastore tests and generates a coverage report +func (tds Testds) CrdbCover() error { + if err := tds.crdb(true, ""); err != nil { + return err + } + return nil } -func (tds Testds) CrdbVer(version string) error { - return tds.crdb(version) +// Crdb Runs the CRDB datastore tests +func (tds Testds) Crdb() error { + return tds.crdb(false, "") } -func (Testds) crdb(version string) error { +func (Testds) crdb(coverage bool, version string) error { + args := []string{"-tags", "ci,docker", "-timeout", "10m"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/datastore/crdb/..."))) + } return datastoreTest("crdb", map[string]string{ "CRDB_TEST_VERSION": version, - }) + }, args...) } -// Spanner Run datastore tests for spanner -func (Testds) Spanner() error { - return datastoreTest("spanner", emptyEnv) +// PostgresCover Runs the Postgres datastore tests and generates a coverage report +func (tds Testds) PostgresCover() error { + if err := tds.postgres(true, ""); err != nil { + return err + } + return nil } -// Postgres Run datastore tests for postgres +// Postgres Runs the Postgres datastore tests func (tds Testds) Postgres() error { - return tds.postgres("") + return tds.postgres(false, "") } -func (tds Testds) PostgresVer(version string) error { - return tds.postgres(version) -} - -func (Testds) postgres(version string) error { +func (Testds) postgres(coverage bool, version string) error { + args := []string{"-tags", "ci,docker", "-timeout", "10m"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/datastore/postgres/..."))) + } return datastoreTest("postgres", map[string]string{ "POSTGRES_TEST_VERSION": version, - }, "postgres") + }, args...) +} + +// SpannerCover Runs the Spanner datastore tests and generates a coverage report +func (tds Testds) SpannerCover() error { + if err := tds.spanner(true); err != nil { + return err + } + return nil +} + +// Spanner Runs the Spanner datastore tests +func (tds Testds) Spanner() error { + return tds.spanner(false) +} + +func (Testds) spanner(coverage bool) error { + args := []string{"-tags", "ci,docker", "-timeout", "10m"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/datastore/spanner/..."))) + } + return datastoreTest("spanner", emptyEnv, args...) +} + +// MysqlCover Runs the MySQL datastore tests and generates a coverage report +func (tds Testds) MysqlCover() error { + if err := tds.mysql(true); err != nil { + return err + } + return nil +} + +// Mysql Runs the MySQL datastore tests +func (tds Testds) Mysql() error { + return tds.mysql(false) +} + +func (Testds) mysql(coverage bool) error { + args := []string{"-tags", "ci,docker", "-timeout", "10m"} + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/datastore/mysql/..."))) + } + return datastoreTest("mysql", emptyEnv, args...) +} + +func (tds Testds) PostgresVer(version string) error { + return tds.postgres(false, version) } // Pgbouncer Run datastore tests for postgres with Pgbouncer @@ -137,11 +275,6 @@ func (Testds) pgbouncer(version string) error { }, "pgbouncer") } -// Mysql Run datastore tests for mysql -func (Testds) Mysql() error { - return datastoreTest("mysql", emptyEnv) -} - func datastoreTest(datastore string, env map[string]string, tags ...string) error { mergedTags := append([]string{"ci", "docker"}, tags...) tagString := strings.Join(mergedTags, ",") @@ -151,38 +284,80 @@ func datastoreTest(datastore string, env map[string]string, tags ...string) erro type Testcons mg.Namespace -// Crdb Run consistency tests for crdb -func (tc Testcons) Crdb() error { - return tc.crdb("") +// CrdbCover Runs the CRDB consistency tests and generates a coverage report +func (tc Testcons) CrdbCover() error { + if err := tc.crdb(true, ""); err != nil { + return err + } + return nil } -func (tc Testcons) CrdbVer(version string) error { - return tc.crdb(version) +// Crdb Runs the CRDB consistency tests +func (tc Testcons) Crdb() error { + return tc.crdb(false, "") } -func (Testcons) crdb(version string) error { +func (Testcons) crdb(coverage bool, version string) error { return consistencyTest("crdb", map[string]string{ "CRDB_TEST_VERSION": version, - }) + }, coverage) } -// Spanner Run consistency tests for spanner -func (Testcons) Spanner() error { - return consistencyTest("spanner", emptyEnv) +// PostgresCover Runs the Postgres consistency tests and generates a coverage report +func (tc Testcons) PostgresCover() error { + if err := tc.postgres(true, ""); err != nil { + return err + } + return nil } +// Postgres Runs the Postgres consistency tests func (tc Testcons) Postgres() error { - return tc.postgres("") -} - -func (tc Testcons) PostgresVer(version string) error { - return tc.postgres(version) + return tc.postgres(false, "") } -func (Testcons) postgres(version string) error { +func (Testcons) postgres(coverage bool, version string) error { return consistencyTest("postgres", map[string]string{ "POSTGRES_TEST_VERSION": version, - }) + }, coverage) +} + +// SpannerCover Runs the Spanner consistency tests and generates a coverage report +func (tc Testcons) SpannerCover() error { + if err := tc.spanner(true); err != nil { + return err + } + return nil +} + +// Spanner Runs the Spanner consistency tests +func (tc Testcons) Spanner() error { + return tc.spanner(false) +} + +func (Testcons) spanner(coverage bool) error { + return consistencyTest("spanner", emptyEnv, coverage) +} + +// MysqlCover Runs the MySQL consistency tests and generates a coverage report +func (tc Testcons) MysqlCover() error { + if err := tc.mysql(true); err != nil { + return err + } + return nil +} + +// Mysql Runs the MySQL consistency tests +func (tc Testcons) Mysql() error { + return tc.mysql(false) +} + +func (Testcons) mysql(coverage bool) error { + return consistencyTest("mysql", emptyEnv, coverage) +} + +func (tc Testcons) PostgresVer(version string) error { + return tc.postgres(false, version) } // Pgbouncer Run consistency tests for postgres with pgbouncer @@ -197,16 +372,11 @@ func (Testcons) PgbouncerVer(version string) error { return nil } -// Mysql Run consistency tests for mysql -func (Testcons) Mysql() error { - return consistencyTest("mysql", emptyEnv) -} - -func consistencyTest(datastore string, env map[string]string) error { +func consistencyTest(datastore string, env map[string]string, coverage bool) error { + args := []string{"-tags", "ci,docker,datastoreconsistency", "-timeout", "10m", "-run", fmt.Sprintf("TestConsistencyPerDatastore/%s", datastore)} mg.Deps(checkDocker) - return goDirTestWithEnv(".", "./internal/services/integrationtesting/...", - env, - "-tags", "ci,docker,datastoreconsistency", - "-timeout", "10m", - "-run", fmt.Sprintf("TestConsistencyPerDatastore/%s", datastore)) + if coverage { + args = append(args, "-covermode=atomic", fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath("./internal/services/integrationtesting/..."))) + } + return goDirTestWithEnv(".", "./internal/services/integrationtesting/...", env, args...) } diff --git a/magefiles/util.go b/magefiles/util.go index f018c1abf3..fb5e64fe6a 100644 --- a/magefiles/util.go +++ b/magefiles/util.go @@ -26,8 +26,6 @@ func goTest(path string, args ...string) error { func goDirTest(dir string, path string, args ...string) error { testArgs := append([]string{ "test", - "-covermode=atomic", - fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath(path)), "-failfast", "-count=1", }, args...) @@ -37,8 +35,6 @@ func goDirTest(dir string, path string, args ...string) error { func goDirTestWithEnv(dir string, path string, env map[string]string, args ...string) error { testArgs := append([]string{ "test", - "-covermode=atomic", - fmt.Sprintf("-coverprofile=coverage-%s.txt", hashPath(path)), "-failfast", "-count=1", }, args...) @@ -231,8 +227,23 @@ func hashPath(path string) string { return hex.EncodeToString(h[:]) } +// Searches for coverage files recursively +func findCoverageFiles(root string) ([]string, error) { + var files []string + err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if matched, _ := filepath.Match("coverage-*.txt", filepath.Base(path)); matched { + files = append(files, path) + } + return nil + }) + return files, err +} + func combineCoverage() error { - files, err := filepath.Glob("coverage-*.txt") + files, err := findCoverageFiles(".") if err != nil { return err }