diff --git a/extensions/parallel/options.go b/extensions/parallel/options.go index c27432d070..40162efd28 100644 --- a/extensions/parallel/options.go +++ b/extensions/parallel/options.go @@ -17,15 +17,15 @@ package parallel type parallelOptions struct { - excludedTests []string + syncTests []func() } // Option is an option pattern for parallel package type Option func(o *parallelOptions) -// WithExcludedTests - set a list of tests to exclude from parallel execution -func WithExcludedTests(tests []string) Option { +// WithRunningTestsSynchronously - set a list of tests that should be run synchronously +func WithRunningTestsSynchronously(tests ...func()) Option { return func(o *parallelOptions) { - o.excludedTests = tests + o.syncTests = tests } } diff --git a/extensions/parallel/suite.go b/extensions/parallel/suite.go index d4492469dd..6cb6f5fc2c 100644 --- a/extensions/parallel/suite.go +++ b/extensions/parallel/suite.go @@ -19,6 +19,7 @@ package parallel import ( "reflect" + "runtime" "runtime/debug" "strings" "testing" @@ -45,9 +46,9 @@ func Run(t *testing.T, s suite.TestingSuite, options ...Option) { opt(parallelOpts) } - excludedTestsSet := make(map[string]struct{}) - for _, test := range parallelOpts.excludedTests { - excludedTestsSet[test] = struct{}{} + syncedTestsSet := make(map[string]struct{}, len(parallelOpts.syncTests)) + for _, test := range parallelOpts.syncTests { + syncedTestsSet[getFunctionName(test)] = struct{}{} } defer recoverAndFailOnPanic(t) @@ -71,7 +72,7 @@ func Run(t *testing.T, s suite.TestingSuite, options ...Option) { continue } parallel := true - if _, ok := excludedTestsSet[method.Name]; ok { + if _, ok := syncedTestsSet[method.Name]; ok { parallel = false } @@ -136,3 +137,10 @@ func newTest(t *testing.T, s suite.TestingSuite, methodFinder reflect.Type, meth }, } } + +func getFunctionName(fn interface{}) string { + var rawFnName = runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name() + var splitFn = func(r rune) bool { return r == '.' || r == '-' } + var segments = strings.FieldsFunc(rawFnName, splitFn) + return segments[len(segments)-2] +} diff --git a/extensions/parallel/suite_test.go b/extensions/parallel/suite_test.go new file mode 100644 index 0000000000..34f9cc9ad6 --- /dev/null +++ b/extensions/parallel/suite_test.go @@ -0,0 +1,57 @@ +// Copyright (c) 2024 Pragmagic Inc. and/or its affiliates. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package parallel_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "go.uber.org/goleak" + + "github.com/networkservicemesh/integration-tests/extensions/parallel" +) + +type negativeSuite struct { + suite.Suite +} + +func (s *negativeSuite) TestParallel1() {} +func (s *negativeSuite) TestParallel2() {} +func (s *negativeSuite) TestParallel3() {} + +func (s *negativeSuite) TestSynchronously() { + s.Error(goleak.Find()) +} + +type positiveSuite struct { + suite.Suite +} + +func (s *positiveSuite) TestParallel1() {} +func (s *positiveSuite) TestParallel2() {} +func (s *positiveSuite) TestParallel3() {} + +func (s *positiveSuite) TestSynchronously() { + s.NoError(goleak.Find()) +} + +func Test_OptionWithRunningTestsSynchronously_ShouldExcludeTestsFromParallelExecution(t *testing.T) { + var s1 = new(negativeSuite) + parallel.Run(t, s1) + var s2 = new(positiveSuite) + parallel.Run(t, s2, parallel.WithRunningTestsSynchronously(s2.TestSynchronously)) +} diff --git a/go.mod b/go.mod index 1669f92260..d2b2a36944 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/networkservicemesh/gotestmd v0.0.0-20220628095933-eabbdc09e0dc github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.8.4 + go.uber.org/goleak v1.1.10 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index c6c614152a..978501e8cd 100644 --- a/go.sum +++ b/go.sum @@ -40,10 +40,12 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=