123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // Package suite is a simplified version of testify's suite package which has unnecessary dependencies.
- // Please remove this package whenever possible.
- package suite
- import (
- "context"
- "flag"
- "reflect"
- "runtime/debug"
- "strings"
- "testing"
- "github.com/docker/docker/testutil"
- )
- // TimeoutFlag is the flag to set a per-test timeout when running tests. Defaults to `-timeout`.
- var TimeoutFlag = flag.Duration("timeout", 0, "DO NOT USE")
- var typTestingT = reflect.TypeOf(new(testing.T))
- // Run takes a testing suite and runs all of the tests attached to it.
- func Run(ctx context.Context, t *testing.T, suite interface{}) {
- defer failOnPanic(t)
- ctx = testutil.StartSpan(ctx, t)
- suiteCtx := ctx
- suiteSetupDone := false
- defer func() {
- if suiteSetupDone {
- if tearDownAllSuite, ok := getTeardownAllSuite(suite); ok {
- tearDownAllSuite.TearDownSuite(suiteCtx, t)
- }
- }
- }()
- methodFinder := reflect.TypeOf(suite)
- for index := 0; index < methodFinder.NumMethod(); index++ {
- method := methodFinder.Method(index)
- if !methodFilter(method.Name, method.Type) {
- continue
- }
- t.Run(method.Name, func(t *testing.T) {
- ctx := testutil.StartSpan(ctx, t)
- testutil.SetContext(t, ctx)
- t.Cleanup(func() {
- testutil.CleanupContext(t)
- })
- defer failOnPanic(t)
- if !suiteSetupDone {
- if setupAllSuite, ok := getSetupAllSuite(suite); ok {
- setupAllSuite.SetUpSuite(suiteCtx, t)
- }
- suiteSetupDone = true
- }
- if setupTestSuite, ok := getSetupTestSuite(suite); ok {
- setupTestSuite.SetUpTest(ctx, t)
- }
- defer func() {
- if tearDownTestSuite, ok := getTearDownTestSuite(suite); ok {
- tearDownTestSuite.TearDownTest(ctx, t)
- }
- }()
- method.Func.Call([]reflect.Value{reflect.ValueOf(suite), reflect.ValueOf(t)})
- })
- }
- }
- func getSetupAllSuite(suite interface{}) (SetupAllSuite, bool) {
- setupAllSuite, ok := suite.(SetupAllSuite)
- if ok {
- return setupAllSuite, ok
- }
- t := reflect.TypeOf(suite)
- for i := 0; i < t.NumMethod(); i++ {
- if t.Method(i).Name == "SetUpSuite" {
- panic("Wrong SetUpSuite signature")
- }
- }
- return nil, false
- }
- func getSetupTestSuite(suite interface{}) (SetupTestSuite, bool) {
- setupAllTest, ok := suite.(SetupTestSuite)
- if ok {
- return setupAllTest, ok
- }
- t := reflect.TypeOf(suite)
- for i := 0; i < t.NumMethod(); i++ {
- if t.Method(i).Name == "SetUpTest" {
- panic("Wrong SetUpTest signature")
- }
- }
- return nil, false
- }
- func getTearDownTestSuite(suite interface{}) (TearDownTestSuite, bool) {
- tearDownTest, ok := suite.(TearDownTestSuite)
- if ok {
- return tearDownTest, ok
- }
- t := reflect.TypeOf(suite)
- for i := 0; i < t.NumMethod(); i++ {
- if t.Method(i).Name == "TearDownTest" {
- panic("Wrong TearDownTest signature")
- }
- }
- return nil, false
- }
- func getTeardownAllSuite(suite interface{}) (TearDownAllSuite, bool) {
- tearDownAll, ok := suite.(TearDownAllSuite)
- if ok {
- return tearDownAll, ok
- }
- t := reflect.TypeOf(suite)
- for i := 0; i < t.NumMethod(); i++ {
- if t.Method(i).Name == "TearDownSuite" {
- panic("Wrong TearDownSuite signature")
- }
- }
- return nil, false
- }
- func failOnPanic(t *testing.T) {
- r := recover()
- if r != nil {
- t.Errorf("test suite panicked: %v\n%s", r, debug.Stack())
- t.FailNow()
- }
- }
- func methodFilter(name string, typ reflect.Type) bool {
- return strings.HasPrefix(name, "Test") && typ.NumIn() == 2 && typ.In(1) == typTestingT // 2 params: method receiver and *testing.T
- }
|