From d2c0459cc40570dc9776c5191c35e474c7809fc4 Mon Sep 17 00:00:00 2001 From: Philip Conrad Date: Tue, 12 Nov 2024 12:06:09 -0500 Subject: [PATCH] test: Parallelize package tests in high-cost packages. (#7126) * test: Parallelize package level tests in high-cost packages. This commit adds `t.Parallel()` calls to the beginning of many tests across several Go packages in OPA. The slowest packages (taking ~10s or more) have been instrumented where possible as a proof-of-concept. On a machine with many cores, the tests now will complete as fast as the slowest test per package, instead of the sum of all the tests in a particular package. * server/server_test: Remove 3x tests from parallel set. This commit fixes a data race that could occur in the `server` package tests, because 3x tests were modifying package variables under `internal/version`. These tests now run sequentially, and are not included in the parallel test set. * plugins/bundle/plugin_test: Remove 2x tests from the parallel set. Two tests in this package modified a package variable directly, and as such cannot be safely run in parallel with each other or any other tests in the package. * topdown/*_test: t.Parallel refactors. This commit wraps up a large batch of fairly mechanical refactorings to add t.Parallel() annotations to almost every test under `topdown`. The tests that could not be safely parallelized now have explicit warning comments on them describing why they are not safe to run in parallel. * storage/disk: t.Parallel refactors. This commit bundles up test parallelization changes for the `storage/disk` package, dramatically reducing its execution time. * topdown/net_test: Remove sub-test parallelization. * rego: t.Parallel refactors. This commit includes a bundle of t.Parallel refactoring changes for the `rego` package, including a timer-related bugfix, and a slight change on a cancellation test to reduce its overall cost during test runs (the logic is preserved, but the mandatory timeouts are lower now). * test: Fixes for sporadic test breakages. --------- Signed-off-by: Philip Conrad --- cmd/bench_test.go | 70 +++++++- download/download_test.go | 39 +++++ plugins/bundle/plugin_test.go | 99 ++++++++++- plugins/logs/plugin_test.go | 78 ++++++++- plugins/rest/rest_test.go | 62 +++++++ rego/plugins_test.go | 6 + rego/prepare_test.go | 2 + rego/rego_wasmtarget_test.go | 29 +++- server/server_test.go | 159 ++++++++++++++++- storage/disk/config_test.go | 9 + storage/disk/disk_test.go | 43 +++++ storage/disk/partition_test.go | 4 + storage/disk/paths_test.go | 5 + storage/disk/txn_test.go | 4 + topdown/bindings_test.go | 4 + topdown/builtins_test.go | 1 + topdown/cache/cache_test.go | 25 ++- topdown/cache_test.go | 8 + topdown/cidr_test.go | 2 +- topdown/copypropagation/unionfind_test.go | 11 ++ topdown/crypto_test.go | 35 ++++ topdown/errors_test.go | 5 + topdown/eval_test.go | 30 ++++ topdown/exported_test.go | 21 +++ topdown/glob_test.go | 5 + topdown/http_slow_test.go | 11 +- topdown/http_test.go | 203 ++++++++++++++++++---- topdown/input_test.go | 6 +- topdown/json_test.go | 5 + topdown/jsonschema_test.go | 15 ++ topdown/lineage/lineage_test.go | 5 +- topdown/net_test.go | 2 + topdown/numbers_test.go | 4 + topdown/object_test.go | 2 + topdown/print_test.go | 7 + topdown/query_test.go | 16 +- topdown/regex_template_test.go | 5 + topdown/regex_test.go | 4 + topdown/runtime_test.go | 2 + topdown/save_test.go | 1 + topdown/sets_test.go | 2 + topdown/time_test.go | 1 + topdown/tokens_test.go | 37 ++++ topdown/topdown_partial_test.go | 2 + topdown/topdown_test.go | 32 +++- topdown/trace_test.go | 43 +++++ topdown/uuid_test.go | 5 +- 47 files changed, 1103 insertions(+), 63 deletions(-) diff --git a/cmd/bench_test.go b/cmd/bench_test.go index 2b22683d49..98bce011a5 100644 --- a/cmd/bench_test.go +++ b/cmd/bench_test.go @@ -26,6 +26,8 @@ import ( // Minimize the number of tests that *actually* run the benchmarks, they are pretty slow. // Have one test that exercises the whole flow. func TestRunBenchmark(t *testing.T) { + t.Parallel() + params := testBenchParams() args := []string{"1 + 1"} @@ -61,6 +63,8 @@ func TestRunBenchmark(t *testing.T) { } func TestRunBenchmarkWithQueryImport(t *testing.T) { + t.Parallel() + params := testBenchParams() // We add the rego.v1 import .. params.imports = newrepeatedStringFlag([]string{"rego.v1"}) @@ -99,6 +103,8 @@ func TestRunBenchmarkWithQueryImport(t *testing.T) { } func TestRunBenchmarkE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true @@ -143,6 +149,7 @@ func TestRunBenchmarkE2E(t *testing.T) { } func TestRunBenchmarkE2EWithOPAConfigFile(t *testing.T) { + t.Parallel() fs := map[string]string{ "/config.yaml": `{"decision_logs": {"console": true}}`, @@ -196,6 +203,8 @@ func TestRunBenchmarkE2EWithOPAConfigFile(t *testing.T) { } func TestRunBenchmarkFailFastE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.fail = true // configured to fail on undefined results params.e2e = true @@ -225,6 +234,8 @@ func TestRunBenchmarkFailFastE2E(t *testing.T) { } func TestBenchPartialE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.partial = true params.fail = true @@ -270,6 +281,8 @@ func TestBenchPartialE2E(t *testing.T) { } func TestRunBenchmarkPartialFailFastE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.partial = true params.unknowns = []string{} @@ -300,10 +313,11 @@ func TestRunBenchmarkPartialFailFastE2E(t *testing.T) { if actual != expected { t.Fatalf("\nExpected:\n%s\n\nGot:\n%s\n", expected, actual) } - } func TestRunBenchmarkFailFast(t *testing.T) { + t.Parallel() + params := testBenchParams() params.fail = true // configured to fail on undefined results @@ -345,6 +359,8 @@ func (r *mockBenchRunner) run(ctx context.Context, ectx *evalContext, params ben } func TestBenchPartial(t *testing.T) { + t.Parallel() + params := testBenchParams() params.partial = true params.fail = true @@ -362,6 +378,8 @@ func TestBenchPartial(t *testing.T) { } func TestBenchMainErrPreparing(t *testing.T) { + t.Parallel() + params := testBenchParams() args := []string{"???"} // query compile error var buf bytes.Buffer @@ -377,6 +395,8 @@ func TestBenchMainErrPreparing(t *testing.T) { } func TestBenchMainErrRunningBenchmark(t *testing.T) { + t.Parallel() + params := testBenchParams() args := []string{"1+1"} var buf bytes.Buffer @@ -397,6 +417,8 @@ func TestBenchMainErrRunningBenchmark(t *testing.T) { } func TestBenchMainWithCount(t *testing.T) { + t.Parallel() + params := testBenchParams() args := []string{"1+1"} var buf bytes.Buffer @@ -425,6 +447,8 @@ func TestBenchMainWithCount(t *testing.T) { } func TestBenchMainWithNegativeCount(t *testing.T) { + t.Parallel() + params := testBenchParams() args := []string{"1+1"} var buf bytes.Buffer @@ -489,6 +513,8 @@ func validateBenchMainPrep(t *testing.T, args []string, params benchmarkCommandP } func TestBenchMainWithJSONInputFile(t *testing.T) { + t.Parallel() + params := testBenchParams() files := map[string]string{ "/input.json": `{"x": 42}`, @@ -502,6 +528,8 @@ func TestBenchMainWithJSONInputFile(t *testing.T) { } func TestBenchMainWithYAMLInputFile(t *testing.T) { + t.Parallel() + params := testBenchParams() files := map[string]string{ "/input.yaml": `x: 42`, @@ -515,6 +543,8 @@ func TestBenchMainWithYAMLInputFile(t *testing.T) { } func TestBenchMainInvalidInputFile(t *testing.T) { + t.Parallel() + params := testBenchParams() files := map[string]string{ "/input.yaml": `x: 42`, @@ -536,6 +566,8 @@ func TestBenchMainInvalidInputFile(t *testing.T) { } func TestBenchMainWithJSONInputFileE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true files := map[string]string{ @@ -559,6 +591,8 @@ func TestBenchMainWithJSONInputFileE2E(t *testing.T) { } func TestBenchMainWithYAMLInputFileE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true files := map[string]string{ @@ -582,6 +616,8 @@ func TestBenchMainWithYAMLInputFileE2E(t *testing.T) { } func TestBenchMainInvalidInputFileE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true files := map[string]string{ @@ -605,6 +641,8 @@ func TestBenchMainInvalidInputFileE2E(t *testing.T) { } func TestBenchMainWithBundleData(t *testing.T) { + t.Parallel() + params := testBenchParams() b := testBundle() @@ -637,6 +675,8 @@ func TestBenchMainWithBundleData(t *testing.T) { } func TestBenchMainWithBundleDataE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true @@ -679,6 +719,8 @@ func TestBenchMainWithBundleDataE2E(t *testing.T) { } func TestBenchMainWithDataE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true @@ -716,6 +758,8 @@ func TestBenchMainWithDataE2E(t *testing.T) { } func TestBenchMainBadQueryE2E(t *testing.T) { + t.Parallel() + params := testBenchParams() params.e2e = true args := []string{"foo.bar"} @@ -733,6 +777,8 @@ func TestBenchMainBadQueryE2E(t *testing.T) { } func TestBenchMainCompatibleFlags(t *testing.T) { + t.Parallel() + tests := []struct { note string v0Compatible bool @@ -813,7 +859,10 @@ a[4] { for _, mode := range modes { for _, tc := range tests { + tc := tc // Reassignment prevents loop var scoping issue. (See: https://go.dev/blog/loopvar-preview) t.Run(fmt.Sprintf("%s, %s", tc.note, mode.name), func(t *testing.T) { + t.Parallel() + files := map[string]string{ "mod.rego": tc.module, } @@ -863,6 +912,8 @@ a[4] { } func TestBenchMainWithBundleRegoVersion(t *testing.T) { + t.Parallel() + tests := []struct { note string bundleRegoVersion int @@ -972,7 +1023,10 @@ a contains 4 if { for _, bundleType := range bundleTypeCases { for _, mode := range modes { for _, tc := range tests { + tc := tc // Reassignment prevents loop var scoping issue. (See: https://go.dev/blog/loopvar-preview) t.Run(fmt.Sprintf("%s, %s, %s", bundleType.note, tc.note, mode.name), func(t *testing.T) { + t.Parallel() + files := map[string]string{} if bundleType.tar { @@ -1062,6 +1116,8 @@ a contains 4 if { } func TestRenderBenchmarkResultJSONOutput(t *testing.T) { + t.Parallel() + params := testBenchParams() err := params.outputFormat.Set(evalJSONOutput) if err != nil { @@ -1103,6 +1159,8 @@ func TestRenderBenchmarkResultJSONOutput(t *testing.T) { } func TestRenderBenchmarkResultPrettyOutput(t *testing.T) { + t.Parallel() + params := testBenchParams() params.benchMem = false err := params.outputFormat.Set(evalPrettyOutput) @@ -1140,6 +1198,8 @@ func TestRenderBenchmarkResultPrettyOutput(t *testing.T) { } func TestRenderBenchmarkResultPrettyOutputShowAllocs(t *testing.T) { + t.Parallel() + params := testBenchParams() params.benchMem = true err := params.outputFormat.Set(evalPrettyOutput) @@ -1179,6 +1239,8 @@ func TestRenderBenchmarkResultPrettyOutputShowAllocs(t *testing.T) { } func TestRenderBenchmarkResultGoBenchOutputShowAllocs(t *testing.T) { + t.Parallel() + params := testBenchParams() params.benchMem = true err := params.outputFormat.Set(benchmarkGoBenchOutput) @@ -1203,6 +1265,8 @@ func TestRenderBenchmarkResultGoBenchOutputShowAllocs(t *testing.T) { } func TestRenderBenchmarkErrorJSONOutput(t *testing.T) { + t.Parallel() + params := testBenchParams() err := params.outputFormat.Set(evalJSONOutput) if err != nil { @@ -1244,6 +1308,8 @@ func TestRenderBenchmarkErrorJSONOutput(t *testing.T) { } func TestRenderBenchmarkErrorPrettyOutput(t *testing.T) { + t.Parallel() + params := testBenchParams() err := params.outputFormat.Set(evalPrettyOutput) if err != nil { @@ -1254,6 +1320,8 @@ func TestRenderBenchmarkErrorPrettyOutput(t *testing.T) { } func TestRenderBenchmarkErrorGoBenchOutput(t *testing.T) { + t.Parallel() + params := testBenchParams() err := params.outputFormat.Set(benchmarkGoBenchOutput) if err != nil { diff --git a/download/download_test.go b/download/download_test.go index 2dea57b842..c9a4bcd896 100644 --- a/download/download_test.go +++ b/download/download_test.go @@ -25,6 +25,8 @@ import ( ) func TestStartStop(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -62,6 +64,8 @@ func TestStartStop(t *testing.T) { } func TestStartStopWithBundlePersistence(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -118,6 +122,8 @@ func TestStartStopWithBundlePersistence(t *testing.T) { } func TestStopWithMultipleCalls(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -158,6 +164,8 @@ func TestStopWithMultipleCalls(t *testing.T) { } func TestStartStopWithLazyLoadingMode(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -199,6 +207,8 @@ func TestStartStopWithLazyLoadingMode(t *testing.T) { } func TestStartStopWithDeltaBundleMode(t *testing.T) { + t.Parallel() + ctx := context.Background() updates := make(chan *Update) @@ -234,6 +244,8 @@ func TestStartStopWithDeltaBundleMode(t *testing.T) { } func TestStartStopWithLongPollNotSupported(t *testing.T) { + t.Parallel() + ctx := context.Background() config := Config{} @@ -264,6 +276,8 @@ func TestStartStopWithLongPollNotSupported(t *testing.T) { } func TestStartStopWithLongPollSupportedByServer(t *testing.T) { + t.Parallel() + ctx := context.Background() config := Config{} @@ -300,6 +314,8 @@ func TestStartStopWithLongPollSupportedByServer(t *testing.T) { } func TestStartStopWithLongPollSupported(t *testing.T) { + t.Parallel() + ctx := context.Background() config := Config{} @@ -327,6 +343,8 @@ func TestStartStopWithLongPollSupported(t *testing.T) { } func TestStartStopWithLongPollWithLongTimeout(t *testing.T) { + t.Parallel() + ctx := context.Background() config := Config{} @@ -362,6 +380,7 @@ func TestStartStopWithLongPollWithLongTimeout(t *testing.T) { } func TestEtagCachingLifecycle(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -456,6 +475,7 @@ func TestEtagCachingLifecycle(t *testing.T) { } func TestOneShotWithBundleEtag(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -490,6 +510,8 @@ func TestOneShotWithBundleEtag(t *testing.T) { } func TestOneShotV1Compatible(t *testing.T) { + t.Parallel() + tests := []struct { note string v1Compatible bool @@ -590,6 +612,8 @@ func TestOneShotV1Compatible(t *testing.T) { } func TestOneShotWithBundleRegoVersion(t *testing.T) { + t.Parallel() + tests := []struct { note string bundleRegoVersion int @@ -719,6 +743,7 @@ p contains 1 if { } func TestFailureAuthn(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -734,6 +759,7 @@ func TestFailureAuthn(t *testing.T) { } func TestFailureNotFound(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -749,6 +775,7 @@ func TestFailureNotFound(t *testing.T) { } func TestFailureUnexpected(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -771,6 +798,7 @@ func TestFailureUnexpected(t *testing.T) { } func TestFailureUnexpectedWithResponseBody(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -816,6 +844,8 @@ func TestFailureUnexpectedWithResponseBody(t *testing.T) { } func TestEtagInResponse(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) fixture.server.etagInResponse = true @@ -858,6 +888,7 @@ func TestEtagInResponse(t *testing.T) { } func TestTriggerManual(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -905,6 +936,7 @@ func TestTriggerManual(t *testing.T) { } func TestTriggerManualWithTimeout(t *testing.T) { + t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -952,6 +984,7 @@ func TestTriggerManualWithTimeout(t *testing.T) { } func TestDownloadLongPollNotModifiedOn304(t *testing.T) { + t.Parallel() ctx := context.Background() config := Config{} @@ -980,6 +1013,8 @@ func TestDownloadLongPollNotModifiedOn304(t *testing.T) { } func TestOneShotLongPollingSwitch(t *testing.T) { + t.Parallel() + ctx := context.Background() config := Config{} timeout := int64(3) // this will result in the test server sleeping for 3 seconds @@ -1012,6 +1047,8 @@ func TestOneShotLongPollingSwitch(t *testing.T) { } func TestOneShotNotLongPollingSwitch(t *testing.T) { + t.Parallel() + ctx := context.Background() config := Config{} timeout := int64(3) @@ -1045,6 +1082,8 @@ func TestOneShotNotLongPollingSwitch(t *testing.T) { } func TestWarnOnNonBundleContentType(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) fixture.server.bundles["not-a-bundle"] = bundle.Bundle{} diff --git a/plugins/bundle/plugin_test.go b/plugins/bundle/plugin_test.go index 4650689f73..9232883b3c 100644 --- a/plugins/bundle/plugin_test.go +++ b/plugins/bundle/plugin_test.go @@ -46,6 +46,7 @@ const ( ) func TestPluginOneShot(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -113,6 +114,7 @@ func TestPluginOneShot(t *testing.T) { } func TestPluginOneShotWithAstStore(t *testing.T) { + t.Parallel() ctx := context.Background() store := inmem.NewWithOpts(inmem.OptRoundTripOnWrite(false), inmem.OptReturnASTValuesOnRead(true)) @@ -157,6 +159,8 @@ func TestPluginOneShotWithAstStore(t *testing.T) { } func TestPluginOneShotV1Compatible(t *testing.T) { + t.Parallel() + // Note: modules are parsed before passed to plugin, so any expected errors must be triggered by the compiler stage. tests := []struct { note string @@ -296,6 +300,8 @@ corge contains 1 if { } func TestPluginOneShotWithBundleRegoVersion(t *testing.T) { + t.Parallel() + // Note: modules are parsed before passed to plugin, so any expected errors must be triggered by the compiler stage. tests := []struct { note string @@ -542,6 +548,7 @@ corge contains 1 if { } func TestPluginOneShotWithAuthzSchemaVerification(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -686,6 +693,7 @@ func TestPluginOneShotWithAuthzSchemaVerification(t *testing.T) { } func TestPluginOneShotWithAuthzSchemaVerificationNonDefaultAuthzPath(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -785,6 +793,8 @@ func TestPluginOneShotWithAuthzSchemaVerificationNonDefaultAuthzPath(t *testing. } func TestPluginStartLazyLoadInMem(t *testing.T) { + t.Parallel() + readMode := []struct { note string readAst bool @@ -967,6 +977,7 @@ func TestPluginStartLazyLoadInMem(t *testing.T) { } func TestPluginOneShotDiskStorageMetrics(t *testing.T) { + t.Parallel() test.WithTempFS(nil, func(dir string) { ctx := context.Background() @@ -1072,6 +1083,7 @@ func TestPluginOneShotDiskStorageMetrics(t *testing.T) { } func TestPluginOneShotDeltaBundle(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -1169,6 +1181,7 @@ func TestPluginOneShotDeltaBundle(t *testing.T) { } func TestPluginOneShotDeltaBundleWithAstStore(t *testing.T) { + t.Parallel() ctx := context.Background() store := inmem.NewWithOpts(inmem.OptRoundTripOnWrite(false), inmem.OptReturnASTValuesOnRead(true)) @@ -1267,6 +1280,7 @@ func TestPluginOneShotDeltaBundleWithAstStore(t *testing.T) { } func TestPluginStart(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -1280,6 +1294,8 @@ func TestPluginStart(t *testing.T) { } func TestStop(t *testing.T) { + t.Parallel() + var longPollTimeout int64 = 3 done := make(chan struct{}) tsURLBase := "/opa-test/" @@ -1345,6 +1361,7 @@ func TestStop(t *testing.T) { } func TestPluginOneShotBundlePersistence(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -1446,6 +1463,8 @@ func TestPluginOneShotBundlePersistence(t *testing.T) { } func TestPluginOneShotBundlePersistenceV1Compatible(t *testing.T) { + t.Parallel() + // Note: modules are parsed before passed to plugin, so any expected errors must be triggered by the compiler stage. tests := []struct { note string @@ -1631,6 +1650,8 @@ corge contains 1 if { } func TestPluginOneShotBundlePersistenceWithBundleRegoVersion(t *testing.T) { + t.Parallel() + // Note: modules are parsed before passed to plugin, so any expected errors must be triggered by the compiler stage. tests := []struct { note string @@ -1923,6 +1944,7 @@ corge contains 1 if { } func TestPluginOneShotSignedBundlePersistence(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -2019,6 +2041,7 @@ func TestPluginOneShotSignedBundlePersistence(t *testing.T) { } func TestLoadAndActivateBundlesFromDisk(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -2099,8 +2122,9 @@ func TestLoadAndActivateBundlesFromDisk(t *testing.T) { } } +// Warning: This test modifies package variables, and as +// a result, cannot be run in parallel with other tests. func TestLoadAndActivateBundlesFromDiskReservedChars(t *testing.T) { - ctx := context.Background() manager := getTestManager() @@ -2179,6 +2203,8 @@ func TestLoadAndActivateBundlesFromDiskReservedChars(t *testing.T) { } func TestLoadAndActivateBundlesFromDiskV1Compatible(t *testing.T) { + t.Parallel() + type update struct { modules map[string]string expErrs []string @@ -2426,6 +2452,8 @@ corge contains 2 if { } func TestLoadAndActivateBundlesFromDiskWithBundleRegoVersion(t *testing.T) { + t.Parallel() + // Note: modules are parsed before passed to plugin, so any expected errors must be triggered by the compiler stage. tests := []struct { note string @@ -2654,6 +2682,8 @@ func bundleRegoVersion(v ast.RegoVersion) int { } func TestLoadAndActivateDepBundlesFromDisk(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() @@ -2760,6 +2790,8 @@ is_one(x) if { } func TestLoadAndActivateDepBundlesFromDiskMaxAttempts(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() @@ -2827,6 +2859,7 @@ allow if { } func TestPluginOneShotCompileError(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -2916,10 +2949,11 @@ p contains x`), if err != nil || !reflect.DeepEqual("b", data) { t.Fatalf("Expected data to be intact but got: %v, err: %v", data, err) } - } func TestPluginOneShotHTTPError(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() plugin := New(&Config{}, manager) @@ -2959,6 +2993,7 @@ func TestPluginOneShotHTTPError(t *testing.T) { } func TestPluginOneShotActivationRemovesOld(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -3030,13 +3065,14 @@ func TestPluginOneShotActivationRemovesOld(t *testing.T) { } return nil }) - if err != nil { t.Fatal("Unexpected:", err) } } func TestPluginOneShotActivationConflictingRoots(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() plugin := New(&Config{}, manager) @@ -3104,6 +3140,8 @@ func TestPluginOneShotActivationConflictingRoots(t *testing.T) { } func TestPluginOneShotActivationPrefixMatchingRoots(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() plugin := Plugin{ @@ -3141,7 +3179,6 @@ func TestPluginOneShotActivationPrefixMatchingRoots(t *testing.T) { }}) ensureBundleOverlapStatus(t, &plugin, bundleNames, []bool{false, true}) - } func ensureBundleOverlapStatus(t *testing.T, p *Plugin, bundleNames []string, expectedErrs []bool) { @@ -3159,6 +3196,7 @@ func ensureBundleOverlapStatus(t *testing.T, p *Plugin, bundleNames []string, ex } func TestPluginListener(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -3272,6 +3310,8 @@ func validateStatus(t *testing.T, actual Status, expected string, expectStatusEr } func TestPluginListenerErrorClearedOn304(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() plugin := Plugin{ @@ -3324,6 +3364,8 @@ func TestPluginListenerErrorClearedOn304(t *testing.T) { } func TestPluginBulkListener(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() plugin := Plugin{ @@ -3525,6 +3567,8 @@ p contains x if { x = 1 }` } func TestPluginBulkListenerStatusCopyOnly(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() plugin := Plugin{ @@ -3584,6 +3628,8 @@ p contains x if { x = 1 }` } func TestPluginActivateScopedBundle(t *testing.T) { + t.Parallel() + readMode := []struct { note string readAst bool @@ -3744,6 +3790,7 @@ func TestPluginActivateScopedBundle(t *testing.T) { } func TestPluginSetCompilerOnContext(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -3822,6 +3869,8 @@ func getTestManagerWithOpts(config []byte, stores ...storage.Store) *plugins.Man } func TestPluginReconfigure(t *testing.T) { + t.Parallel() + tsURLBase := "/opa-test/" ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !strings.HasPrefix(r.URL.Path, tsURLBase) { @@ -4019,6 +4068,7 @@ func TestPluginReconfigure(t *testing.T) { } func TestPluginRequestVsDownloadTimestamp(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -4068,6 +4118,7 @@ func TestPluginRequestVsDownloadTimestamp(t *testing.T) { } func TestUpgradeLegacyBundleToMuiltiBundleSameBundle(t *testing.T) { + t.Parallel() ctx := context.Background() manager := getTestManager() @@ -4164,6 +4215,8 @@ func TestUpgradeLegacyBundleToMuiltiBundleSameBundle(t *testing.T) { } func TestUpgradeLegacyBundleToMultiBundleNewBundles(t *testing.T) { + t.Parallel() + ctx := context.Background() manager := getTestManager() @@ -4303,6 +4356,8 @@ func TestUpgradeLegacyBundleToMultiBundleNewBundles(t *testing.T) { } func TestLegacyBundleDataRead(t *testing.T) { + t.Parallel() + readModes := []struct { note string readAst bool @@ -4408,6 +4463,7 @@ func TestLegacyBundleDataRead(t *testing.T) { } func TestSaveBundleToDiskNew(t *testing.T) { + t.Parallel() manager := getTestManager() @@ -4424,6 +4480,8 @@ func TestSaveBundleToDiskNew(t *testing.T) { } func TestSaveBundleToDiskNewConfiguredPersistDir(t *testing.T) { + t.Parallel() + dir := t.TempDir() manager := getTestManager() @@ -4449,6 +4507,7 @@ func TestSaveBundleToDiskNewConfiguredPersistDir(t *testing.T) { } func TestSaveBundleToDiskOverWrite(t *testing.T) { + t.Parallel() manager := getTestManager() @@ -4509,6 +4568,8 @@ func TestSaveBundleToDiskOverWrite(t *testing.T) { } func TestSaveCurrentBundleToDisk(t *testing.T) { + t.Parallel() + srcDir := t.TempDir() bundlePath, err := saveCurrentBundleToDisk(srcDir, getTestRawBundle(t)) @@ -4532,6 +4593,7 @@ func TestSaveCurrentBundleToDisk(t *testing.T) { } func TestLoadBundleFromDisk(t *testing.T) { + t.Parallel() manager := getTestManager() plugin := New(&Config{}, manager) @@ -4566,6 +4628,8 @@ func TestLoadBundleFromDisk(t *testing.T) { } func TestLoadBundleFromDiskV1Compatible(t *testing.T) { + t.Parallel() + popts := ast.ParserOptions{RegoVersion: ast.RegoV1} manager, err := plugins.New(nil, "test-instance-id", inmemtst.New(), plugins.WithParserOptions(popts)) @@ -4626,6 +4690,8 @@ p contains 1 if { } func TestLoadSignedBundleFromDisk(t *testing.T) { + t.Parallel() + manager := getTestManager() plugin := New(&Config{}, manager) @@ -4667,6 +4733,8 @@ func TestLoadSignedBundleFromDisk(t *testing.T) { } func TestGetDefaultBundlePersistPath(t *testing.T) { + t.Parallel() + plugin := New(&Config{}, getTestManager()) path, err := plugin.getBundlePersistPath() if err != nil { @@ -4679,6 +4747,8 @@ func TestGetDefaultBundlePersistPath(t *testing.T) { } func TestConfiguredBundlePersistPath(t *testing.T) { + t.Parallel() + persistPath := "/var/opa" manager := getTestManager() manager.Config.PersistenceDirectory = &persistPath @@ -4695,6 +4765,7 @@ func TestConfiguredBundlePersistPath(t *testing.T) { } func TestPluginUsingFileLoader(t *testing.T) { + t.Parallel() test.WithTempFS(map[string]string{}, func(dir string) { @@ -4749,10 +4820,11 @@ func TestPluginUsingFileLoader(t *testing.T) { t.Fatal("expected successful activation") } }) - } func TestPluginUsingFileLoaderV1Compatible(t *testing.T) { + t.Parallel() + tests := []struct { note string v1Compatible bool @@ -4940,6 +5012,8 @@ p contains 7 if { } func TestPluginUsingFileLoaderWithBundleRegoVersion(t *testing.T) { + t.Parallel() + tests := []struct { note string managerRegoVersion ast.RegoVersion @@ -5255,6 +5329,8 @@ p contains 7 if { } func TestPluginUsingDirectoryLoader(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{ "test.rego": `package test @@ -5290,6 +5366,8 @@ func TestPluginUsingDirectoryLoader(t *testing.T) { } func TestPluginUsingDirectoryLoaderV1Compatible(t *testing.T) { + t.Parallel() + tests := []struct { note string v1Compatible bool @@ -5456,6 +5534,8 @@ p contains 7 if { } func TestPluginUsingDirectoryLoaderWithBundleRegoVersion(t *testing.T) { + t.Parallel() + tests := []struct { note string managerRegoVersion ast.RegoVersion @@ -5748,6 +5828,7 @@ p contains 7 if { } func TestPluginReadBundleEtagFromDiskStore(t *testing.T) { + t.Parallel() // setup fake http server with mock bundle mockBundle := bundle.Bundle{ @@ -5925,6 +6006,8 @@ func TestPluginReadBundleEtagFromDiskStore(t *testing.T) { } func TestPluginStateReconciliationOnReconfigure(t *testing.T) { + t.Parallel() + // setup fake http server with mock bundle mockBundles := map[string]bundle.Bundle{ "b1": { @@ -6122,6 +6205,7 @@ func TestPluginStateReconciliationOnReconfigure(t *testing.T) { } func TestPluginManualTrigger(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -6210,6 +6294,7 @@ func TestPluginManualTrigger(t *testing.T) { } func TestPluginManualTriggerMultipleDiskStorage(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -6359,6 +6444,7 @@ func TestPluginManualTriggerMultipleDiskStorage(t *testing.T) { } func TestPluginManualTriggerMultiple(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -6463,6 +6549,7 @@ func TestPluginManualTriggerMultiple(t *testing.T) { } func TestPluginManualTriggerWithTimeout(t *testing.T) { + t.Parallel() ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -6522,6 +6609,8 @@ func TestPluginManualTriggerWithTimeout(t *testing.T) { } } +// Warning: This test modifies package variables, and as +// a result, cannot be run in parallel with other tests. func TestGetNormalizedBundleName(t *testing.T) { cases := []struct { input string diff --git a/plugins/logs/plugin_test.go b/plugins/logs/plugin_test.go index d904205811..68295616ba 100644 --- a/plugins/logs/plugin_test.go +++ b/plugins/logs/plugin_test.go @@ -64,6 +64,8 @@ func (p *testPlugin) Log(_ context.Context, event EventV1) error { } func TestPluginCustomBackend(t *testing.T) { + t.Parallel() + ctx := context.Background() manager, _ := plugins.New(nil, "test-instance-id", inmem.New()) @@ -92,6 +94,7 @@ func TestPluginCustomBackend(t *testing.T) { } func TestPluginCustomBackendAndHTTPServiceAndConsole(t *testing.T) { + t.Parallel() ctx := context.Background() backend := testPlugin{} @@ -156,6 +159,8 @@ func TestPluginCustomBackendAndHTTPServiceAndConsole(t *testing.T) { } func TestPluginRequestContext(t *testing.T) { + t.Parallel() + ctx := context.Background() manager, _ := plugins.New(nil, "test-instance-id", inmem.New()) @@ -267,6 +272,8 @@ func TestPluginRequestContext(t *testing.T) { } func TestPluginSingleBundle(t *testing.T) { + t.Parallel() + ctx := context.Background() manager, _ := plugins.New(nil, "test-instance-id", inmem.New()) @@ -292,6 +299,8 @@ func TestPluginSingleBundle(t *testing.T) { } func TestPluginErrorNoResult(t *testing.T) { + t.Parallel() + ctx := context.Background() manager, _ := plugins.New(nil, "test-instance-id", inmem.New()) @@ -315,6 +324,8 @@ func TestPluginErrorNoResult(t *testing.T) { } func TestPluginQueriesAndPaths(t *testing.T) { + t.Parallel() + ctx := context.Background() manager, _ := plugins.New(nil, "test-instance-id", inmem.New()) @@ -362,6 +373,7 @@ func TestPluginQueriesAndPaths(t *testing.T) { } func TestPluginStartSameInput(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -442,6 +454,7 @@ func TestPluginStartSameInput(t *testing.T) { } func TestPluginStartChangingInputValues(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -511,6 +524,7 @@ func TestPluginStartChangingInputValues(t *testing.T) { } func TestPluginStartChangingInputKeysAndValues(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -572,6 +586,7 @@ func TestPluginStartChangingInputKeysAndValues(t *testing.T) { } func TestPluginRequeue(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -631,6 +646,8 @@ func logServerInfo(id string, input interface{}, result interface{}) *server.Inf } func TestPluginRequeBufferPreserved(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t, testFixtureOptions{ReportingUploadSizeLimitBytes: 300}) @@ -664,6 +681,8 @@ func TestPluginRequeBufferPreserved(t *testing.T) { } func TestPluginRateLimitInt(t *testing.T) { + t.Parallel() + ctx := context.Background() ts, err := time.Parse(time.RFC3339Nano, "2018-01-01T12:00:00.123456Z") @@ -762,6 +781,8 @@ func TestPluginRateLimitInt(t *testing.T) { } func TestPluginRateLimitFloat(t *testing.T) { + t.Parallel() + ctx := context.Background() ts, err := time.Parse(time.RFC3339Nano, "2018-01-01T12:00:00.123456Z") @@ -769,7 +790,7 @@ func TestPluginRateLimitFloat(t *testing.T) { panic(err) } - numDecisions := 0.1 // 0.1 decision per second ie. 1 decision per 10 seconds + numDecisions := 0.5 // 0.5 decision per second ie. 1 decision per 2 seconds fixture := newTestFixture(t, testFixtureOptions{ ReportingMaxDecisionsPerSecond: float64(numDecisions), ReportingUploadSizeLimitBytes: 300, @@ -810,14 +831,14 @@ func TestPluginRateLimitFloat(t *testing.T) { t.Fatalf("Expected %v bytes written into the encoder but got %v", bytesWritten, fixture.plugin.enc.bytesWritten) } - time.Sleep(5 * time.Second) + time.Sleep(1 * time.Second) _ = fixture.plugin.Log(ctx, event2) // event 2 should not be written into the encoder as rate limit exceeded if fixture.plugin.enc.bytesWritten != bytesWritten { t.Fatalf("Expected %v bytes written into the encoder but got %v", bytesWritten, fixture.plugin.enc.bytesWritten) } - time.Sleep(5 * time.Second) + time.Sleep(1 * time.Second) _ = fixture.plugin.Log(ctx, event2) // event 2 should now be written into the encoder if fixture.plugin.buffer.Len() != 1 { @@ -867,6 +888,8 @@ func TestPluginRateLimitFloat(t *testing.T) { } func TestPluginStatusUpdateHTTPError(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t, testFixtureOptions{ReportingUploadSizeLimitBytes: 300}) @@ -909,6 +932,8 @@ func TestPluginStatusUpdateHTTPError(t *testing.T) { } func TestPluginStatusUpdateEncodingFailure(t *testing.T) { + t.Parallel() + ctx := context.Background() testLogger := test.New() @@ -997,6 +1022,8 @@ func TestPluginStatusUpdateEncodingFailure(t *testing.T) { } func TestPluginStatusUpdateBufferSizeExceeded(t *testing.T) { + t.Parallel() + ctx := context.Background() testLogger := test.New() @@ -1111,6 +1138,8 @@ func TestPluginStatusUpdateBufferSizeExceeded(t *testing.T) { } func TestPluginStatusUpdateRateLimitExceeded(t *testing.T) { + t.Parallel() + ctx := context.Background() testLogger := test.New() @@ -1218,6 +1247,8 @@ func TestPluginStatusUpdateRateLimitExceeded(t *testing.T) { } func TestPluginRateLimitRequeue(t *testing.T) { + t.Parallel() + ctx := context.Background() numDecisions := 100 // 100 decisions per second @@ -1281,6 +1312,8 @@ func TestPluginRateLimitRequeue(t *testing.T) { } func TestPluginRateLimitDropCountStatus(t *testing.T) { + t.Parallel() + ctx := context.Background() testLogger := test.New() @@ -1381,6 +1414,8 @@ func TestPluginRateLimitDropCountStatus(t *testing.T) { } func TestChunkMaxUploadSizeLimitNDBCacheDropping(t *testing.T) { + t.Parallel() + ctx := context.Background() testLogger := test.New() @@ -1432,6 +1467,8 @@ func TestChunkMaxUploadSizeLimitNDBCacheDropping(t *testing.T) { } func TestPluginRateLimitBadConfig(t *testing.T) { + t.Parallel() + manager, _ := plugins.New(nil, "test-instance-id", inmem.New()) bufSize := 40000 @@ -1457,6 +1494,8 @@ func TestPluginRateLimitBadConfig(t *testing.T) { } func TestPluginNoLogging(t *testing.T) { + t.Parallel() + // Given no custom plugin, no service(s) and no console logging configured, // this should not be an error, but neither do we need to initiate the plugin cases := []struct { @@ -1491,6 +1530,8 @@ func TestPluginNoLogging(t *testing.T) { } func TestPluginTriggerManual(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -1570,6 +1611,8 @@ func TestPluginTriggerManual(t *testing.T) { } func TestPluginTriggerManualWithTimeout(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -1666,6 +1709,8 @@ func TestPluginTriggerManualWithTimeout(t *testing.T) { } func TestPluginGracefulShutdownFlushesDecisions(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -1704,6 +1749,8 @@ func TestPluginGracefulShutdownFlushesDecisions(t *testing.T) { } func TestPluginTerminatesAfterGracefulShutdownPeriod(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -1734,6 +1781,8 @@ func TestPluginTerminatesAfterGracefulShutdownPeriod(t *testing.T) { } func TestPluginTerminatesAfterGracefulShutdownPeriodWithoutLogs(t *testing.T) { + t.Parallel() + ctx := context.Background() fixture := newTestFixture(t) @@ -1753,6 +1802,7 @@ func TestPluginTerminatesAfterGracefulShutdownPeriodWithoutLogs(t *testing.T) { } func TestPluginReconfigure(t *testing.T) { + t.Parallel() ctx := context.Background() fixture := newTestFixture(t) @@ -1799,6 +1849,7 @@ func TestPluginReconfigure(t *testing.T) { } func TestPluginReconfigureUploadSizeLimit(t *testing.T) { + t.Parallel() ctx := context.Background() limit := int64(300) @@ -1854,6 +1905,8 @@ func (a appendingPrintHook) Print(_ print.Context, s string) error { } func TestPluginMasking(t *testing.T) { + t.Parallel() + tests := []struct { note string rawPolicy []byte @@ -2264,12 +2317,13 @@ func TestPluginMasking(t *testing.T) { } } - }) } } func TestPluginDrop(t *testing.T) { + t.Parallel() + // Test cases tests := []struct { note string @@ -2365,6 +2419,8 @@ func TestPluginDrop(t *testing.T) { } func TestPluginMaskErrorHandling(t *testing.T) { + t.Parallel() + rawPolicy := []byte(` package system.log import rego.v1 @@ -2439,6 +2495,8 @@ func TestPluginMaskErrorHandling(t *testing.T) { } func TestPluginDropErrorHandling(t *testing.T) { + t.Parallel() + rawPolicy := []byte(` package system.log import rego.v1 @@ -2649,6 +2707,8 @@ func newTestFixture(t *testing.T, opts ...testFixtureOptions) testFixture { } func TestParseConfigUseDefaultServiceNoConsole(t *testing.T) { + t.Parallel() + services := []string{ "s0", "s1", @@ -2671,6 +2731,8 @@ func TestParseConfigUseDefaultServiceNoConsole(t *testing.T) { } func TestParseConfigDefaultServiceWithConsole(t *testing.T) { + t.Parallel() + services := []string{ "s0", "s1", @@ -2693,6 +2755,8 @@ func TestParseConfigDefaultServiceWithConsole(t *testing.T) { } func TestParseConfigTriggerMode(t *testing.T) { + t.Parallel() + cases := []struct { note string config []byte @@ -2753,6 +2817,8 @@ func TestParseConfigTriggerMode(t *testing.T) { } func TestEventV1ToAST(t *testing.T) { + t.Parallel() + input := `{"foo": [{"bar": 1, "baz": {"2": 3.3333333, "4": null}}]}` var goInput interface{} = string(util.MustMarshalJSON(input)) astInput, err := roundtripJSONToAST(goInput) @@ -2952,12 +3018,12 @@ func TestEventV1ToAST(t *testing.T) { if expected.Compare(actual) != 0 { t.Fatalf("\nExpected:\n%s\n\nGot:\n%s\n\n", expected, actual) } - }) } } func TestPluginDefaultResourcePath(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -2995,6 +3061,7 @@ func TestPluginDefaultResourcePath(t *testing.T) { } func TestPluginResourcePathAndPartitionName(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -3036,6 +3103,7 @@ func TestPluginResourcePathAndPartitionName(t *testing.T) { } func TestPluginResourcePath(t *testing.T) { + t.Parallel() ctx := context.Background() diff --git a/plugins/rest/rest_test.go b/plugins/rest/rest_test.go index b526958335..4255262b1a 100644 --- a/plugins/rest/rest_test.go +++ b/plugins/rest/rest_test.go @@ -48,6 +48,8 @@ import ( const keyID = "key1" func TestAuthPluginWithNoAuthPluginLookup(t *testing.T) { + t.Parallel() + authPlugin := "anything" cfg := Config{ Credentials: struct { @@ -71,6 +73,8 @@ func TestAuthPluginWithNoAuthPluginLookup(t *testing.T) { } } +// Note(philipc): Cannot run this test in parallel, due to the t.Setenv calls +// from one of its helper methods. func TestNew(t *testing.T) { tests := []struct { name string @@ -871,6 +875,8 @@ func TestNew(t *testing.T) { } func TestNewWithResponseHeaderTimeout(t *testing.T) { + t.Parallel() + input := `{ "name": "foo", "url": "http://localhost", @@ -888,6 +894,8 @@ func TestNewWithResponseHeaderTimeout(t *testing.T) { } func TestDoWithResponseHeaderTimeout(t *testing.T) { + t.Parallel() + ctx := context.Background() tests := map[string]struct { @@ -949,6 +957,8 @@ func (*tracemock) NewHandler(http.Handler, string, tracing.Options) http.Handler } func TestDoWithDistributedTracingOpts(t *testing.T) { + t.Parallel() + ctx := context.Background() mock := tracemock{} tracing.RegisterHTTPTracing(&mock) @@ -986,6 +996,8 @@ func TestDoWithDistributedTracingOpts(t *testing.T) { } func TestDoWithResponseInClientLog(t *testing.T) { + t.Parallel() + ctx := context.Background() body := "Some Bad Request was received" @@ -1021,6 +1033,8 @@ func TestDoWithResponseInClientLog(t *testing.T) { } func TestDoWithTruncatedResponseInClientLog(t *testing.T) { + t.Parallel() + ctx := context.Background() ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { @@ -1056,6 +1070,8 @@ func TestDoWithTruncatedResponseInClientLog(t *testing.T) { } func TestValidUrl(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, expMethod: "GET", @@ -1107,14 +1123,20 @@ func testBearerToken(t *testing.T, scheme, token string) { } func TestBearerTokenDefaultScheme(t *testing.T) { + t.Parallel() + testBearerToken(t, "", "secret") } func TestBearerTokenCustomScheme(t *testing.T) { + t.Parallel() + testBearerToken(t, "Acmecorp-Token", "secret") } func TestBearerTokenPath(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, expBearerScheme: "", @@ -1177,6 +1199,8 @@ func TestBearerTokenPath(t *testing.T) { } func TestBearerWithCustomCACert(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, tls: true, @@ -1206,6 +1230,8 @@ func TestBearerWithCustomCACert(t *testing.T) { } func TestBearerWithCustomCACertAndSystemCA(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, tls: true, @@ -1236,6 +1262,8 @@ func TestBearerWithCustomCACertAndSystemCA(t *testing.T) { } func TestBearerTokenInvalidConfig(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, expBearerScheme: "", @@ -1272,6 +1300,8 @@ func TestBearerTokenInvalidConfig(t *testing.T) { } func TestBearerTokenIsEncodedForOCI(t *testing.T) { + t.Parallel() + config := `{ "name": "foo", "type": "oci", @@ -1325,6 +1355,8 @@ func newTestBearerClient(t *testing.T, ts *testServer, tokenPath string) *Client } func TestClientCert(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, tls: true, @@ -1383,6 +1415,8 @@ func TestClientCert(t *testing.T) { } func TestClientCertPassword(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, tls: true, @@ -1411,6 +1445,8 @@ func TestClientCertPassword(t *testing.T) { } func TestClientTLSWithCustomCACert(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, tls: true, @@ -1440,6 +1476,8 @@ func TestClientTLSWithCustomCACert(t *testing.T) { } func TestClientTLSWithCustomCACertAndSystemCA(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, tls: true, @@ -1470,6 +1508,8 @@ func TestClientTLSWithCustomCACertAndSystemCA(t *testing.T) { } func TestOauth2ClientCredentials(t *testing.T) { + t.Parallel() + tests := []struct { ts *testServer ots *oauth2TestServer @@ -1540,6 +1580,8 @@ func TestOauth2ClientCredentials(t *testing.T) { } func TestOauth2ClientCredentialsExpiringTokenIsRefreshed(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, expBearerToken: "token_1", @@ -1578,6 +1620,8 @@ func TestOauth2ClientCredentialsExpiringTokenIsRefreshed(t *testing.T) { } func TestOauth2ClientCredentialsNonExpiringTokenIsReused(t *testing.T) { + t.Parallel() + ts := testServer{ t: t, expBearerToken: "token_1", @@ -1606,6 +1650,8 @@ func TestOauth2ClientCredentialsNonExpiringTokenIsReused(t *testing.T) { } func TestOauth2JwtBearerGrantType(t *testing.T) { + t.Parallel() + key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { t.Fatalf("Unexpected error %v", err) @@ -1645,6 +1691,8 @@ func TestOauth2JwtBearerGrantType(t *testing.T) { } func TestOauth2JwtBearerGrantTypePKCS8EncodedPrivateKey(t *testing.T) { + t.Parallel() + key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { t.Fatalf("Unexpected error %v", err) @@ -1690,6 +1738,8 @@ func TestOauth2JwtBearerGrantTypePKCS8EncodedPrivateKey(t *testing.T) { } func TestOauth2JwtBearerGrantTypeEllipticCurveAlgorithm(t *testing.T) { + t.Parallel() + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { t.Fatalf("Unexpected error %v", err) @@ -1740,6 +1790,8 @@ func TestOauth2JwtBearerGrantTypeEllipticCurveAlgorithm(t *testing.T) { } func TestOauth2ClientCredentialsJwtAuthentication(t *testing.T) { + t.Parallel() + key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { t.Fatalf("Unexpected error %v", err) @@ -1786,6 +1838,8 @@ func TestOauth2ClientCredentialsJwtAuthentication(t *testing.T) { // https://github.com/open-policy-agent/opa/issues/3255 func TestS3SigningInstantiationInitializesLogger(t *testing.T) { + t.Parallel() + config := `{ "name": "foo", "url": "https://bundles.example.com", @@ -1817,6 +1871,8 @@ func TestS3SigningInstantiationInitializesLogger(t *testing.T) { } func TestS3SigningMultiCredentialProvider(t *testing.T) { + t.Parallel() + credentialProviderCount := 4 config := `{ "name": "foo", @@ -1866,6 +1922,8 @@ func TestS3SigningMultiCredentialProvider(t *testing.T) { } func TestAWSCredentialServiceChain(t *testing.T) { + t.Parallel() + tests := []struct { name string input string @@ -1962,6 +2020,8 @@ func TestAWSCredentialServiceChain(t *testing.T) { } func TestDebugLoggingRequestMaskAuthorizationHeader(t *testing.T) { + t.Parallel() + token := "secret" plaintext := "plaintext" ts := testServer{t: t, expBearerToken: token} @@ -2509,6 +2569,8 @@ func (*myPluginMock) Prepare(*http.Request) error { return nil } +// Note(philipc): Cannot run this test in parallel, due to the t.Setenv calls +// from one of its helper methods. func TestOauth2ClientCredentialsGrantTypeWithKms(t *testing.T) { // DER-encoded object from KMS as explained here: https://docs.aws.amazon.com/kms/latest/APIReference/API_Sign.html#API_Sign_ResponseSyntax diff --git a/rego/plugins_test.go b/rego/plugins_test.go index 858430231c..0bf1eeeaa2 100644 --- a/rego/plugins_test.go +++ b/rego/plugins_test.go @@ -58,6 +58,8 @@ func (t *testPlugin) Eval(_ context.Context, _ *EvalContext, rt ast.Value) (ast. ))), nil } +// Warning(philipc): This test modifies package variables, which means it cannot +// be run safely in parallel with other tests. func TestTargetViaPlugin(t *testing.T) { tp := testPlugin{} RegisterPlugin("rego.target.foo", &tp) @@ -77,6 +79,8 @@ type defaultPlugin struct { func (*defaultPlugin) IsTarget(t string) bool { return t == "" || t == "foo" } +// Warning(philipc): This test modifies package variables, which means it cannot +// be run safely in parallel with other tests. func TestTargetViaDefaultPlugin(t *testing.T) { t.Run("no target", func(t *testing.T) { tp := defaultPlugin{testPlugin{}} @@ -102,6 +106,8 @@ func TestTargetViaDefaultPlugin(t *testing.T) { }) } +// Warning(philipc): This test modifies package variables, which means it cannot +// be run safely in parallel with other tests. func TestPluginPrepareOptions(t *testing.T) { ctx := context.Background() tp := testPlugin{} diff --git a/rego/prepare_test.go b/rego/prepare_test.go index 41a65d9eb8..c9c309c14e 100644 --- a/rego/prepare_test.go +++ b/rego/prepare_test.go @@ -20,6 +20,8 @@ import ( // used is outside of the rego package. Testing them within the rego package // would be less realistic. func TestPrepareOption(t *testing.T) { + t.Parallel() + t.Run("BuiltinFuncs", func(t *testing.T) { bi := map[string]*topdown.Builtin{ "count": { diff --git a/rego/rego_wasmtarget_test.go b/rego/rego_wasmtarget_test.go index 88b65eddb7..9c2d100985 100644 --- a/rego/rego_wasmtarget_test.go +++ b/rego/rego_wasmtarget_test.go @@ -10,7 +10,6 @@ package rego import ( "context" "fmt" - "github.com/open-policy-agent/opa/metrics" "math/rand" "net/http" "net/http/httptest" @@ -19,6 +18,9 @@ import ( "testing" "time" + "github.com/open-policy-agent/opa/metrics" + "github.com/open-policy-agent/opa/util" + "github.com/fortytw2/leaktest" "github.com/open-policy-agent/opa/ast" @@ -32,6 +34,8 @@ import ( ) func TestPrepareAndEvalWithWasmTarget(t *testing.T) { + t.Parallel() + mod := ` package test default p = false @@ -78,6 +82,8 @@ func TestPrepareAndEvalWithWasmTarget(t *testing.T) { } func TestPrepareAndEvalWithWasmTargetModulesOnCompiler(t *testing.T) { + t.Parallel() + mod := ` package test default p = false @@ -117,6 +123,7 @@ func TestPrepareAndEvalWithWasmTargetModulesOnCompiler(t *testing.T) { } func TestWasmTimeOfDay(t *testing.T) { + t.Parallel() ctx := context.Background() pq, err := New(Query("time.now_ns()"), Target("wasm")).PrepareForEval(ctx) @@ -132,16 +139,19 @@ func TestWasmTimeOfDay(t *testing.T) { } func TestEvalWithContextTimeout(t *testing.T) { + t.Parallel() test.Skip(t) ts := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) { + timer, cancel := util.TimerWithCancel(5 * time.Second) select { case <-r.Context().Done(): // Without this, our test execution would hang waiting for this server to have // served all requests to the end -- unrelated to the behaviour in the client, // so the test would still pass. + cancel() return - case <-time.After(5 * time.Second): + case <-timer.C: return } })) @@ -213,7 +223,7 @@ allow { t.Run(tc.target+"/"+tc.note, func(t *testing.T) { defer leaktest.Check(t)() before := time.Now() - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) defer cancel() pq, err := New( @@ -242,13 +252,17 @@ allow { } func TestRandSeedingOptions(t *testing.T) { + t.Parallel() ctx := context.Background() exp := "0194fdc2-fa2f-4cc0-81d3-ff12045b73c8" for _, tgt := range []string{targetWasm, targetRego} { + tgt := tgt // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tgt, func(t *testing.T) { + t.Parallel() + seed := rand.New(rand.NewSource(0)) // Check expected uuid is returned. @@ -286,13 +300,14 @@ func TestRandSeedingOptions(t *testing.T) { } func TestCompatWithABIMinorVersion1(t *testing.T) { + t.Parallel() + ctx := context.Background() pq, err := New( LoadBundle("testdata/bundle.tar.gz"), Query("data.test.allow"), ).PrepareForEval(ctx) - if err != nil { t.Fatalf("Unexpected error: %s", err) } @@ -306,6 +321,8 @@ func TestCompatWithABIMinorVersion1(t *testing.T) { } func TestEvalWasmWithInterQueryCache(t *testing.T) { + t.Parallel() + newHeaders := map[string][]string{"Cache-Control": {"max-age=290304000, public"}} var requests []*http.Request @@ -347,6 +364,8 @@ func TestEvalWasmWithInterQueryCache(t *testing.T) { } func TestEvalWasmWithHTTPAllowNet(t *testing.T) { + t.Parallel() + var requests []*http.Request ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requests = append(requests, r) @@ -396,6 +415,8 @@ func TestEvalWasmWithHTTPAllowNet(t *testing.T) { } } +// Warning(philipc): This test modifies package variables, which means it cannot +// be run safely in parallel with other tests. func TestRegoTargetWasmAndTargetPluginDisablesIndexingTopdownStages(t *testing.T) { tp := testPlugin{} RegisterPlugin("rego.target.foo", &tp) diff --git a/server/server_test.go b/server/server_test.go index 8e80f77117..2d660c0ce0 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -70,18 +70,23 @@ type tr struct { } func TestUnversionedGetHealth(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqUnversioned(http.MethodGet, "/health", "") validateDiagnosticRequest(t, f, req, 200, `{}`) } func TestUnversionedGetHealthBundleNoBundleSet(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqUnversioned(http.MethodGet, "/health?bundles=true", "") validateDiagnosticRequest(t, f, req, 200, `{}`) } func TestUnversionedGetHealthCheckOnlyBundlePlugin(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -102,6 +107,7 @@ func TestUnversionedGetHealthCheckOnlyBundlePlugin(t *testing.T) { } func TestUnversionedGetHealthCheckDiscoveryWithBundle(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -129,6 +135,7 @@ func TestUnversionedGetHealthCheckDiscoveryWithBundle(t *testing.T) { } func TestUnversionedGetHealthCheckBundleActivationSingleLegacy(t *testing.T) { + t.Parallel() // Initialize the server as if there is no bundle plugin @@ -156,6 +163,7 @@ func TestUnversionedGetHealthCheckBundleActivationSingleLegacy(t *testing.T) { } func TestBundlesReady(t *testing.T) { + t.Parallel() cases := []struct { note string @@ -247,6 +255,7 @@ func TestBundlesReady(t *testing.T) { } func TestUnversionedGetHealthCheckDiscoveryWithPlugins(t *testing.T) { + t.Parallel() // Use the same server through the cases, the status updates apply incrementally to it. f := newFixture(t) @@ -387,6 +396,7 @@ func TestUnversionedGetHealthCheckDiscoveryWithPlugins(t *testing.T) { } func TestUnversionedGetHealthCheckDiscoveryWithPluginsAndExclude(t *testing.T) { + t.Parallel() // Use the same server through the cases, the status updates apply incrementally to it. f := newFixture(t) @@ -499,6 +509,7 @@ func TestUnversionedGetHealthCheckDiscoveryWithPluginsAndExclude(t *testing.T) { } func TestUnversionedGetHealthCheckBundleAndPlugins(t *testing.T) { + t.Parallel() cases := []struct { note string @@ -588,12 +599,16 @@ func TestUnversionedGetHealthCheckBundleAndPlugins(t *testing.T) { } func TestUnversionedGetHealthWithPolicyMissing(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqUnversioned(http.MethodGet, "/health/live", "") validateDiagnosticRequest(t, f, req, 500, `{"error":"health check (data.system.health.live) was undefined"}`) } func TestUnversionedGetHealthWithPolicyUpdates(t *testing.T) { + t.Parallel() + ctx := context.Background() store := inmem.New() txn := storage.NewTransactionOrDie(ctx, store, storage.WriteParams) @@ -634,6 +649,8 @@ func TestUnversionedGetHealthWithPolicyUpdates(t *testing.T) { } func TestUnversionedGetHealthWithPolicyUsingPlugins(t *testing.T) { + t.Parallel() + ctx := context.Background() store := inmem.New() txn := storage.NewTransactionOrDie(ctx, store, storage.WriteParams) @@ -696,6 +713,8 @@ func TestUnversionedGetHealthWithPolicyUsingPlugins(t *testing.T) { } func TestDataV0(t *testing.T) { + t.Parallel() + testMod1 := `package test import rego.v1 @@ -757,6 +776,8 @@ func TestDataV0(t *testing.T) { // Tests that the responses for (theoretically) valid resources but with forbidden methods return the proper status code func Test405StatusCodev1(t *testing.T) { + t.Parallel() + tests := []struct { note string reqs []tr @@ -820,6 +841,8 @@ func Test405StatusCodev1(t *testing.T) { // Tests that the responses for (theoretically) valid resources but with forbidden methods return the proper status code func Test405StatusCodev0(t *testing.T) { + t.Parallel() + tests := []struct { note string reqs []tr @@ -853,6 +876,7 @@ func Test405StatusCodev0(t *testing.T) { } func TestCompileV1(t *testing.T) { + t.Parallel() mod := `package test import rego.v1 @@ -1016,6 +1040,8 @@ func TestCompileV1(t *testing.T) { } func TestCompileV1Observability(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() test.WithTempFS(nil, func(root string) { @@ -1062,6 +1088,8 @@ func TestCompileV1Observability(t *testing.T) { } func TestCompileV1UnsafeBuiltin(t *testing.T) { + t.Parallel() + f := newFixture(t) query := `{"query": "http.send({\"method\": \"get\", \"url\": \"foo.com\"}, x)"}` @@ -1087,6 +1115,8 @@ func TestCompileV1UnsafeBuiltin(t *testing.T) { } func TestDataV1Redirection(t *testing.T) { + t.Parallel() + f := newFixture(t) // Testing redirect at the root level if err := f.v1(http.MethodPut, "/data/", `{"foo": [1,2,3]}`, 301, ""); err != nil { @@ -1121,6 +1151,8 @@ func TestDataV1Redirection(t *testing.T) { } func TestDataV1(t *testing.T) { + t.Parallel() + testMod1 := `package testmod import rego.v1 @@ -1531,6 +1563,8 @@ p = true if { false }` } func TestDataV1Metrics(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() test.WithTempFS(nil, func(root string) { @@ -1569,6 +1603,8 @@ func TestDataV1Metrics(t *testing.T) { } func TestConfigV1(t *testing.T) { + t.Parallel() + f := newFixture(t) c := []byte(`{"services": { @@ -1633,6 +1669,7 @@ func TestConfigV1(t *testing.T) { } func TestDataYAML(t *testing.T) { + t.Parallel() testMod1 := `package testmod import rego.v1 @@ -1685,6 +1722,8 @@ main = data.testmod.gt1`, 200, ""); err != nil { } func TestDataPutV1IfNoneMatch(t *testing.T) { + t.Parallel() + f := newFixture(t) if err := f.v1(http.MethodPut, "/data/a/b/c", "0", 204, ""); err != nil { t.Fatalf("Unexpected error from PUT /data/a/b/c: %v", err) @@ -1734,6 +1773,8 @@ func generateJSONBenchmarkData(k, v int) map[string]interface{} { // Ref: https://github.com/open-policy-agent/opa/issues/6804 func TestDataGetV1CompressedRequestWithAuthorizer(t *testing.T) { + t.Parallel() + tests := []struct { note string payload []byte @@ -1840,6 +1881,8 @@ allow if { // Tests to ensure the body size limits work, for compressed requests. func TestDataPostV1CompressedDecodingLimits(t *testing.T) { + t.Parallel() + defaultMaxLen := int64(1024) defaultGzipMaxLen := int64(1024) @@ -2035,6 +2078,8 @@ allow if { } func TestDataPostV0CompressedResponse(t *testing.T) { + t.Parallel() + tests := []struct { gzipMinLength int compressedResponse bool @@ -2101,6 +2146,8 @@ allow_request if { flag == true } } func TestDataPostV1CompressedResponse(t *testing.T) { + t.Parallel() + tests := []struct { gzipMinLength int compressedResponse bool @@ -2174,6 +2221,8 @@ hello if { } func TestCompileV1CompressedResponse(t *testing.T) { + t.Parallel() + tests := []struct { gzipMinLength int compressedResponse bool @@ -2263,6 +2312,8 @@ func TestCompileV1CompressedResponse(t *testing.T) { } func TestDataPostV0CompressedRequest(t *testing.T) { + t.Parallel() + f := newFixture(t) // create the policy err := f.v1(http.MethodPut, "/policies/test", `package opa.examples @@ -2289,6 +2340,8 @@ allow_request if { flag == true } } func TestDataPostV1CompressedRequest(t *testing.T) { + t.Parallel() + f := newFixture(t) // create the policy err := f.v1(http.MethodPut, "/policies/test", `package test @@ -2326,6 +2379,8 @@ hello if { } func TestCompileV1CompressedRequest(t *testing.T) { + t.Parallel() + f := newFixture(t) // create the policy mod := `package test @@ -2378,6 +2433,7 @@ func TestCompileV1CompressedRequest(t *testing.T) { } func TestBundleScope(t *testing.T) { + t.Parallel() ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -2503,6 +2559,7 @@ func TestBundleScope(t *testing.T) { } func TestBundleScopeMultiBundle(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -2568,6 +2625,8 @@ func TestBundleScopeMultiBundle(t *testing.T) { } func TestBundleNoRoots(t *testing.T) { + t.Parallel() + ctx := context.Background() f := newFixture(t) @@ -2705,6 +2764,8 @@ func TestDataUpdate(t *testing.T) { } func TestDataGetExplainFull(t *testing.T) { + t.Parallel() + f := newFixture(t) err := f.v1(http.MethodPut, "/data/x", `{"a":1,"b":2}`, 204, "") @@ -2794,6 +2855,7 @@ func TestDataGetExplainFull(t *testing.T) { } func TestDataPostWithActiveStoreWriteTxn(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -2832,6 +2894,8 @@ p = [1, 2, 3, 4] if { true }`, 200, "") } func TestDataPostExplain(t *testing.T) { + t.Parallel() + f := newFixture(t) err := f.v1(http.MethodPut, "/policies/test", `package test @@ -2872,6 +2936,8 @@ p = [1, 2, 3, 4] if { true }`, 200, "") } func TestDataPostExplainNotes(t *testing.T) { + t.Parallel() + f := newFixture(t) err := f.v1(http.MethodPut, "/policies/test", ` @@ -2916,8 +2982,9 @@ func TestDataPostExplainNotes(t *testing.T) { } } +// Warning(philipc): This test modifies package variables in the version +// package, which means it cannot be run in parallel with other tests. func TestDataProvenanceSingleBundle(t *testing.T) { - f := newFixture(t) // Dummy up since we are not using ld... @@ -2986,8 +3053,9 @@ func TestDataProvenanceSingleBundle(t *testing.T) { } } +// Warning(philipc): This test modifies package variables in the version +// package, which means it cannot be run in parallel with other tests. func TestDataProvenanceSingleFileBundle(t *testing.T) { - f := newFixture(t) // Dummy up since we are not using ld... @@ -3034,8 +3102,9 @@ func TestDataProvenanceSingleFileBundle(t *testing.T) { } } +// Warning(philipc): This test modifies package variables in the version +// package, which means it cannot be run in parallel with other tests. func TestDataProvenanceMultiBundle(t *testing.T) { - f := newFixture(t) // Dummy up since we are not using ld... @@ -3145,6 +3214,8 @@ func TestDataProvenanceMultiBundle(t *testing.T) { } func TestDataMetricsEval(t *testing.T) { + t.Parallel() + // These tests all use the POST /v1/data API with ?metrics appended. // We're setting up the disk store because that injects a few extra metrics, // which storage/inmem does not. @@ -3222,6 +3293,7 @@ func assertMetricsExist(t *testing.T, metrics types.MetricsV1, expected []string } func TestV1Pretty(t *testing.T) { + t.Parallel() f := newFixture(t) err := f.v1(http.MethodPatch, "/data/x", `[{"op": "add", "path":"/", "value": [1,2,3,4]}]`, 204, "") @@ -3249,6 +3321,8 @@ func TestV1Pretty(t *testing.T) { } func TestPoliciesPutV1(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqV1(http.MethodPut, "/policies/1", testMod) @@ -3269,6 +3343,8 @@ func TestPoliciesPutV1(t *testing.T) { } func TestPoliciesPutV1Empty(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqV1(http.MethodPut, "/policies/1", "") @@ -3280,6 +3356,8 @@ func TestPoliciesPutV1Empty(t *testing.T) { } func TestPoliciesPutV1ParseError(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqV1(http.MethodPut, "/policies/test", ` package a.b.c @@ -3334,6 +3412,8 @@ func TestPoliciesPutV1ParseError(t *testing.T) { } func TestPoliciesPutV1CompileError(t *testing.T) { + t.Parallel() + f := newFixture(t) req := newReqV1(http.MethodPut, "/policies/test", `package a.b.c @@ -3370,6 +3450,8 @@ q[x] { p[x] }`, } func TestPoliciesPutV1Noop(t *testing.T) { + t.Parallel() + f := newFixture(t) err := f.v1("PUT", "/policies/test?metrics", `package foo`, 200, "") if err != nil { @@ -3422,6 +3504,8 @@ func TestPoliciesPutV1Noop(t *testing.T) { } func TestPoliciesListV1(t *testing.T) { + t.Parallel() + f := newFixture(t) putPolicy(t, f, testMod) @@ -3473,6 +3557,8 @@ func assertListPolicy(t *testing.T, f *fixture, expected []types.PolicyV1) { } func TestPoliciesGetV1(t *testing.T) { + t.Parallel() + f := newFixture(t) put := newReqV1(http.MethodPut, "/policies/1", testMod) f.server.Handler.ServeHTTP(f.recorder, put) @@ -3503,6 +3589,8 @@ func TestPoliciesGetV1(t *testing.T) { } func TestPoliciesDeleteV1(t *testing.T) { + t.Parallel() + f := newFixture(t) put := newReqV1(http.MethodPut, "/policies/1", testMod) f.server.Handler.ServeHTTP(f.recorder, put) @@ -3538,6 +3626,8 @@ func TestPoliciesDeleteV1(t *testing.T) { } func TestPoliciesPathSlashes(t *testing.T) { + t.Parallel() + f := newFixture(t) if err := f.v1(http.MethodPut, "/policies/a/b/c.rego", testMod, 200, ""); err != nil { t.Fatalf("Unexpected error: %v", err) @@ -3548,6 +3638,8 @@ func TestPoliciesPathSlashes(t *testing.T) { } func TestPoliciesUrlEncoded(t *testing.T) { + t.Parallel() + const expectedPolicyID = "/a policy/another-component" var urlEscapedPolicyID = url.PathEscape(expectedPolicyID) f := newFixture(t) @@ -3590,6 +3682,7 @@ func TestPoliciesUrlEncoded(t *testing.T) { } func TestStatusV1(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -3680,6 +3773,7 @@ func TestStatusV1(t *testing.T) { } func TestStatusV1MetricsWithSystemAuthzPolicy(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -3849,6 +3943,8 @@ func TestStatusV1MetricsWithSystemAuthzPolicy(t *testing.T) { } func TestQueryPostBasic(t *testing.T) { + t.Parallel() + f := newFixture(t) f.server, _ = New(). WithAddresses([]string{"localhost:8182"}). @@ -3873,6 +3969,7 @@ func TestQueryPostBasic(t *testing.T) { } func TestDecisionIDs(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -3924,6 +4021,8 @@ func TestDecisionIDs(t *testing.T) { } func TestDecisionLoggingWithHTTPRequestContext(t *testing.T) { + t.Parallel() + f := newFixture(t) decisions := []*Info{} @@ -3968,6 +4067,8 @@ func TestDecisionLoggingWithHTTPRequestContext(t *testing.T) { } func TestDecisionLogging(t *testing.T) { + t.Parallel() + f := newFixture(t) decisions := []*Info{} @@ -4158,6 +4259,7 @@ func TestDecisionLogging(t *testing.T) { } func TestDecisionLogErrorMessage(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -4174,6 +4276,8 @@ func TestDecisionLogErrorMessage(t *testing.T) { } func TestQueryV1(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() test.WithTempFS(nil, func(root string) { @@ -4221,6 +4325,8 @@ func TestQueryV1(t *testing.T) { } func TestBadQueryV1(t *testing.T) { + t.Parallel() + f := newFixture(t) expectedErr := `{ @@ -4250,6 +4356,8 @@ func TestBadQueryV1(t *testing.T) { } func TestQueryV1UnsafeBuiltin(t *testing.T) { + t.Parallel() + f := newFixture(t) query := `/query?q=http.send({"method": "get", "url": "foo.com"}, x)` @@ -4276,6 +4384,7 @@ func TestQueryV1UnsafeBuiltin(t *testing.T) { } func TestUnversionedPost(t *testing.T) { + t.Parallel() f := newFixture(t) @@ -4398,6 +4507,8 @@ func TestUnversionedPost(t *testing.T) { } func TestQueryV1Explain(t *testing.T) { + t.Parallel() + f := newFixture(t) get := newReqV1(http.MethodGet, `/query?q=a=[1,2,3]%3Ba[i]=x&explain=debug`, "") f.server.Handler.ServeHTTP(f.recorder, get) @@ -4420,6 +4531,7 @@ func TestQueryV1Explain(t *testing.T) { } func TestAuthorization(t *testing.T) { + t.Parallel() ctx := context.Background() store := inmem.New() @@ -4541,6 +4653,7 @@ func TestAuthorization(t *testing.T) { } func TestAuthorizationUsesInterQueryCache(t *testing.T) { + t.Parallel() ctx := context.Background() store := inmem.New() @@ -4629,6 +4742,7 @@ func validateAuthorizedRequest(t *testing.T, s *Server, req *http.Request, exp i } func TestServerUsesAuthorizerParsedBody(t *testing.T) { + t.Parallel() // Construct a request w/ a different message body (this should never happen.) req, err := http.NewRequest(http.MethodPost, "http://localhost:8182/v1/data/test/echo", bytes.NewBufferString(`{"foo": "bad"}`)) @@ -4679,6 +4793,8 @@ func TestServerUsesAuthorizerParsedBody(t *testing.T) { } func TestServerReloadTrigger(t *testing.T) { + t.Parallel() + f := newFixture(t) store := f.server.store ctx := context.Background() @@ -4699,6 +4815,8 @@ func TestServerReloadTrigger(t *testing.T) { } func TestServerClearsCompilerConflictCheck(t *testing.T) { + t.Parallel() + f := newFixture(t) store := f.server.store ctx := context.Background() @@ -4777,6 +4895,7 @@ func (queryBindingErrStore) Unregister(context.Context, storage.Transaction, str } func TestQueryBindingIterationError(t *testing.T) { + t.Parallel() ctx := context.Background() mock := &queryBindingErrStore{} @@ -5091,6 +5210,8 @@ func mustUnmarshalTrace(t types.TraceV1) (trace types.TraceV1Raw) { } func TestShutdown(t *testing.T) { + t.Parallel() + f := newFixture(t, func(s *Server) { s.WithDiagnosticAddresses([]string{":8443"}) }) @@ -5115,6 +5236,8 @@ func TestShutdown(t *testing.T) { } func TestShutdownError(t *testing.T) { + t.Parallel() + f := newFixture(t, func(s *Server) { s.WithDiagnosticAddresses([]string{":8443"}) }) @@ -5140,6 +5263,8 @@ func TestShutdownError(t *testing.T) { } func TestShutdownMultipleErrors(t *testing.T) { + t.Parallel() + f := newFixture(t, func(s *Server) { s.WithDiagnosticAddresses([]string{":8443"}) }) @@ -5173,6 +5298,8 @@ func TestShutdownMultipleErrors(t *testing.T) { } func TestAddrsNoListeners(t *testing.T) { + t.Parallel() + s := New() a := s.Addrs() if len(a) != 0 { @@ -5181,6 +5308,8 @@ func TestAddrsNoListeners(t *testing.T) { } func TestAddrsWithEmptyListenAddr(t *testing.T) { + t.Parallel() + s := New() s.httpListeners = []httpListener{&mockHTTPListener{}} a := s.Addrs() @@ -5190,6 +5319,8 @@ func TestAddrsWithEmptyListenAddr(t *testing.T) { } func TestAddrsWithListenAddr(t *testing.T) { + t.Parallel() + s := New() s.httpListeners = []httpListener{&mockHTTPListener{addrs: ":8181"}} a := s.Addrs() @@ -5199,6 +5330,8 @@ func TestAddrsWithListenAddr(t *testing.T) { } func TestAddrsWithMixedListenerAddr(t *testing.T) { + t.Parallel() + s := New() addrs := []string{":8181", "", "unix:///var/tmp/foo.sock"} expected := []string{":8181", "unix:///var/tmp/foo.sock"} @@ -5228,6 +5361,8 @@ func TestAddrsWithMixedListenerAddr(t *testing.T) { } func TestDiagnosticAddrsNoListeners(t *testing.T) { + t.Parallel() + s := New() a := s.DiagnosticAddrs() if len(a) != 0 { @@ -5236,6 +5371,8 @@ func TestDiagnosticAddrsNoListeners(t *testing.T) { } func TestDiagnosticAddrsWithEmptyListenAddr(t *testing.T) { + t.Parallel() + s := New() s.httpListeners = []httpListener{&mockHTTPListener{t: diagnosticListenerType}} a := s.DiagnosticAddrs() @@ -5245,6 +5382,8 @@ func TestDiagnosticAddrsWithEmptyListenAddr(t *testing.T) { } func TestDiagnosticAddrsWithListenAddr(t *testing.T) { + t.Parallel() + s := New() s.httpListeners = []httpListener{&mockHTTPListener{addrs: ":8181", t: diagnosticListenerType}} a := s.DiagnosticAddrs() @@ -5254,6 +5393,8 @@ func TestDiagnosticAddrsWithListenAddr(t *testing.T) { } func TestDiagnosticAddrsWithMixedListenerAddr(t *testing.T) { + t.Parallel() + s := New() addrs := []string{":8181", "", "unix:///var/tmp/foo.sock"} expected := []string{":8181", "unix:///var/tmp/foo.sock"} @@ -5283,6 +5424,8 @@ func TestDiagnosticAddrsWithMixedListenerAddr(t *testing.T) { } func TestMixedAddrTypes(t *testing.T) { + t.Parallel() + s := New() s.httpListeners = []httpListener{} @@ -5321,6 +5464,8 @@ func TestMixedAddrTypes(t *testing.T) { } func TestCustomRoute(t *testing.T) { + t.Parallel() + router := mux.NewRouter() router.HandleFunc("/customEndpoint", func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(`{"myCustomResponse": true}`)) // ignore error @@ -5342,6 +5487,8 @@ func TestCustomRoute(t *testing.T) { } func TestDiagnosticRoutes(t *testing.T) { + t.Parallel() + cases := []struct { path string should404 bool @@ -5386,6 +5533,8 @@ func TestDiagnosticRoutes(t *testing.T) { } func TestDistributedTracingEnabled(t *testing.T) { + t.Parallel() + c := []byte(`{"distributed_tracing": { "type": "grpc" }}`) @@ -5398,6 +5547,8 @@ func TestDistributedTracingEnabled(t *testing.T) { } func TestDistributedTracingResourceAttributes(t *testing.T) { + t.Parallel() + c := []byte(`{"distributed_tracing": { "type": "grpc", "service_name": "my-service", @@ -5425,6 +5576,7 @@ func TestDistributedTracingResourceAttributes(t *testing.T) { } func TestCertPoolReloading(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -5836,6 +5988,7 @@ func TestCertPoolReloading(t *testing.T) { } func TestCertReloading(t *testing.T) { + t.Parallel() ctx := context.Background() diff --git a/storage/disk/config_test.go b/storage/disk/config_test.go index 4d90e90858..c0a976a36e 100644 --- a/storage/disk/config_test.go +++ b/storage/disk/config_test.go @@ -16,6 +16,8 @@ import ( ) func TestNewFromConfig(t *testing.T) { + t.Parallel() + tmpdir := t.TempDir() for _, tc := range []struct { @@ -101,6 +103,8 @@ storage: } func TestDataDirPrefix(t *testing.T) { + t.Parallel() + ctx := context.Background() tmpdir := t.TempDir() @@ -130,6 +134,8 @@ func TestDataDirPrefix(t *testing.T) { } func TestBadgerConfigFromOptions(t *testing.T) { + t.Parallel() + type check func(*testing.T, badger.Options) checks := func(c ...check) []check { return c @@ -219,7 +225,10 @@ func TestBadgerConfigFromOptions(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + act, _ := badgerConfigFromOptions(tc.opts) for _, check := range tc.checks { check(t, act) diff --git a/storage/disk/disk_test.go b/storage/disk/disk_test.go index f28a749eed..351410ab47 100644 --- a/storage/disk/disk_test.go +++ b/storage/disk/disk_test.go @@ -105,6 +105,7 @@ func (*testDump) do(t *testing.T, s *Store) { } func TestPolicies(t *testing.T) { + t.Parallel() test.WithTempFS(map[string]string{}, func(dir string) { ctx := context.Background() @@ -170,12 +171,16 @@ func TestPolicies(t *testing.T) { } func TestTruncateAbsoluteStoragePath(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { runTruncateTest(t, dir) }) } func TestTruncateRelativeStoragePath(t *testing.T) { + t.Parallel() + dir := "foobar" err := os.Mkdir(dir, 0700) if err != nil { @@ -306,6 +311,8 @@ func runTruncateTest(t *testing.T, dir string) { } func TestTruncateMultipleTxn(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { ctx := context.Background() s, err := New(ctx, logging.NewNoOpLogger(), nil, Options{Dir: dir, Partitions: nil, Badger: "memtablesize=4000;valuethreshold=600"}) @@ -392,6 +399,7 @@ func TestTruncateMultipleTxn(t *testing.T) { } func TestDataPartitioningValidation(t *testing.T) { + t.Parallel() closeFn := func(ctx context.Context, s *Store) { t.Helper() @@ -585,6 +593,8 @@ func TestDataPartitioningValidation(t *testing.T) { } func TestDataPartitioningSystemPartitions(t *testing.T) { + t.Parallel() + ctx := context.Background() dir := "unused" @@ -604,6 +614,7 @@ func TestDataPartitioningSystemPartitions(t *testing.T) { } func TestDataPartitioningReadsAndWrites(t *testing.T) { + t.Parallel() tests := []struct { note string @@ -1133,7 +1144,10 @@ func TestDataPartitioningReadsAndWrites(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { partitions := make([]storage.Path, len(tc.partitions)) @@ -1179,6 +1193,8 @@ func TestDataPartitioningReadsAndWrites(t *testing.T) { } func TestDataPartitioningReadNotFoundErrors(t *testing.T) { + t.Parallel() + tests := []struct { note string partitions []string @@ -1285,7 +1301,10 @@ func TestDataPartitioningReadNotFoundErrors(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { partitions := make([]storage.Path, len(tc.partitions)) @@ -1323,6 +1342,8 @@ func TestDataPartitioningReadNotFoundErrors(t *testing.T) { } func TestDataPartitioningWriteNotFoundErrors(t *testing.T) { + t.Parallel() + tests := []struct { note string partitions []string @@ -1437,7 +1458,10 @@ func TestDataPartitioningWriteNotFoundErrors(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { partitions := make([]storage.Path, len(tc.partitions)) @@ -1480,8 +1504,13 @@ func TestDataPartitioningWriteNotFoundErrors(t *testing.T) { } func TestDataPartitioningWriteInvalidPatchError(t *testing.T) { + t.Parallel() + for _, pt := range []string{"/*", "/foo"} { + pt := pt // copy for capturing loop variable (not needed in Go 1.22+) t.Run(pt, func(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { ctx := context.Background() s, err := New(ctx, logging.NewNoOpLogger(), nil, Options{Dir: dir, Partitions: []storage.Path{ @@ -1536,6 +1565,8 @@ func executeTestWrite(ctx context.Context, t *testing.T, s storage.Store, x test } func TestDiskTriggers(t *testing.T) { + t.Parallel() + test.WithTempFS(map[string]string{}, func(dir string) { ctx := context.Background() store, err := New(ctx, logging.NewNoOpLogger(), nil, Options{Dir: dir, Partitions: []storage.Path{ @@ -1606,6 +1637,8 @@ func TestDiskTriggers(t *testing.T) { } func TestLookup(t *testing.T) { + t.Parallel() + cases := []struct { note string input []byte @@ -1639,7 +1672,9 @@ func TestLookup(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() path, ok := storage.ParsePathEscaped("/" + tc.path) if !ok { @@ -1672,9 +1707,13 @@ func TestLookup(t *testing.T) { } func TestDiskDiagnostics(t *testing.T) { + t.Parallel() + ctx := context.Background() t.Run("no partitions", func(t *testing.T) { + t.Parallel() + test.WithTempFS(nil, func(dir string) { buf := bytes.Buffer{} logger := logging.New() @@ -1736,6 +1775,8 @@ func TestDiskDiagnostics(t *testing.T) { }) t.Run("two partitions", func(t *testing.T) { + t.Parallel() + test.WithTempFS(nil, func(dir string) { opts := Options{ Dir: dir, @@ -1803,6 +1844,8 @@ func TestDiskDiagnostics(t *testing.T) { }) t.Run("patterned partitions", func(t *testing.T) { + t.Parallel() + test.WithTempFS(nil, func(dir string) { opts := Options{Dir: dir, Partitions: []storage.Path{ diff --git a/storage/disk/partition_test.go b/storage/disk/partition_test.go index 29fc830ca8..cc295efbec 100644 --- a/storage/disk/partition_test.go +++ b/storage/disk/partition_test.go @@ -12,6 +12,7 @@ import ( ) func TestPartitionTrie(t *testing.T) { + t.Parallel() // Build simple trie root := buildPartitionTrie([]storage.Path{ @@ -104,7 +105,10 @@ func TestPartitionTrie(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(strings.TrimPrefix(tc.path, "/"), func(t *testing.T) { + t.Parallel() + gotIdx, gotPtr := root.Find(storage.MustParsePath(tc.path)) if gotIdx != tc.wantIdx || gotPtr != tc.wantPtr { t.Fatalf("expected (%d, %v) but got (%d, %v)", tc.wantIdx, tc.wantPtr, gotIdx, gotPtr) diff --git a/storage/disk/paths_test.go b/storage/disk/paths_test.go index 92993a2d89..f592c08889 100644 --- a/storage/disk/paths_test.go +++ b/storage/disk/paths_test.go @@ -11,6 +11,8 @@ import ( ) func TestIsDisjoint(t *testing.T) { + t.Parallel() + paths := func(ps ...string) pathSet { ret := make([]storage.Path, len(ps)) for i := range ps { @@ -49,7 +51,10 @@ func TestIsDisjoint(t *testing.T) { overlapped: true, }, } { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + act := tc.ps.IsDisjoint() if !tc.overlapped != act { t.Errorf("path set: %v, disjoint == %v, expected %v", tc.ps, act, !tc.overlapped) diff --git a/storage/disk/txn_test.go b/storage/disk/txn_test.go index 2f2d4906f0..8171ccef86 100644 --- a/storage/disk/txn_test.go +++ b/storage/disk/txn_test.go @@ -36,6 +36,8 @@ func fixture(n int) map[string]interface{} { } func TestSetTxnIsTooBigToFitIntoOneRequestWhenUseDiskStoreReturnsError(t *testing.T) { + t.Parallel() + test.WithTempFS(nil, func(dir string) { ctx := context.Background() s, err := New(ctx, logging.NewNoOpLogger(), nil, Options{Dir: dir, Partitions: []storage.Path{ @@ -72,6 +74,8 @@ func TestSetTxnIsTooBigToFitIntoOneRequestWhenUseDiskStoreReturnsError(t *testin } func TestDeleteTxnIsTooBigToFitIntoOneRequestWhenUseDiskStore(t *testing.T) { + t.Parallel() + test.WithTempFS(nil, func(dir string) { ctx := context.Background() s, err := New(ctx, logging.NewNoOpLogger(), nil, Options{Dir: dir, Partitions: []storage.Path{ diff --git a/topdown/bindings_test.go b/topdown/bindings_test.go index 230f5b4a81..5994c78432 100644 --- a/topdown/bindings_test.go +++ b/topdown/bindings_test.go @@ -13,6 +13,8 @@ import ( ) func TestBindingsZeroValues(t *testing.T) { + t.Parallel() + var unifier *bindings // Plugging @@ -33,6 +35,8 @@ func term(s string) *ast.Term { } func TestBindingsArrayHashmap(t *testing.T) { + t.Parallel() + var bindings bindings b := newBindingsArrayHashmap() keys := make(map[int]ast.Var) diff --git a/topdown/builtins_test.go b/topdown/builtins_test.go index c8ef41080f..b6e0e5df8c 100644 --- a/topdown/builtins_test.go +++ b/topdown/builtins_test.go @@ -9,6 +9,7 @@ import ( ) func TestCustomBuiltinIterator(t *testing.T) { + t.Parallel() query := NewQuery(ast.MustParseBody("test(1, x)")).WithBuiltins(map[string]*Builtin{ "test": { diff --git a/topdown/cache/cache_test.go b/topdown/cache/cache_test.go index b5c1a3865a..ede1983c44 100644 --- a/topdown/cache/cache_test.go +++ b/topdown/cache/cache_test.go @@ -15,6 +15,8 @@ import ( ) func TestParseCachingConfig(t *testing.T) { + t.Parallel() + maxSize := new(int64) *maxSize = defaultMaxSizeBytes period := new(int64) @@ -55,7 +57,6 @@ func TestParseCachingConfig(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - config, err := ParseCachingConfig(tc.input) if tc.wantErr { if err == nil { @@ -90,6 +91,7 @@ func TestParseCachingConfig(t *testing.T) { } func TestInsert(t *testing.T) { + t.Parallel() in := `{"inter_query_builtin_cache": {"max_size_bytes": 20},}` // 20 byte limit for test purposes @@ -178,6 +180,7 @@ func TestInsert(t *testing.T) { } func TestInterQueryValueCache(t *testing.T) { + t.Parallel() in := `{"inter_query_builtin_value_cache": {"max_num_entries": 4},}` @@ -269,6 +272,8 @@ func TestInterQueryValueCache(t *testing.T) { } func TestConcurrentInsert(t *testing.T) { + t.Parallel() + in := `{"inter_query_builtin_cache": {"max_size_bytes": 20},}` // 20 byte limit for test purposes config, err := ParseCachingConfig([]byte(in)) @@ -321,6 +326,8 @@ func TestConcurrentInsert(t *testing.T) { } func TestClone(t *testing.T) { + t.Parallel() + in := `{"inter_query_builtin_cache": {"max_size_bytes": 40},}` config, err := ParseCachingConfig([]byte(in)) @@ -362,6 +369,8 @@ func TestClone(t *testing.T) { } func TestDelete(t *testing.T) { + t.Parallel() + config, err := ParseCachingConfig(nil) if err != nil { t.Fatalf("Unexpected error %v", err) @@ -387,6 +396,8 @@ func TestDelete(t *testing.T) { } func TestInsertWithExpiryAndEviction(t *testing.T) { + t.Parallel() + // 50 byte max size // 1s stale cleanup period // 80% threshold to for FIFO eviction (eviction after 40 bytes) @@ -431,6 +442,8 @@ func TestInsertWithExpiryAndEviction(t *testing.T) { } func TestInsertHighTTLWithStaleEntryCleanup(t *testing.T) { + t.Parallel() + // 40 byte max size // 1s stale cleanup period // 100% threshold to for FIFO eviction (eviction after 40 bytes) @@ -472,6 +485,8 @@ func TestInsertHighTTLWithStaleEntryCleanup(t *testing.T) { } func TestInsertHighTTLWithoutStaleEntryCleanup(t *testing.T) { + t.Parallel() + // 40 byte max size // 0s stale cleanup period -> no cleanup // 100% threshold to for FIFO eviction (eviction after 40 bytes) @@ -510,6 +525,8 @@ func TestInsertHighTTLWithoutStaleEntryCleanup(t *testing.T) { } func TestZeroExpiryTime(t *testing.T) { + t.Parallel() + // 20 byte max size // 1s stale cleanup period // 100% threshold to for FIFO eviction (eviction after 40 bytes) @@ -536,6 +553,8 @@ func TestZeroExpiryTime(t *testing.T) { } func TestCancelNewInterQueryCacheWithContext(t *testing.T) { + t.Parallel() + // 40 byte max size // 1s stale cleanup period // 100% threshold to for FIFO eviction (eviction after 40 bytes) @@ -565,6 +584,8 @@ func TestCancelNewInterQueryCacheWithContext(t *testing.T) { } func TestUpdateConfig(t *testing.T) { + t.Parallel() + config, err := ParseCachingConfig(nil) if err != nil { t.Fatalf("Unexpected error %v", err) @@ -592,6 +613,8 @@ func TestUpdateConfig(t *testing.T) { } func TestDefaultConfigValues(t *testing.T) { + t.Parallel() + c := NewInterQueryCache(nil) actualC, ok := c.(*cache) if !ok { diff --git a/topdown/cache_test.go b/topdown/cache_test.go index 654dd2e4d6..9f2936f08a 100644 --- a/topdown/cache_test.go +++ b/topdown/cache_test.go @@ -11,6 +11,8 @@ import ( ) func TestVirtualCacheCompositeKey(t *testing.T) { + t.Parallel() + cache := NewVirtualCache() ref := ast.MustParseRef("data.x.y[[1]].z") cache.Put(ref, ast.BooleanTerm(true)) @@ -21,6 +23,8 @@ func TestVirtualCacheCompositeKey(t *testing.T) { } func TestVirtualCacheInvalidate(t *testing.T) { + t.Parallel() + cache := NewVirtualCache() cache.Push() cache.Put(ast.MustParseRef("data.x.p"), ast.BooleanTerm(true)) @@ -32,6 +36,8 @@ func TestVirtualCacheInvalidate(t *testing.T) { } func TestSetAndRetriveUndefined(t *testing.T) { + t.Parallel() + cache := NewVirtualCache() cache.Put(ast.MustParseRef("data.foo.bar"), nil) result, undefined := cache.Get(ast.MustParseRef("data.foo.bar")) @@ -44,6 +50,8 @@ func TestSetAndRetriveUndefined(t *testing.T) { } func TestBaseCacheGetExactMatch(t *testing.T) { + t.Parallel() + cache := newBaseCache() cache.Put(ast.MustParseRef("data.x.foo"), ast.StringTerm("bar").Value) result := cache.Get(ast.MustParseRef("data.x.foo")) diff --git a/topdown/cidr_test.go b/topdown/cidr_test.go index ac80412a87..3a6b454621 100644 --- a/topdown/cidr_test.go +++ b/topdown/cidr_test.go @@ -11,6 +11,7 @@ import ( ) func TestNetCIDRExpandCancellation(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -42,5 +43,4 @@ func TestNetCIDRExpandCancellation(t *testing.T) { if err == nil || err.(*Error).Code != CancelErr { t.Fatalf("Expected cancel error but got: %v (err: %v)", qrs, err) } - } diff --git a/topdown/copypropagation/unionfind_test.go b/topdown/copypropagation/unionfind_test.go index de4110a137..fe1366d5b0 100644 --- a/topdown/copypropagation/unionfind_test.go +++ b/topdown/copypropagation/unionfind_test.go @@ -12,6 +12,8 @@ import ( ) func TestUnionFindRootValue(t *testing.T) { + t.Parallel() + tests := []struct { name string root unionFindRoot @@ -47,6 +49,7 @@ func TestUnionFindRootValue(t *testing.T) { } func TestUnionFindMakeSet(t *testing.T) { + t.Parallel() uf := newUnionFind(nil) @@ -94,6 +97,8 @@ func TestUnionFindMakeSet(t *testing.T) { } func TestUnionFindFindEmptyUF(t *testing.T) { + t.Parallel() + uf := newUnionFind(noopUnionFindRank) actual, found := uf.Find(ast.Var("a")) if found || actual != nil { @@ -102,6 +107,8 @@ func TestUnionFindFindEmptyUF(t *testing.T) { } func TestUnionFindFindIsParent(t *testing.T) { + t.Parallel() + uf := newUnionFind(noopUnionFindRank) uf.MakeSet(ast.Var("a")) // "a" will have a parent "a" @@ -115,6 +122,8 @@ func TestUnionFindFindIsParent(t *testing.T) { } func TestUnionFindFindParent(t *testing.T) { + t.Parallel() + fooBarRef := ast.Ref{ast.StringTerm("foo"), ast.StringTerm("bar"), ast.VarTerm("x")} call := ast.Call{ast.RefTerm(ast.VarTerm("gt")), ast.NumberTerm("1"), ast.VarTerm("x")} @@ -135,6 +144,8 @@ func TestUnionFindFindParent(t *testing.T) { } func TestUnionFindMerge(t *testing.T) { + t.Parallel() + uf := newUnionFind(noopUnionFindRank) tests := []struct { diff --git a/topdown/crypto_test.go b/topdown/crypto_test.go index 00e067a59a..fa1a1c307e 100644 --- a/topdown/crypto_test.go +++ b/topdown/crypto_test.go @@ -149,8 +149,11 @@ something else var invalidData = `nothingtoseehere` func TestX509ParseAndVerify(t *testing.T) { + t.Parallel() t.Run("TestFullChainPEM", func(t *testing.T) { + t.Parallel() + chain := strings.Join([]string{rootCA, intermediateCA, leaf}, "\n") parsed, err := getX509CertsFromString(chain) @@ -164,6 +167,8 @@ func TestX509ParseAndVerify(t *testing.T) { }) t.Run("TestFullChainBase64", func(t *testing.T) { + t.Parallel() + chain := strings.Join([]string{rootCA, intermediateCA, leaf}, "\n") b64 := base64.StdEncoding.EncodeToString([]byte(chain)) @@ -178,6 +183,8 @@ func TestX509ParseAndVerify(t *testing.T) { }) t.Run("TestWrongOrder", func(t *testing.T) { + t.Parallel() + chain := strings.Join([]string{leaf, intermediateCA, rootCA}, "\n") parsed, err := getX509CertsFromString(chain) @@ -191,6 +198,8 @@ func TestX509ParseAndVerify(t *testing.T) { }) t.Run("TestMissingIntermediate", func(t *testing.T) { + t.Parallel() + chain := strings.Join([]string{rootCA, leaf}, "\n") parsed, err := getX509CertsFromString(chain) @@ -204,6 +213,8 @@ func TestX509ParseAndVerify(t *testing.T) { }) t.Run("TestTooFewCerts", func(t *testing.T) { + t.Parallel() + parsed, err := getX509CertsFromString(leaf) if err != nil { t.Fatalf("failed to parse leaf cert: %v", err) @@ -216,6 +227,8 @@ func TestX509ParseAndVerify(t *testing.T) { } func Test_parsex509KeyPair(t *testing.T) { + t.Parallel() + certPemEC := []byte(`-----BEGIN CERTIFICATE----- MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow @@ -399,6 +412,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== certPemRSAKeyB64 := []byte(`LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRQzNOOWp2aWNtS3BHZDEKUDNwWGVBK01vaWRkTmpKNXZNMTNLcWFUYzEyOW1jbUhIdElyakduaG9Mck5TTFdjTEdLTkJic0JOaTVsb3E0MQpzSm9neW1OeFVzeFFRRXJYbjVEaUVuRVFmMUJxK25TR3pJZEdtYm1KVldxSHQ0dFNJSGRDSUVheEhESFdrSW9rCmxSNHQ4Q2dOSXZoS3FsR0dKbHZMZlBWWmdXSGpzOUhBKzYrRzM1dHAvWmdBdlNBL051dGs1UDlBTE9qbHlzaXkKU2lYNm1hUlBrK3lyTmZwcXpBOWNsSWVWUVFDVFNHSFJQZU94ZzFTU3FwSGhNdWt1WTAxSkh3b3RCVVFsTkt1RApXQnd6MTNGT3VhUGM3NGcwcHNOUVdlQ0lpN0laNmNQWldKZmJDa1JIQjBlRnBhT0djbnlGRmFmQWZOWVoxd1o4CjdINlUzVTR6d3IwSUx4WXo2RG44QjRmSWtrb1kxOVBIRW1uNHRySG01d2JSbkpWUGllZmZBWnpxSy96Y2FpQkYKVkRkR1FDL1R5M0s1ejkrVkZiSXpQV0lSNVM2d2VXdGJBOGgzYWEvRS90SFNDWVd2aSs0UndxUHhmV1E2SmV2eApkV0MwOFJneTFJUHo3dnFrdkQwYmc3UmYwMXZJVW9oTzN2Ym9IN0p6Mkswb3ZFR2lSZGNQUWZCeHkvUjZPNGVzCnRQcFRMRTlDU1NrY1RBUWNpZkNwbjNPVTgvdnVSTERFeTlBdCttYWQrRzVWS2lTbm84RDV5Z2xqT0hFUUlDWk8KMGNFTkY1dVZjck5OaFFZUzBKZDdGOWVWQ1NPOEhVQ3NsTXFGMmVkbkZDcFNmcllJUWtzUlRnZWo0YlhVeGxURgozdmZqRVpuNWlkVnNJZ2oydFZRb04wZHJuOE1BU1FJREFRQUJBb0lDQUJKaUttUm9neDRqM2xTYm5Lc3Jtd1hOCm5GMEVLOTdlcEpBTktiOFlQNExmYkNMZ1l3Nm5EVldzQXFwSDNoOFFMZ2cvMTdKb3JSR2FGOWcvd3N0QSsyYmEKdTdEZXJwUEJpVEJCMFBIcWtGZFhqM3NhQ1FXNnRXelQ4dmN3b2F4SklTWXpwbHd0ZTh1dlg0a0pwRWhRTlRpUwpObThKZFZvY1BiQW1kdGkyL0dzME52cmgxZ3dXb2htcHJnZCs4bjRkUk5Pd0RYTnpQaUFXYjNwQ0tkcmg4U1JoCjc0aURSei9SZjBZWENoNmQ4ZENWWGVrNGlFRGVzRXp5QythWWJPQ3dhb2dJY3dVdTV0WkQyV1M1b2NUSzNHM2QKZnhWVFBHdXFBdVZzU3pUd0xWdmZ3bnlyb0xzRDVmTnBoZEhoVzQzSkxYak9BakcwWk9nZFZPT1NlQ1g0S1prbwptcWc4b3Y1TksxclVRVGQwNng2bmg0elBXdEdaTDIwbE9EMTZvRWgzUlZoRFU5akQ1U25aZ2M1Mzg2bVkxeTVJClV0QTBUUnh3MzNIcjRWT1ExaXVCZzlrNTU2MzFIcGl0clBWZ1QvLzVzYzdjMjhpQ2lBRnVFZGg3SDF5cG5NNkgKc1pjL2prRTJBOFF1NnpKSTV2NzRoYkFaTmxONVMrcDU4ajhrV2pPYTd4bnZwYk5saXc1a2JDK2Ezb25ZSVNHZApTNVZITzVEVkVaOEY3aUtUTS8zTEFZdDZScG0vdEZJOUhFZVRGWHVCVEVsYTlsb0srUWdXbjF1QVVMeGtKUHFyCkFXZ0tzL0FYYWpxVyt0d3ZUM2M5cUFDaGFTakhjV3lxem05WGh6RDRwNTg2cnpDZ3M5VUNSSStudlEvOGFIMWoKNm9CdkRqbUxpem9WUEVkR2k1VkJBb0lCQVFEM2pRZThEdVIxVjYveS9HcXRNRVcyVXptdTl2d1R4VXRBSFZtawpob25PbFo0MDVEL1B3b0s1dXBORjV2QWtxNDN1b1M2OXVuQWxxbGpraVNmOTEzU3pYZEE4dXRRYlQzVFczUmxWCkZ2dXZlN3YvcWtRZFdScm5rdXJhcWtFbnhUMnlKOGdlaG1Qcmo1STMwVHVRVXpSdmFRc2hyYkIwV3NCcGcrRmIKdWJnV29wU21hVTY5aEJpSGxwWFYrcjJRUXIrVllHT3JLUkNSWDRhMGxtbEJxbDdnemVZSTA2d2RpamszelF5cgorcVltYjRkdEFqd3huQ09CRG9qbVJBM2hGTmpVbC8wNlVvMmZzUEM1cjduWlA2cURUMUU2MU5tVDhPZ3kyUWE1Cm90Uk4wS1E3bThGRXAwUDA4aHByOTRxVlZLaHB2NzMzcGMwQkhCQXZ6VG9RdTdKcEFvSUJBUUM5ZUxZZzVSS3cKMDZQSEVmRlhMTnZ1NU12Q2I0T2NHY1BHUElLaHEyWExTbFJSSElVSkdueFB2RVRrcm93YXhDVGVVc2g0WUFtUApZUjZxKzE2aHRwN1JBZ1RWNkxvZUpnQ2hDNVRvTWlkZkR2MmxEUnZneVpMWWtsU0VIcEpaSXRWWTI4NzFWTkRaClhFQWwwOGFGcHlENDNseXdNc3UxaHYzSnRMVGJVTDNZdGtBZnBQVFJBZ0ZaaFlxbVJUdTJKeXN5dXVoWWFVbS8KeEw3WDcvYmlJZ2FPemR1YkF0QXBFTUlEbnFOdVdKOUVBQit4a1c5VUIyTFpRZjBuOTh2bG40aUowaDhsb1V5RAphWElPbWpDZFJXeGFzeVRRQkNEZUR0eXgxbHNvb1R1U2JWU1FFSHVUeUgzVno2UHZBZC9xNGxwRW5hY0UvMjE5CjRXUEh6NnArcDJMaEFvSUJBQ28yQXhhZkYzZW16eHJJemN2Z1NsTFBtQ3RzZEFsUEFBamJ1RmhrbElVRVlDaTIKcnViWFRRRXNma1pTSGFxekVnMlpzR1dycjhuTVpVSDYzVFhja2txdmVYMlJnZTl5T2dNVlNtZUc5cjJ5aEprUQp5SEtVcWhESXJZRkJ2TUJ5VXBYWlVMZGJ4UmY2c0QwU1VXekhzMDQ0QkN6bStBcXZHdFlqSmI5RlNNMmJSV3VtCjAwVmZpK3M2MHl2Y2lJeGJ4VjFNUlZKL094TCt6ZkpuSDJXU0RvR1l1bHZROUMxSlQzNWpXWUROeVowT01YSjIKQ2h1UGUwSmJYeDZjaGgxV042N3doNzUxS3k4S3RkR0QxRlhtRkVZMXRTMHA5RHZVdlZOR1RHNUZCSnlNTWlUego1eDIwdzlLMW9hbTlXUVVqbldBQzBQcTBhK04vakljS0lKZVAyZGtDZ2dFQVhPZzhKcFV0UFJnS1R5czFOSklDCnBubjZrRFV1Uy9VMlVwYUpWODA3OVJ0VmpSQjNDNmU1SFVBc2FCWlBEVER4QXpPRXFjSXQ3ZWlwcVIzcG9WSnoKUGZuSGRUelJSc2RMdDZ4K0wvMm40S3p4STJYeUxaK3FLaGhXNlJJMG9SQzduUDdyMU5EcU9DdE1LVUJYTUdKcgpnSjFJeGYyaWRqamphV3o2NGpBTlo1NjJnczNZWGtTbGRNaE8zSWxHWm1OK2d6bXpoT2JjQ3ZUbXYrd2pHMitqCjE1S0tCTkMwVWU2dHRDaXQ2d1g1MHRaY3RDMmtjWWZOcU1yNjRBWmFMUmExVlI5N3RuQUpuTWF2N3drY25ZSFYKU0FSZ0lNQmxmWDI4S2xmNkMwcEVjK0M0Zm93V2pMamJPMlM5OWd6dFI3Z0dtMjdTMzFpQTBDRWRWSFU0SFRMbgpBUUtDQVFFQXNzajBmRThqa0ZpdnpRMmxTZTBEeGhwUXFHZVF1UGROYkJKVnNBcVdmRXRKQ0h2R0JYaTZBeEIrClFnN015RE14dnVPYXQ1TVNUQ01GYzNYdVFUdEtxdlF3SGxXMXZpTnJxckNzRHVRNTVDa1ZQTUxmazk4VlFoeHkKMnpUd20zOUd5a1ZpLy9CaU5LQzRCU2ZtZlN6cGdiYlJnSEI2Ny9zcGIwejBMbXUrWG5uL0ROemxxS1pvQUZFQgpwcDdzNkVmWGdJN1Npbm94dGxuRHM4eDdFM2dlcEtENVVWbnQzM3FZbUhCOVZ3WHpUZDBaSkhrY0x1b1VpanJjCko2cENYVTcrRlpPd3pJQi9IcFFPZ2pwdklqQ0pJaHRGeFZ5Z2JqdXVjRThRS2Naaml5VXNGTHZkQzVkZTFNZVQKMXJKalFFc2laeEgrUVBSODh0dUJ5VVZHMDAwbHBBPT0KLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo=`) t.Run("ParseX509KeyPairEC", func(t *testing.T) { + t.Parallel() + validKeyPairEc, err := getTLSx509KeyPairFromString(certPemEC, keyPemEC) if err != nil { t.Fatal("failed to parse x509 key pair") @@ -410,6 +425,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== }) t.Run("ParseX509KeyPairRSA", func(t *testing.T) { + t.Parallel() + validCertPair, err := getTLSx509KeyPairFromString(certPemx509, certPemRSA) if err != nil { t.Fatal("failed to parse x509 Pair with RSAkey") @@ -421,6 +438,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== }) t.Run("ParseX509KeyPairRSABase64", func(t *testing.T) { + t.Parallel() + validCertPair, err := getTLSx509KeyPairFromString(certPemRSACrtB64, certPemRSAKeyB64) if err != nil { t.Fatal("failed to parse x509 Pair with RSAkey") @@ -432,6 +451,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== }) t.Run("ParseX509KeyPairDERx509", func(t *testing.T) { + t.Parallel() + validCertPair, err := getTLSx509KeyPairFromString(certDERx509, certDERRSA) if err != nil { t.Fatal("failed to parse x509 Pair with RSAkey", err) @@ -442,6 +463,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== }) t.Run("ParseX509KeyPairPEMstringB64Key", func(t *testing.T) { + t.Parallel() + validCertPair, err := getTLSx509KeyPairFromString(certPemx509, certPemRSAKeyB64) if err != nil { t.Fatal("failed to parse x509 Pair with RSAkey") @@ -453,6 +476,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== }) t.Run("ParseX509KeyPairB64CRTBPEMKey", func(t *testing.T) { + t.Parallel() + validCertPair, err := getTLSx509KeyPairFromString(certPemRSACrtB64, certPemRSA) if err != nil { t.Fatal("failed to parse x509 Pair with RSAkey") @@ -464,6 +489,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== }) t.Run("ParseX509KeyPairMisMatchedTypes", func(t *testing.T) { + t.Parallel() + certPair, err := getTLSx509KeyPairFromString(certPemEC, certPemRSA) if err == nil { t.Fatal("expected error but got nil") @@ -476,6 +503,8 @@ KcZjiyUsFLvdC5de1MeT1rJjQEsiZxH+QPR88tuByUVG000lpA== } func Test_getPrivateKeyFromPEMData(t *testing.T) { + t.Parallel() + tests := map[string]struct { input string wantErr string @@ -638,7 +667,10 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }, } for name, testData := range tests { + testData := testData // copy for capturing loop variable (not needed in Go 1.22+) t.Run(name, func(t *testing.T) { + t.Parallel() + keys, err := getPrivateKeysFromPEMData(testData.input) if testData.wantErr != "" { if err != nil && !strings.Contains(err.Error(), testData.wantErr) { @@ -657,6 +689,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx } func TestParseAndVerifyX509CertsWithOptions(t *testing.T) { + t.Parallel() chain := strings.Join([]string{rootCA, intermediateCA, leaf}, "\n") @@ -732,6 +765,8 @@ func TestParseAndVerifyX509CertsWithOptions(t *testing.T) { } func TestExtractX509VerifyOptions(t *testing.T) { + t.Parallel() + tests := []struct { jsonOption *ast.Term expectErr error diff --git a/topdown/errors_test.go b/topdown/errors_test.go index 674dda902c..8a381f8f8c 100644 --- a/topdown/errors_test.go +++ b/topdown/errors_test.go @@ -10,6 +10,8 @@ import ( ) func TestErrorWrapping(t *testing.T) { + t.Parallel() + isHalt := func(err error) bool { return errors.As(err, &topdown.Halt{}) } @@ -104,7 +106,10 @@ func TestErrorWrapping(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + if !tc.check(tc.err) { t.Errorf("unexpected 'false'") } diff --git a/topdown/eval_test.go b/topdown/eval_test.go index b672bbf551..d6b30e2701 100644 --- a/topdown/eval_test.go +++ b/topdown/eval_test.go @@ -17,6 +17,8 @@ import ( ) func TestQueryIDFactory(t *testing.T) { + t.Parallel() + f := &queryIDFactory{} for i := 0; i < 10; i++ { if n := f.Next(); n != uint64(i) { @@ -26,6 +28,8 @@ func TestQueryIDFactory(t *testing.T) { } func TestMergeNonOverlappingKeys(t *testing.T) { + t.Parallel() + realData := ast.MustParseTerm(`{"foo": "bar"}`).Value.(ast.Object) mockData := ast.MustParseTerm(`{"baz": "blah"}`).Value.(ast.Object) @@ -42,6 +46,8 @@ func TestMergeNonOverlappingKeys(t *testing.T) { } func TestMergeOverlappingKeys(t *testing.T) { + t.Parallel() + realData := ast.MustParseTerm(`{"foo": "bar"}`).Value.(ast.Object) mockData := ast.MustParseTerm(`{"foo": "blah"}`).Value.(ast.Object) @@ -71,6 +77,8 @@ func TestMergeOverlappingKeys(t *testing.T) { } func TestMergeWhenHittingNonObject(t *testing.T) { + t.Parallel() + cases := []struct { note string real, mock, exp *ast.Term @@ -108,7 +116,10 @@ func TestMergeWhenHittingNonObject(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + merged, ok := merge(tc.mock.Value, tc.real.Value) if !ok { t.Fatal("expected no error") @@ -121,6 +132,8 @@ func TestMergeWhenHittingNonObject(t *testing.T) { } func TestRefContainsNonScalar(t *testing.T) { + t.Parallel() + cases := []struct { note string ref ast.Ref @@ -159,7 +172,10 @@ func TestRefContainsNonScalar(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actual := refContainsNonScalar(tc.ref) if actual != tc.expected { @@ -171,6 +187,7 @@ func TestRefContainsNonScalar(t *testing.T) { } func TestContainsNestedRefOrCall(t *testing.T) { + t.Parallel() tests := []struct { note string @@ -235,7 +252,10 @@ func TestContainsNestedRefOrCall(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + vis := newNestedCheckVisitor() expr := ast.MustParseExpr(tc.input) result := containsNestedRefOrCall(vis, expr) @@ -247,6 +267,8 @@ func TestContainsNestedRefOrCall(t *testing.T) { } func TestTopdownVirtualCache(t *testing.T) { + t.Parallel() + ctx := context.Background() store := inmem.New() @@ -661,7 +683,10 @@ func TestTopdownVirtualCache(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + compiler := compileModules([]string{tc.module}) txn := storage.NewTransactionOrDie(ctx, store) defer store.Abort(ctx, txn) @@ -698,6 +723,8 @@ func TestTopdownVirtualCache(t *testing.T) { } func TestPartialRule(t *testing.T) { + t.Parallel() + ctx := context.Background() store := inmem.New() @@ -1508,7 +1535,10 @@ func TestPartialRule(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + compiler := compileModules([]string{tc.module}) txn := storage.NewTransactionOrDie(ctx, store) defer store.Abort(ctx, txn) diff --git a/topdown/exported_test.go b/topdown/exported_test.go index b676d9413b..42b2a5bc5d 100644 --- a/topdown/exported_test.go +++ b/topdown/exported_test.go @@ -20,36 +20,57 @@ import ( ) func TestRego(t *testing.T) { + t.Parallel() + for _, tc := range cases.MustLoad("../test/cases/testdata/v0").Sorted().Cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(fmt.Sprintf("v0/%s", tc.Note), func(t *testing.T) { + t.Parallel() + testRun(t, tc, ast.RegoV0) }) } for _, tc := range cases.MustLoad("../test/cases/testdata/v1").Sorted().Cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(fmt.Sprintf("v1/%s", tc.Note), func(t *testing.T) { + t.Parallel() + testRun(t, tc, ast.RegoV1) }) } } func TestOPARego(t *testing.T) { + t.Parallel() + for _, tc := range cases.MustLoad("testdata/cases").Sorted().Cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.Note, func(t *testing.T) { + t.Parallel() + testRun(t, tc, ast.RegoV0) }) } } func TestRegoWithNDBCache(t *testing.T) { + t.Parallel() + for _, tc := range cases.MustLoad("../test/cases/testdata/v0").Sorted().Cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(fmt.Sprintf("v0/%s", tc.Note), func(t *testing.T) { + t.Parallel() + testRun(t, tc, ast.RegoV0, func(q *Query) *Query { return q.WithNDBuiltinCache(builtins.NDBCache{}) }) }) } for _, tc := range cases.MustLoad("../test/cases/testdata/v1").Sorted().Cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(fmt.Sprintf("v1/%s", tc.Note), func(t *testing.T) { + t.Parallel() + testRun(t, tc, ast.RegoV1, func(q *Query) *Query { return q.WithNDBuiltinCache(builtins.NDBCache{}) }) diff --git a/topdown/glob_test.go b/topdown/glob_test.go index 2ec7f3732e..57133b59fc 100644 --- a/topdown/glob_test.go +++ b/topdown/glob_test.go @@ -14,6 +14,8 @@ import ( ) func TestGlobBuiltinCache(t *testing.T) { + t.Parallel() + ctx := BuiltinContext{} iter := func(*ast.Term) error { return nil } @@ -73,6 +75,8 @@ func TestGlobBuiltinCache(t *testing.T) { } func TestGlobBuiltinInterQueryValueCache(t *testing.T) { + t.Parallel() + ip := []byte(`{"inter_query_builtin_value_cache": {"max_num_entries": "10"},}`) config, _ := cache.ParseCachingConfig(ip) interQueryValueCache := cache.NewInterQueryValueCache(context.Background(), config) @@ -128,6 +132,7 @@ func TestGlobBuiltinInterQueryValueCache(t *testing.T) { } func TestGlobBuiltinInterQueryValueCacheTypeMismatch(t *testing.T) { + t.Parallel() ip := []byte(`{"inter_query_builtin_value_cache": {"max_num_entries": "10"},}`) config, _ := cache.ParseCachingConfig(ip) diff --git a/topdown/http_slow_test.go b/topdown/http_slow_test.go index 521bcfa2ad..37503d7948 100644 --- a/topdown/http_slow_test.go +++ b/topdown/http_slow_test.go @@ -20,8 +20,9 @@ import ( "github.com/open-policy-agent/opa/ast" ) +// Warning(philipc): This test modifies package variables, which means it cannot +// be run in parallel with other tests. func TestHTTPSendTimeout(t *testing.T) { - // Each test can tweak the response delay, default is 0 with no delay var responseDelay time.Duration @@ -123,6 +124,7 @@ func TestHTTPSendTimeout(t *testing.T) { } func TestHTTPSendRetryRequest(t *testing.T) { + t.Parallel() tests := []struct { note string @@ -155,7 +157,10 @@ func TestHTTPSendRetryRequest(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, err := w.Write([]byte(tc.response)) @@ -174,7 +179,9 @@ func TestHTTPSendRetryRequest(t *testing.T) { ctx := context.Background() if tc.evalTimeout > 0 { - ctx, _ = context.WithTimeout(ctx, tc.evalTimeout) + var ctxCancel context.CancelFunc + ctx, ctxCancel = context.WithTimeout(ctx, tc.evalTimeout) + defer ctxCancel() } q := newQuery(strings.ReplaceAll(tc.query, "%URL%", "http://"+ts.Listener.Addr().String()), time.Now()) diff --git a/topdown/http_test.go b/topdown/http_test.go index 7521c8e1e8..accb328463 100644 --- a/topdown/http_test.go +++ b/topdown/http_test.go @@ -47,6 +47,8 @@ type Person struct { // TestHTTPGetRequest returns the list of persons func TestHTTPGetRequest(t *testing.T) { + t.Parallel() + var people []Person // test data @@ -101,6 +103,8 @@ func TestHTTPGetRequest(t *testing.T) { // TestHTTPGetRequest returns the list of persons func TestHTTPGetRequestTlsInsecureSkipVerify(t *testing.T) { + t.Parallel() + var people []Person // test data @@ -155,6 +159,8 @@ func TestHTTPGetRequestTlsInsecureSkipVerify(t *testing.T) { } func TestHTTPEnableJSONOrYAMLDecode(t *testing.T) { + t.Parallel() + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/json-no-header": @@ -307,6 +313,8 @@ func echoCustomHeaders(w http.ResponseWriter, r *http.Request) { // TestHTTPSendCustomRequestHeaders adds custom headers to request func TestHTTPSendCustomRequestHeaders(t *testing.T) { + t.Parallel() + // test server ts := httptest.NewServer(http.HandlerFunc(echoCustomHeaders)) defer ts.Close() @@ -359,6 +367,8 @@ func TestHTTPSendCustomRequestHeaders(t *testing.T) { // TestHTTPHostHeader tests Host header support func TestHTTPHostHeader(t *testing.T) { + t.Parallel() + // test server ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -396,6 +406,8 @@ func TestHTTPHostHeader(t *testing.T) { // TestHTTPPostRequest adds a new person func TestHTTPPostRequest(t *testing.T) { + t.Parallel() + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { contentType := r.Header.Get("Content-Type") @@ -496,6 +508,8 @@ func TestHTTPPostRequest(t *testing.T) { } func TestHTTPDeleteRequest(t *testing.T) { + t.Parallel() + var people []Person // test data @@ -572,6 +586,8 @@ func TestHTTPDeleteRequest(t *testing.T) { // TestInvalidKeyError returns an error when an invalid key is passed in the // http.send builtin func TestInvalidKeyError(t *testing.T) { + t.Parallel() + // run the test tests := []struct { note string @@ -590,6 +606,8 @@ func TestInvalidKeyError(t *testing.T) { } func TestInvalidRetryParam(t *testing.T) { + t.Parallel() + // run the test tests := []struct { note string @@ -609,6 +627,8 @@ func TestInvalidRetryParam(t *testing.T) { } func TestParseTimeout(t *testing.T) { + t.Parallel() + tests := []struct { note string raw ast.Value @@ -687,7 +707,10 @@ func TestParseTimeout(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actual, err := parseTimeout(tc.raw) switch e := tc.expected.(type) { case error: @@ -703,6 +726,8 @@ func TestParseTimeout(t *testing.T) { // TestHTTPRedirectDisable tests redirects are not enabled by default func TestHTTPRedirectDisable(t *testing.T) { + t.Parallel() + // test server baseURL, teardown := getTestServer() defer teardown() @@ -733,6 +758,8 @@ func TestHTTPRedirectDisable(t *testing.T) { // TestHTTPRedirectEnable tests redirects are enabled func TestHTTPRedirectEnable(t *testing.T) { + t.Parallel() + // test server baseURL, teardown := getTestServer() defer teardown() @@ -760,6 +787,8 @@ func TestHTTPRedirectEnable(t *testing.T) { } func TestHTTPRedirectAllowNet(t *testing.T) { + t.Parallel() + // test server baseURL, teardown := getTestServer() defer teardown() @@ -826,6 +855,8 @@ func TestHTTPRedirectAllowNet(t *testing.T) { } func TestHTTPSendRaiseError(t *testing.T) { + t.Parallel() + // test server baseURL, teardown := getTestServer() defer teardown() @@ -928,13 +959,18 @@ func TestHTTPSendRaiseError(t *testing.T) { data := loadSmallTestData() for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + runTopDownTestCase(t, data, tc.note, []string{strings.ReplaceAll(tc.ruleTemplate, "%URL%", baseURL)}, tc.response) }) } } func TestHTTPSendCaching(t *testing.T) { + t.Parallel() + // run the test tests := []struct { note string @@ -1099,7 +1135,10 @@ func TestHTTPSendCaching(t *testing.T) { data := loadSmallTestData() for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + var requests []*http.Request ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requests = append(requests, r) @@ -1124,6 +1163,8 @@ func TestHTTPSendCaching(t *testing.T) { } func TestHTTPSendIntraQueryCaching(t *testing.T) { + t.Parallel() + tests := []struct { note string request string @@ -1198,7 +1239,10 @@ func TestHTTPSendIntraQueryCaching(t *testing.T) { t0 := time.Now() for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + var requests []*http.Request ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requests = append(requests, r) @@ -1267,6 +1311,8 @@ func TestHTTPSendIntraQueryCaching(t *testing.T) { } func TestHTTPSendInterQueryCaching(t *testing.T) { + t.Parallel() + tests := []struct { note string query string // each query is run three times @@ -1354,7 +1400,10 @@ func TestHTTPSendInterQueryCaching(t *testing.T) { t0 := time.Now() for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + var requests []*http.Request ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requests = append(requests, r) @@ -1408,6 +1457,8 @@ func TestHTTPSendInterQueryCaching(t *testing.T) { } func TestHTTPSendInterQueryForceCaching(t *testing.T) { + t.Parallel() + tests := []struct { note string query string @@ -1519,7 +1570,10 @@ func TestHTTPSendInterQueryForceCaching(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + t0 := time.Now().UTC() var requests []*http.Request @@ -1567,6 +1621,8 @@ func TestHTTPSendInterQueryForceCaching(t *testing.T) { } func TestHTTPSendInterQueryForceCachingRefresh(t *testing.T) { + t.Parallel() + cacheTime := 300 tests := []struct { note string @@ -1601,7 +1657,10 @@ func TestHTTPSendInterQueryForceCachingRefresh(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + t0 := time.Now().UTC() var requests []*http.Request @@ -1715,6 +1774,8 @@ func TestHTTPSendInterQueryForceCachingRefresh(t *testing.T) { } func TestHTTPSendInterQueryCachingModifiedResp(t *testing.T) { + t.Parallel() + tests := []struct { note string query string @@ -1747,7 +1808,10 @@ func TestHTTPSendInterQueryCachingModifiedResp(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + t0 := time.Now().UTC() var requests []*http.Request @@ -1803,6 +1867,8 @@ func TestHTTPSendInterQueryCachingModifiedResp(t *testing.T) { } func TestHTTPSendInterQueryCachingNewResp(t *testing.T) { + t.Parallel() + tests := []struct { note string query string // each query will be run three times @@ -1821,7 +1887,10 @@ func TestHTTPSendInterQueryCachingNewResp(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + t0 := time.Now().UTC() var requests []*http.Request @@ -1889,6 +1958,8 @@ func newQuery(qStr string, t0 time.Time) *Query { } func TestInsertIntoHTTPSendInterQueryCacheError(t *testing.T) { + t.Parallel() + tests := []struct { note string query string @@ -1914,9 +1985,12 @@ func TestInsertIntoHTTPSendInterQueryCacheError(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t0 := time.Now().UTC() t.Run(tc.note, func(t *testing.T) { + t.Parallel() + var requests []*http.Request ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requests = append(requests, r) @@ -1958,6 +2032,8 @@ func TestInsertIntoHTTPSendInterQueryCacheError(t *testing.T) { } func TestGetCachingMode(t *testing.T) { + t.Parallel() + tests := []struct { note string input ast.Object @@ -1998,7 +2074,10 @@ func TestGetCachingMode(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actual, err := getCachingMode(tc.input) if tc.wantError { if err == nil { @@ -2022,6 +2101,8 @@ func TestGetCachingMode(t *testing.T) { } func TestGetResponseHeaderDateEmpty(t *testing.T) { + t.Parallel() + _, err := getResponseHeaderDate(http.Header{"Date": {""}}) if err == nil { t.Fatal("Expected error but got nil") @@ -2034,6 +2115,8 @@ func TestGetResponseHeaderDateEmpty(t *testing.T) { } func TestParseMaxAgeCacheDirective(t *testing.T) { + t.Parallel() + tests := []struct { note string input map[string]string @@ -2079,7 +2162,10 @@ func TestParseMaxAgeCacheDirective(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actual, err := parseMaxAgeCacheDirective(tc.input) if tc.wantError { if err == nil { @@ -2103,6 +2189,8 @@ func TestParseMaxAgeCacheDirective(t *testing.T) { } func TestNewForceCacheParams(t *testing.T) { + t.Parallel() + tests := []struct { note string input ast.Object @@ -2141,7 +2229,10 @@ func TestNewForceCacheParams(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actual, err := newForceCacheParams(tc.input) if tc.wantError { if err == nil { @@ -2165,6 +2256,8 @@ func TestNewForceCacheParams(t *testing.T) { } func TestGetBoolValFromReqObj(t *testing.T) { + t.Parallel() + validInput := ast.MustParseTerm(`{"cache": true}`) validInputObj := validInput.Value.(ast.Object) @@ -2206,7 +2299,10 @@ func TestGetBoolValFromReqObj(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actual, err := getBoolValFromReqObj(tc.input, tc.key) if tc.wantError { if err == nil { @@ -2230,6 +2326,8 @@ func TestGetBoolValFromReqObj(t *testing.T) { } func TestInterQueryCheckCacheError(t *testing.T) { + t.Parallel() + input := ast.MustParseTerm(`{"force_cache": true}`) inputObj := input.Value.(ast.Object) @@ -2245,6 +2343,8 @@ func TestInterQueryCheckCacheError(t *testing.T) { } func TestNewInterQueryCacheValue(t *testing.T) { + t.Parallel() + date := "Wed, 31 Dec 2115 07:28:00 GMT" maxAge := 290304000 @@ -2338,6 +2438,8 @@ func getTLSTestServer() (ts *httptest.Server) { return } +// Warning(philipc): This test cannot be run in parallel with other tests, due +// to the t.Setenv calls used to set up the server environment. func TestHTTPSClient(t *testing.T) { const ( localClientCertFile = "testdata/client-cert.pem" @@ -2631,6 +2733,8 @@ func TestHTTPSClient(t *testing.T) { }) } +// Warning(philipc): This test cannot be run in parallel with other tests, due +// to the t.Setenv calls from one of its helper methods. func TestHTTPSNoClientCerts(t *testing.T) { const ( localCaFile = "testdata/ca.pem" @@ -2847,6 +2951,9 @@ func TestHTTPSNoClientCerts(t *testing.T) { // tests, some larger projects have just slapped linter ignores on the // offending callsites. Since we only use (*CertPool).Subjects() here for // tests, we've gone with using linter ignores for now. +// +// Warning(philipc): This test cannot be run in parallel with other tests, due +// to the t.Setenv calls used to set up the server environment. func TestCertSelectionLogic(t *testing.T) { const ( localCaFile = "testdata/ca.pem" @@ -2979,6 +3086,7 @@ func TestCertSelectionLogic(t *testing.T) { } func TestHTTPSendCacheDefaultStatusCodesIntraQueryCache(t *testing.T) { + t.Parallel() // run test server var requests []*http.Request @@ -3020,6 +3128,7 @@ func TestHTTPSendCacheDefaultStatusCodesIntraQueryCache(t *testing.T) { } func TestHTTPSendCacheDefaultStatusCodesInterQueryCache(t *testing.T) { + t.Parallel() // run test server var requests []*http.Request @@ -3110,6 +3219,7 @@ func (c *onlyOnceInterQueryCache) Clone(val iCache.InterQueryCacheValue) (iCache } func TestInterQueryCacheConcurrentModification(t *testing.T) { + t.Parallel() // create an inter-query cache that'll return a value on first access, but none at subsequent accesses. clock := time.Now() @@ -3158,6 +3268,8 @@ func TestInterQueryCacheConcurrentModification(t *testing.T) { } func TestInterQueryCacheDataClone(t *testing.T) { + t.Parallel() + data := interQueryCacheData{ Headers: map[string][]string{ "Date": {"Thu, 01 Jan 1970 00:00:00 GMT"}, @@ -3184,6 +3296,7 @@ func TestInterQueryCacheDataClone(t *testing.T) { } func TestInterQueryCacheValueClone(t *testing.T) { + t.Parallel() cacheData := interQueryCacheData{ Headers: map[string][]string{ @@ -3218,6 +3331,8 @@ func TestInterQueryCacheValueClone(t *testing.T) { } func TestIntraQueryCache_ClientError(t *testing.T) { + t.Parallel() + data := loadSmallTestData() tests := []struct { @@ -3250,7 +3365,10 @@ func TestIntraQueryCache_ClientError(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + ch := make(chan *http.Request) // A HTTP server that always causes a timeout ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -3280,6 +3398,8 @@ func TestIntraQueryCache_ClientError(t *testing.T) { } func TestInterQueryCache_ClientError(t *testing.T) { + t.Parallel() + data := loadSmallTestData() tests := []struct { @@ -3312,7 +3432,10 @@ func TestInterQueryCache_ClientError(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + ch := make(chan *http.Request) // A HTTP server that always causes a timeout @@ -3360,6 +3483,8 @@ func getAllRequests(ch chan *http.Request) []*http.Request { } func TestHTTPSendMetrics(t *testing.T) { + t.Parallel() + // run test server ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) @@ -3407,6 +3532,8 @@ func TestHTTPSendMetrics(t *testing.T) { }) } +// Warning(philipc): This test cannot be run in parallel with other tests, due +// to the t.Setenv calls used to set up the server environment. func TestInitDefaults(t *testing.T) { t.Setenv("HTTP_SEND_TIMEOUT", "300mss") @@ -3428,6 +3555,8 @@ var httpSendHelperRules = []string{ } func TestSocketHTTPGetRequest(t *testing.T) { + t.Parallel() + var people []Person // test data @@ -3517,50 +3646,56 @@ func (*tracemock) NewHandler(http.Handler, string, tracing.Options) http.Handler panic("unreachable") } -func TestDistributedTracingEnabled(t *testing.T) { - mock := tracemock{} - tracing.RegisterHTTPTracing(&mock) +// Warning(philipc): This test modifies package variables in tracing, which +// means it cannot be run in parallel with other tests. +func TestDistributedTracingEnableDisable(t *testing.T) { + t.Run("TestDistributedTracingEnabled", func(t *testing.T) { + mock := tracemock{} + tracing.RegisterHTTPTracing(&mock) - builtinContext := BuiltinContext{ - Context: context.Background(), - DistributedTracingOpts: tracing.NewOptions(true), // any option means it's enabled - } + builtinContext := BuiltinContext{ + Context: context.Background(), + DistributedTracingOpts: tracing.NewOptions(true), // any option means it's enabled + } - _, client, err := createHTTPRequest(builtinContext, ast.NewObject()) - if err != nil { - t.Fatalf("Unexpected error creating HTTP request %v", err) - } - if client.Transport == nil { - t.Fatal("No Transport defined") - } + _, client, err := createHTTPRequest(builtinContext, ast.NewObject()) + if err != nil { + t.Fatalf("Unexpected error creating HTTP request %v", err) + } + if client.Transport == nil { + t.Fatal("No Transport defined") + } - if exp, act := 1, mock.called; exp != act { - t.Errorf("calls to NewTransport: expected %d, got %d", exp, act) - } -} + if exp, act := 1, mock.called; exp != act { + t.Errorf("calls to NewTransport: expected %d, got %d", exp, act) + } + }) -func TestDistributedTracingDisabled(t *testing.T) { - mock := tracemock{} - tracing.RegisterHTTPTracing(&mock) + t.Run("TestDistributedTracingDisabled", func(t *testing.T) { + mock := tracemock{} + tracing.RegisterHTTPTracing(&mock) - builtinContext := BuiltinContext{ - Context: context.Background(), - } + builtinContext := BuiltinContext{ + Context: context.Background(), + } - _, client, err := createHTTPRequest(builtinContext, ast.NewObject()) - if err != nil { - t.Fatalf("Unexpected error creating HTTP request %v", err) - } - if client.Transport == nil { - t.Fatal("No Transport defined") - } + _, client, err := createHTTPRequest(builtinContext, ast.NewObject()) + if err != nil { + t.Fatalf("Unexpected error creating HTTP request %v", err) + } + if client.Transport == nil { + t.Fatal("No Transport defined") + } - if exp, act := 0, mock.called; exp != act { - t.Errorf("calls to NewTransported: expected %d, got %d", exp, act) - } + if exp, act := 0, mock.called; exp != act { + t.Errorf("calls to NewTransported: expected %d, got %d", exp, act) + } + }) } func TestHTTPGetRequestAllowNet(t *testing.T) { + t.Parallel() + // test data body := map[string]bool{"ok": true} diff --git a/topdown/input_test.go b/topdown/input_test.go index a2993c89d1..87ca3187a2 100644 --- a/topdown/input_test.go +++ b/topdown/input_test.go @@ -11,6 +11,7 @@ import ( ) func TestMergeTermWithValues(t *testing.T) { + t.Parallel() tests := []struct { note string @@ -83,8 +84,10 @@ func TestMergeTermWithValues(t *testing.T) { } for i, tc := range tests { - + i := i + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() pairs := make([][2]*ast.Term, len(tc.input)) @@ -124,6 +127,7 @@ func TestMergeTermWithValues(t *testing.T) { } func TestMergeTermWithValuesInputsShouldBeImmutable(t *testing.T) { + t.Parallel() initial := ast.MustParseTerm(`{"foo": 1}`) expInitial := initial.Copy() diff --git a/topdown/json_test.go b/topdown/json_test.go index f1056f0c98..75ad974fc1 100644 --- a/topdown/json_test.go +++ b/topdown/json_test.go @@ -11,6 +11,8 @@ import ( ) func TestFiltersToObject(t *testing.T) { + t.Parallel() + cases := []struct { note string filters []string @@ -94,7 +96,10 @@ func TestFiltersToObject(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + var paths []ast.Ref for _, path := range tc.filters { parsedPath, err := parsePath(ast.MustParseTerm(path)) diff --git a/topdown/jsonschema_test.go b/topdown/jsonschema_test.go index e093e86331..4b756de3a4 100644 --- a/topdown/jsonschema_test.go +++ b/topdown/jsonschema_test.go @@ -14,6 +14,8 @@ import ( ) func TestAstValueToJSONSchemaLoader(t *testing.T) { + t.Parallel() + cases := []struct { note string schema ast.Value @@ -71,7 +73,10 @@ func TestAstValueToJSONSchemaLoader(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + _, err := astValueToJSONSchemaLoader(tc.schema) if tc.valid && err != nil { t.Errorf("Unexpected JSON Schema validation result, expected valid = true, got = false: %s", err) @@ -86,6 +91,8 @@ func TestAstValueToJSONSchemaLoader(t *testing.T) { } func TestBuiltinJSONSchemaVerify(t *testing.T) { + t.Parallel() + cases := []struct { note string schema ast.Value @@ -137,7 +144,10 @@ func TestBuiltinJSONSchemaVerify(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + result := ast.NullTerm().Value err := builtinJSONSchemaVerify( BuiltinContext{}, @@ -165,6 +175,8 @@ func TestBuiltinJSONSchemaVerify(t *testing.T) { } func TestBuiltinJSONMatchSchema(t *testing.T) { + t.Parallel() + cases := []struct { note string document ast.Value @@ -250,7 +262,10 @@ func TestBuiltinJSONMatchSchema(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + result := ast.NullTerm().Value err := builtinJSONMatchSchema( BuiltinContext{}, diff --git a/topdown/lineage/lineage_test.go b/topdown/lineage/lineage_test.go index 8a0cbc1b32..3453c4241b 100644 --- a/topdown/lineage/lineage_test.go +++ b/topdown/lineage/lineage_test.go @@ -15,6 +15,7 @@ import ( ) func TestFilter(t *testing.T) { + t.Parallel() tests := []struct { note string @@ -172,7 +173,10 @@ Enter data.test.p = x } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + buf := topdown.NewBufferTracer() compiler := ast.MustCompileModules(map[string]string{ "test.rego": tc.module, @@ -195,5 +199,4 @@ Enter data.test.p = x } }) } - } diff --git a/topdown/net_test.go b/topdown/net_test.go index 14144f46df..fd103987d3 100644 --- a/topdown/net_test.go +++ b/topdown/net_test.go @@ -23,6 +23,8 @@ import ( // Due to some intricacies of the net/LookupIP internals, it seems impossible // to do that in a way that passes the race detector. func TestNetLookupIPAddr(t *testing.T) { + t.Parallel() + srv, err := mockdns.NewServerWithLogger(map[string]mockdns.Zone{ "v4.org.": { A: []string{"1.2.3.4"}, diff --git a/topdown/numbers_test.go b/topdown/numbers_test.go index 183f5e23ad..f0486de41d 100644 --- a/topdown/numbers_test.go +++ b/topdown/numbers_test.go @@ -9,6 +9,7 @@ import ( ) func TestRandIntnZero(t *testing.T) { + t.Parallel() qrs, err := NewQuery(ast.MustParseBody(`rand.intn("x", 0, out)`)).Run(context.Background()) if err != nil { @@ -27,6 +28,7 @@ func TestRandIntnZero(t *testing.T) { } func TestRandIntnNegative(t *testing.T) { + t.Parallel() qrs, err := NewQuery(ast.MustParseBody(`rand.intn("x", -100, out)`)).Run(context.Background()) if err != nil { @@ -46,6 +48,7 @@ func TestRandIntnNegative(t *testing.T) { } func TestRandIntnSeedingAndCaching(t *testing.T) { + t.Parallel() query := `rand.intn("x", 100000, x); rand.intn("x", 1000, y); rand.intn("x", 100000, x2); rand.intn("y", 1000, z)` @@ -80,6 +83,7 @@ func TestRandIntnSeedingAndCaching(t *testing.T) { } func TestRandIntnSavingDuringPartialEval(t *testing.T) { + t.Parallel() query := `x = "x"; y = 100; rand.intn(x, y, z)` c := ast.NewCompiler(). diff --git a/topdown/object_test.go b/topdown/object_test.go index 0ef95905b1..000c6fe2cc 100644 --- a/topdown/object_test.go +++ b/topdown/object_test.go @@ -11,6 +11,8 @@ import ( ) func TestObjectUnionNBuiltin(t *testing.T) { + t.Parallel() + tests := []struct { note string query string diff --git a/topdown/print_test.go b/topdown/print_test.go index 8398b3e0e2..b7b0a31591 100644 --- a/topdown/print_test.go +++ b/topdown/print_test.go @@ -12,6 +12,7 @@ import ( ) func TestTopDownPrint(t *testing.T) { + t.Parallel() cases := []struct { note string @@ -106,7 +107,9 @@ func TestTopDownPrint(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() c := ast.MustCompileModulesWithOpts(map[string]string{"test.rego": tc.module}, ast.CompileOpts{ @@ -139,6 +142,7 @@ func TestTopDownPrint(t *testing.T) { } func TestTopDownPrintInternalError(t *testing.T) { + t.Parallel() buf := bytes.NewBuffer(nil) @@ -158,6 +162,7 @@ func TestTopDownPrintInternalError(t *testing.T) { } func TestTopDownPrintHookNotSupplied(t *testing.T) { + t.Parallel() // NOTE(tsandall): The built-in function implementation expects all inputs // to be _sets_, even scalar values are wrapped. This expectation comes from @@ -179,6 +184,7 @@ func TestTopDownPrintHookNotSupplied(t *testing.T) { } func TestTopDownPrintWithStrictBuiltinErrors(t *testing.T) { + t.Parallel() buf := bytes.NewBuffer(nil) @@ -215,6 +221,7 @@ func (erroringPrintHook) Print(print.Context, string) error { } func TestTopDownPrintHookErrorPropagation(t *testing.T) { + t.Parallel() // NOTE(tsandall): See comment above about wrapping operands in sets. q := NewQuery(ast.MustParseBody(`internal.print([{"some message"}])`)). diff --git a/topdown/query_test.go b/topdown/query_test.go index a2ef0c496c..27b19899c1 100644 --- a/topdown/query_test.go +++ b/topdown/query_test.go @@ -16,6 +16,7 @@ import ( ) func TestQueryTracerDontPlugLocalVars(t *testing.T) { + t.Parallel() cases := []struct { note string @@ -66,7 +67,9 @@ func TestQueryTracerDontPlugLocalVars(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() query := initTracerTestQuery() @@ -105,6 +108,7 @@ func TestQueryTracerDontPlugLocalVars(t *testing.T) { } func TestLegacyTracerUpgrade(t *testing.T) { + t.Parallel() query := initTracerTestQuery() @@ -126,7 +130,8 @@ func TestLegacyTracerUpgrade(t *testing.T) { } func TestLegacyTracerBackwardsCompatibility(t *testing.T) { - t.Helper() + t.Parallel() + query := initTracerTestQuery() // Using a tracer that does _not_ implement the newer @@ -156,6 +161,8 @@ func TestLegacyTracerBackwardsCompatibility(t *testing.T) { } func TestDisabledTracer(t *testing.T) { + t.Parallel() + query := initTracerTestQuery() tracer := &testQueryTracer{ @@ -180,6 +187,8 @@ func TestDisabledTracer(t *testing.T) { } func TestRegoMetadataBuiltinCall(t *testing.T) { + t.Parallel() + tests := []struct { note string query string @@ -198,7 +207,10 @@ func TestRegoMetadataBuiltinCall(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + c := ast.NewCompiler() q := NewQuery(ast.MustParseBody(tc.query)).WithCompiler(c). WithStrictBuiltinErrors(true) @@ -216,6 +228,8 @@ func TestRegoMetadataBuiltinCall(t *testing.T) { } func TestWithCompilerErrors(t *testing.T) { + t.Parallel() + store := inmem.New() ctx := context.Background() txn := storage.NewTransactionOrDie(ctx, store) diff --git a/topdown/regex_template_test.go b/topdown/regex_template_test.go index 3764712454..1d10ed7588 100644 --- a/topdown/regex_template_test.go +++ b/topdown/regex_template_test.go @@ -7,6 +7,8 @@ import ( ) func TestRegexCompiler(t *testing.T) { + t.Parallel() + for _, tc := range []struct { template string delimiterStart byte @@ -23,7 +25,10 @@ func TestRegexCompiler(t *testing.T) { {"urn:foo.bar.com:{.*{}", '{', '}', true, "", true}, {"urn:foo:<.*>", '<', '>', false, "urn:foo:bar:baz", false}, } { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(fmt.Sprintf("template=%s", tc.template), func(t *testing.T) { + t.Parallel() + result, err := compileRegexTemplate(tc.template, tc.delimiterStart, tc.delimiterEnd) if tc.failCompile != (err != nil) { t.Fatalf("failed regex template compilation: %t != %t", tc.failCompile, err != nil) diff --git a/topdown/regex_test.go b/topdown/regex_test.go index bfa429d5e7..e559bd3e6f 100644 --- a/topdown/regex_test.go +++ b/topdown/regex_test.go @@ -14,6 +14,8 @@ import ( ) func TestRegexBuiltinCache(t *testing.T) { + t.Parallel() + ctx := BuiltinContext{} iter := func(*ast.Term) error { return nil } @@ -69,6 +71,7 @@ func TestRegexBuiltinCache(t *testing.T) { } func TestRegexBuiltinInterQueryValueCache(t *testing.T) { + t.Parallel() ip := []byte(`{"inter_query_builtin_value_cache": {"max_num_entries": "10"},}`) config, _ := cache.ParseCachingConfig(ip) @@ -121,6 +124,7 @@ func TestRegexBuiltinInterQueryValueCache(t *testing.T) { } func TestRegexBuiltinInterQueryValueCacheTypeMismatch(t *testing.T) { + t.Parallel() ip := []byte(`{"inter_query_builtin_value_cache": {"max_num_entries": "10"},}`) config, _ := cache.ParseCachingConfig(ip) diff --git a/topdown/runtime_test.go b/topdown/runtime_test.go index bd6f671d53..480b362d99 100644 --- a/topdown/runtime_test.go +++ b/topdown/runtime_test.go @@ -11,6 +11,7 @@ import ( ) func TestOPARuntime(t *testing.T) { + t.Parallel() ctx := context.Background() q := NewQuery(ast.MustParseBody("opa.runtime(x)")) // no runtime info @@ -46,6 +47,7 @@ func TestOPARuntime(t *testing.T) { } func TestOPARuntimeConfigMasking(t *testing.T) { + t.Parallel() ctx := context.Background() q := NewQuery(ast.MustParseBody("opa.runtime(x)")).WithRuntime(ast.MustParseTerm(`{"config": { diff --git a/topdown/save_test.go b/topdown/save_test.go index 0f3522680b..86aba38e86 100644 --- a/topdown/save_test.go +++ b/topdown/save_test.go @@ -11,6 +11,7 @@ import ( ) func TestSaveSet(t *testing.T) { + t.Parallel() tests := []struct { terms []string diff --git a/topdown/sets_test.go b/topdown/sets_test.go index c999bb004a..ad152ad8ae 100644 --- a/topdown/sets_test.go +++ b/topdown/sets_test.go @@ -11,6 +11,8 @@ import ( ) func TestSetUnionBuiltin(t *testing.T) { + t.Parallel() + tests := []struct { note string query string diff --git a/topdown/time_test.go b/topdown/time_test.go index 64c955e5a9..5ebb0836c5 100644 --- a/topdown/time_test.go +++ b/topdown/time_test.go @@ -14,6 +14,7 @@ import ( ) func TestTimeSeeding(t *testing.T) { + t.Parallel() query := `time.now_ns(x)` clock := time.Now() diff --git a/topdown/tokens_test.go b/topdown/tokens_test.go index 129b04c1be..02f63a55ab 100644 --- a/topdown/tokens_test.go +++ b/topdown/tokens_test.go @@ -22,8 +22,12 @@ import ( ) func TestParseTokenConstraints(t *testing.T) { + t.Parallel() + wallclock := ast.NumberTerm(int64ToJSONNumber(time.Now().UnixNano())) t.Run("Empty", func(t *testing.T) { + t.Parallel() + c := ast.NewObject() constraints, err := parseTokenConstraints(c, wallclock) if err != nil { @@ -37,6 +41,8 @@ func TestParseTokenConstraints(t *testing.T) { } }) t.Run("Alg", func(t *testing.T) { + t.Parallel() + c := ast.NewObject() c.Insert(ast.StringTerm("alg"), ast.StringTerm("RS256")) constraints, err := parseTokenConstraints(c, wallclock) @@ -48,6 +54,8 @@ func TestParseTokenConstraints(t *testing.T) { } }) t.Run("Cert", func(t *testing.T) { + t.Parallel() + c := ast.NewObject() c.Insert(ast.StringTerm("cert"), ast.StringTerm(`-----BEGIN CERTIFICATE----- MIIBcDCCARagAwIBAgIJAMZmuGSIfvgzMAoGCCqGSM49BAMCMBMxETAPBgNVBAMM @@ -75,6 +83,8 @@ OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm } }) t.Run("Cert Multi Key", func(t *testing.T) { + t.Parallel() + c := ast.NewObject() c.Insert(ast.StringTerm("cert"), ast.StringTerm(`{ "keys": [ @@ -113,6 +123,8 @@ OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm } }) t.Run("Time", func(t *testing.T) { + t.Parallel() + now := time.Now() wallclock := ast.NumberTerm(int64ToJSONNumber(now.UnixNano())) @@ -129,6 +141,8 @@ OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm }) t.Run("unset, defaults to wallclock", func(t *testing.T) { + t.Parallel() + c := ast.NewObject() // 'time' constraint is unset constraints, err := parseTokenConstraints(c, wallclock) if err != nil { @@ -141,6 +155,8 @@ OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm }) t.Run("Unrecognized", func(t *testing.T) { + t.Parallel() + c := ast.NewObject() c.Insert(ast.StringTerm("whatever"), ast.StringTerm("junk")) _, err := parseTokenConstraints(c, wallclock) @@ -151,7 +167,11 @@ OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm } func TestParseTokenHeader(t *testing.T) { + t.Parallel() + t.Run("Errors", func(t *testing.T) { + t.Parallel() + token := &JSONWebToken{ header: "", } @@ -179,6 +199,8 @@ func TestParseTokenHeader(t *testing.T) { } }) t.Run("Alg", func(t *testing.T) { + t.Parallel() + token := &JSONWebToken{ header: base64.RawURLEncoding.EncodeToString([]byte(`{"alg":"RS256"}`)), } @@ -199,6 +221,8 @@ func TestParseTokenHeader(t *testing.T) { } func TestTopDownJWTEncodeSignES256(t *testing.T) { + t.Parallel() + const examplePayload = `{"iss":"joe",` + "\r\n" + ` "exp":1300819380,` + "\r\n" + ` "http://example.com/is_root":true}` const es256Hdr = `{"alg":"ES256"}` const ecKey = `{ @@ -320,6 +344,8 @@ func TestTopDownJWTEncodeSignES256(t *testing.T) { // TestTopDownJWTEncodeSignEC needs to perform all tests inline because we do not know the // expected values before hand func TestTopDownJWTEncodeSignES512(t *testing.T) { + t.Parallel() + const examplePayload = `{"iss":"joe",` + "\r\n" + ` "exp":1300819380,` + "\r\n" + ` "http://example.com/is_root":true}` const es512Hdr = `{"alg":"ES512"}` const ecKey = `{ @@ -457,6 +483,8 @@ func (*cng) Read(p []byte) (int, error) { } func TestTopdownJWTEncodeSignECWithSeedReturnsSameSignature(t *testing.T) { + t.Parallel() + query := `io.jwt.encode_sign({"alg": "ES256"},{"pay": "load"}, {"kty":"EC", "crv":"P-256", @@ -490,6 +518,8 @@ func TestTopdownJWTEncodeSignECWithSeedReturnsSameSignature(t *testing.T) { } func TestTopdownJWTUnknownAlgTypesDiscardedFromJWKS(t *testing.T) { + t.Parallel() + cert := `{ "keys": [ { @@ -531,6 +561,8 @@ func TestTopdownJWTUnknownAlgTypesDiscardedFromJWKS(t *testing.T) { } func TestTopdownJWTVerifyOnlyVerifiesUsingApplicableKeys(t *testing.T) { + t.Parallel() + cert := ast.MustInterfaceToValue(`{ "keys": [ { @@ -603,7 +635,10 @@ func TestTopdownJWTVerifyOnlyVerifiesUsingApplicableKeys(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + header := base64.RawURLEncoding.EncodeToString([]byte(tc.header)) payload := base64.RawURLEncoding.EncodeToString([]byte("{}")) signature := base64.RawURLEncoding.EncodeToString([]byte("ignored")) @@ -629,6 +664,8 @@ func TestTopdownJWTVerifyOnlyVerifiesUsingApplicableKeys(t *testing.T) { } func TestTopdownJWTDecodeVerifyIgnoresKeysOfUnknownAlgInJWKS(t *testing.T) { + t.Parallel() + c := ast.NewObject() c.Insert(ast.StringTerm("cert"), ast.StringTerm(`{ "keys": [ diff --git a/topdown/topdown_partial_test.go b/topdown/topdown_partial_test.go index 8f68ac89b5..736853100b 100644 --- a/topdown/topdown_partial_test.go +++ b/topdown/topdown_partial_test.go @@ -18,6 +18,8 @@ import ( ) func TestTopDownPartialEval(t *testing.T) { + t.Parallel() + tests := []struct { note string unknowns []string diff --git a/topdown/topdown_test.go b/topdown/topdown_test.go index 7dce7d3947..5a40e24604 100644 --- a/topdown/topdown_test.go +++ b/topdown/topdown_test.go @@ -33,6 +33,8 @@ import ( ) func TestTopDownQueryIDsUnique(t *testing.T) { + t.Parallel() + ctx := context.Background() store := inmem.New() inputTerm := &ast.Term{} @@ -71,6 +73,8 @@ func TestTopDownQueryIDsUnique(t *testing.T) { } func TestTopDownIndexExpr(t *testing.T) { + t.Parallel() + ctx := context.Background() store := inmem.New() txn := storage.NewTransactionOrDie(ctx, store) @@ -124,6 +128,7 @@ func TestTopDownIndexExpr(t *testing.T) { } func TestTopDownWithKeyword(t *testing.T) { + t.Parallel() tests := []struct { note string @@ -158,8 +163,9 @@ func TestTopDownWithKeyword(t *testing.T) { } } +// Warning(philipc): This test modifies package variables in the ast package, +// which means it cannot be run in parallel with other tests. func TestTopDownUnsupportedBuiltin(t *testing.T) { - ast.RegisterBuiltin(&ast.Builtin{ Name: "unsupported_builtin", }) @@ -178,10 +184,10 @@ func TestTopDownUnsupportedBuiltin(t *testing.T) { if !reflect.DeepEqual(err, expected) { t.Fatalf("Expected %v but got: %v", expected, err) } - } func TestTopDownQueryCancellation(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -230,6 +236,8 @@ func TestTopDownQueryCancellation(t *testing.T) { } func TestTopDownQueryCancellationEvery(t *testing.T) { + t.Parallel() + ctx := context.Background() module := func(ev ast.Every, _ ...interface{}) *ast.Module { @@ -264,7 +272,10 @@ func TestTopDownQueryCancellationEvery(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + compiler := ast.NewCompiler().WithEnablePrintStatements(true) compiler.Compile(map[string]*ast.Module{"test.rego": tc.module}) if compiler.Failed() { @@ -325,6 +336,8 @@ func TestTopDownQueryCancellationEvery(t *testing.T) { } func TestTopDownEarlyExit(t *testing.T) { + t.Parallel() + // NOTE(sr): There are two ways to early-exit: don't evaluate subsequent // rule bodies, like // @@ -1494,7 +1507,10 @@ arr := [1, 2, 3, 4, 5] }, } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + countExit := 1 + tc.extraExit ctx := context.Background() compiler := compileModules([]string{tc.module}) @@ -1553,6 +1569,8 @@ arr := [1, 2, 3, 4, 5] } func TestTopDownEvery(t *testing.T) { + t.Parallel() + n := func(ns ...string) []string { return ns } tests := []struct { @@ -1662,7 +1680,10 @@ func TestTopDownEvery(t *testing.T) { }, } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + ctx := context.Background() c := ast.NewCompiler().WithEnablePrintStatements(true) mod := ast.MustParseModuleWithOpts(tc.module, ast.ParserOptions{AllFutureKeywords: true}) @@ -1743,6 +1764,7 @@ func (m *contextPropagationStore) Read(ctx context.Context, _ storage.Transactio } func TestTopDownContextPropagation(t *testing.T) { + t.Parallel() ctx := context.WithValue(context.Background(), contextPropagationMock{}, "bar") @@ -1808,6 +1830,8 @@ func (a *astStore) Read(_ context.Context, _ storage.Transaction, path storage.P } func TestTopdownStoreAST(t *testing.T) { + t.Parallel() + body := ast.MustParseBody(`data.stored = x`) ctx := context.Background() compiler := ast.NewCompiler() @@ -1832,6 +1856,8 @@ func TestTopdownStoreAST(t *testing.T) { } func TestTopdownLazyObj(t *testing.T) { + t.Parallel() + body := ast.MustParseBody(`data.stored = x`) ctx := context.Background() compiler := ast.NewCompiler() @@ -1862,6 +1888,8 @@ func TestTopdownLazyObj(t *testing.T) { } func TestTopdownLazyObjOptOut(t *testing.T) { + t.Parallel() + body := ast.MustParseBody(`data.stored = x`) ctx := context.Background() compiler := ast.NewCompiler() diff --git a/topdown/trace_test.go b/topdown/trace_test.go index d57dd3c9c9..cf50089eec 100644 --- a/topdown/trace_test.go +++ b/topdown/trace_test.go @@ -19,6 +19,7 @@ import ( ) func TestEventEqual(t *testing.T) { + t.Parallel() a := ast.NewValueMap() a.Put(ast.String("foo"), ast.Number("1")) @@ -54,6 +55,8 @@ func TestEventEqual(t *testing.T) { } func TestPrettyTrace(t *testing.T) { + t.Parallel() + module := `package test p if { q[x]; plus(x, 1, n) } @@ -114,6 +117,8 @@ Redo data.test.p = _ } func TestPrettyTraceWithLocation(t *testing.T) { + t.Parallel() + module := `package test p if { q[x]; plus(x, 1, n) } @@ -174,6 +179,8 @@ query:3 | | Redo data.test.q[x] } func TestPrettyTraceWithLocationTruncatedPaths(t *testing.T) { + t.Parallel() + ctx := context.Background() compiler := ast.MustCompileModulesWithOpts(map[string]string{ @@ -245,6 +252,8 @@ authz_bundle/...ternal/authz/policies/abac/v1/beta/policy.rego:5 | | Redo da } func TestPrettyTracePartialWithLocationTruncatedPaths(t *testing.T) { + t.Parallel() + ctx := context.Background() compiler := ast.MustCompileModulesWithOpts(map[string]string{ @@ -414,6 +423,8 @@ query:1 | Fail data } func TestTraceDuplicate(t *testing.T) { + t.Parallel() + // NOTE(sr): We're explicitly bypassing a caching optimization here: // When the first query for a partial is `p[x]`, and `x` is not ground, // we'll have the evaluation eval the full extent of the partial and @@ -459,6 +470,8 @@ func TestTraceDuplicate(t *testing.T) { } func TestTraceNote(t *testing.T) { + t.Parallel() + module := `package test p if { q[x]; plus(x, 1, n); trace(sprintf("n=%v", [n])) } @@ -524,6 +537,8 @@ Redo data.test.p = _ } func TestTraceNoteWithLocation(t *testing.T) { + t.Parallel() + module := `package test p if { q[x]; plus(x, 1, n); trace(sprintf("n=%v", [n])) } @@ -589,6 +604,7 @@ query:3 | | Redo data.test.q[x] } func TestMultipleTracers(t *testing.T) { + t.Parallel() ctx := context.Background() @@ -616,6 +632,8 @@ func TestMultipleTracers(t *testing.T) { } func TestTraceRewrittenQueryVars(t *testing.T) { + t.Parallel() + module := `package test y = [1, 2, 3]` @@ -674,6 +692,7 @@ func TestTraceRewrittenQueryVars(t *testing.T) { } func TestTraceRewrittenVars(t *testing.T) { + t.Parallel() mustParse := func(s string) *ast.Expr { return ast.MustParseBodyWithOpts(s, ast.ParserOptions{FutureKeywords: []string{"every"}})[0] @@ -743,7 +762,10 @@ func TestTraceRewrittenVars(t *testing.T) { } for _, tc := range tests { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + output := rewrite(tc.evt) tc.exp(t, tc.evt, output) }) @@ -751,6 +773,8 @@ func TestTraceRewrittenVars(t *testing.T) { } func TestTraceEveryEvaluation(t *testing.T) { + t.Parallel() + ctx := context.Background() events := func(es ...string) []string { @@ -865,6 +889,8 @@ func TestTraceEveryEvaluation(t *testing.T) { } func TestShortTraceFileNames(t *testing.T) { + t.Parallel() + longFilePath1 := "/really/long/file/path/longer/than/most/would/really/ever/be/policy.rego" longFilePath1Similar := "/really/long/file/path/longer/than/most/policy.rego" longFilePath2 := "GfjEjnMA6coNiPoMoRMVk7KeorGeRmjRkIYUsWtr564SQ7yDo4Yss2SoN8PMoe0TOfVaNFd1HQbC9NhK.rego" @@ -1003,7 +1029,10 @@ func TestShortTraceFileNames(t *testing.T) { } for _, tc := range cases { + tc := tc // copy for capturing loop variable (not needed in Go 1.22+) t.Run(tc.note, func(t *testing.T) { + t.Parallel() + actualNames, actualLongest := getShortenedFileNames(tc.trace) if actualLongest != tc.expectedLongest { t.Errorf("Expected longest location to be %d, got %d", tc.expectedLongest, actualLongest) @@ -1017,6 +1046,8 @@ func TestShortTraceFileNames(t *testing.T) { } func TestBufferTracerTraceConfig(t *testing.T) { + t.Parallel() + ct := QueryTracer(NewBufferTracer()) conf := ct.Config() @@ -1030,6 +1061,8 @@ func TestBufferTracerTraceConfig(t *testing.T) { } func TestTraceInput(t *testing.T) { + t.Parallel() + ctx := context.Background() module := ` package test @@ -1072,6 +1105,8 @@ func TestTraceInput(t *testing.T) { } func TestTracePlug(t *testing.T) { + t.Parallel() + ctx := context.Background() module := ` package test @@ -1163,6 +1198,8 @@ func compareBuffers(t *testing.T, expected, actual string) { } func TestPrettyTraceWithLocationForMetadataCall(t *testing.T) { + t.Parallel() + module := `package test rule_no_output_var := rego.metadata.rule() @@ -1252,6 +1289,8 @@ query:1 | Redo data.test = _ } func TestPrettyTraceWithUnifyOps(t *testing.T) { + t.Parallel() + module := `package test p contains x if { @@ -1309,6 +1348,8 @@ func removeUnifyOps(trace []*Event) (result []*Event) { } func TestPrettyTraceWithLocalVars(t *testing.T) { + t.Parallel() + { module := `package test @@ -1393,6 +1434,8 @@ Redo data.test = _ {_: {"p": true}} } func TestPrettyTraceExprVars(t *testing.T) { + t.Parallel() + { module := `package test diff --git a/topdown/uuid_test.go b/topdown/uuid_test.go index b4cbe8d363..b122e3a892 100644 --- a/topdown/uuid_test.go +++ b/topdown/uuid_test.go @@ -14,6 +14,7 @@ import ( ) func TestUUIDRFC4122SeedingAndCaching(t *testing.T) { + t.Parallel() query := `uuid.rfc4122("x",x); uuid.rfc4122("y", y); uuid.rfc4122("x",x2)` @@ -43,7 +44,6 @@ func TestUUIDRFC4122SeedingAndCaching(t *testing.T) { if !result.Equal(exp) { t.Fatalf("expected %v but got %v", exp, result) } - } type fakeSeedErrorReader struct{} @@ -53,6 +53,7 @@ func (fakeSeedErrorReader) Read([]byte) (int, error) { } func TestUUIDRFC4122SeedError(t *testing.T) { + t.Parallel() query := `uuid.rfc4122("x",x)` @@ -63,10 +64,10 @@ func TestUUIDRFC4122SeedError(t *testing.T) { if topdownErr, ok := err.(*Error); !ok || topdownErr.Code != BuiltinErr { t.Fatal("unexpected error (or lack of error):", err) } - } func TestUUIDRFC4122SavingDuringPartialEval(t *testing.T) { + t.Parallel() query := `foo = "x"; uuid.rfc4122(foo,x)` c := ast.NewCompiler().