github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/integration_test/itest/runner.go (about)

     1  package itest
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/suite"
     8  
     9  	"github.com/datawire/dtest"
    10  )
    11  
    12  type Runner interface {
    13  	AddClusterSuite(func(context.Context) TestingSuite)
    14  	AddNamespacePairSuite(suffix string, f func(NamespacePair) TestingSuite)
    15  	AddTrafficManagerSuite(suffix string, f func(NamespacePair) TestingSuite)
    16  	AddConnectedSuite(suffix string, f func(NamespacePair) TestingSuite)
    17  	AddMultipleServicesSuite(suffix, name string, f func(MultipleServices) TestingSuite)
    18  	AddSingleServiceSuite(suffix, name string, f func(SingleService) TestingSuite)
    19  	RunTests(context.Context)
    20  }
    21  
    22  type namedRunner struct {
    23  	withMultipleServices []func(MultipleServices) TestingSuite
    24  	withSingleService    []func(SingleService) TestingSuite
    25  }
    26  
    27  type suffixedRunner struct {
    28  	withNamespace      []func(NamespacePair) TestingSuite
    29  	withTrafficManager []func(NamespacePair) TestingSuite
    30  	withConnected      []func(NamespacePair) TestingSuite
    31  	withName           map[string]*namedRunner
    32  }
    33  
    34  type runner struct {
    35  	withCluster []func(ctx context.Context) TestingSuite
    36  	withSuffix  map[string]*suffixedRunner
    37  }
    38  
    39  var defaultRunner Runner = &runner{withSuffix: make(map[string]*suffixedRunner)} //nolint:gochecknoglobals // integration test config
    40  
    41  // AddClusterSuite adds a constructor for a test suite that requires a cluster to run to the default runner.
    42  func AddClusterSuite(f func(context.Context) TestingSuite) {
    43  	defaultRunner.AddClusterSuite(f)
    44  }
    45  
    46  // AddClusterSuite adds a constructor for a test suite that requires a cluster to run.
    47  func (r *runner) AddClusterSuite(f func(context.Context) TestingSuite) {
    48  	r.withCluster = append(r.withCluster, f)
    49  }
    50  
    51  func (r *runner) forSuffix(suffix string) *suffixedRunner {
    52  	sr, ok := r.withSuffix[suffix]
    53  	if !ok {
    54  		sr = &suffixedRunner{withName: map[string]*namedRunner{}}
    55  		r.withSuffix[suffix] = sr
    56  	}
    57  	return sr
    58  }
    59  
    60  // AddNamespacePairSuite adds a constructor for a test suite that requires a cluster where a namespace
    61  // pair has been initialized to the default runner.
    62  func AddNamespacePairSuite(suffix string, f func(NamespacePair) TestingSuite) {
    63  	defaultRunner.AddNamespacePairSuite(suffix, f)
    64  }
    65  
    66  // AddNamespacePairSuite adds a constructor for a test suite that requires a cluster where a namespace
    67  // pair has been initialized.
    68  func (r *runner) AddNamespacePairSuite(suffix string, f func(NamespacePair) TestingSuite) {
    69  	sr := r.forSuffix(suffix)
    70  	sr.withNamespace = append(sr.withNamespace, f)
    71  }
    72  
    73  // AddTrafficManagerSuite adds a constructor for a test suite that requires a cluster where a namespace
    74  // pair has been initialized and a traffic manager is installed.
    75  func AddTrafficManagerSuite(suffix string, f func(NamespacePair) TestingSuite) {
    76  	defaultRunner.AddTrafficManagerSuite(suffix, f)
    77  }
    78  
    79  // AddTrafficManagerSuite adds a constructor for a test suite that requires a cluster where a namespace
    80  // pair has been initialized and a traffic manager is installed.
    81  func (r *runner) AddTrafficManagerSuite(suffix string, f func(NamespacePair) TestingSuite) {
    82  	sr := r.forSuffix(suffix)
    83  	sr.withTrafficManager = append(sr.withTrafficManager, f)
    84  }
    85  
    86  func (r *suffixedRunner) forName(name string) *namedRunner {
    87  	nr, ok := r.withName[name]
    88  	if !ok {
    89  		nr = &namedRunner{}
    90  		r.withName[name] = nr
    91  	}
    92  	return nr
    93  }
    94  
    95  // AddConnectedSuite adds a constructor for a test suite to the default runner that requires a cluster where a namespace
    96  // pair has been initialized, and telepresence is connected.
    97  func AddConnectedSuite(suffix string, f func(NamespacePair) TestingSuite) {
    98  	defaultRunner.AddConnectedSuite(suffix, f)
    99  }
   100  
   101  // AddConnectedSuite adds a constructor for a test suite to the default runner that requires a cluster where a namespace
   102  // pair has been initialized, and telepresence is connected.
   103  func (r *runner) AddConnectedSuite(suffix string, f func(NamespacePair) TestingSuite) {
   104  	sr := r.forSuffix(suffix)
   105  	sr.withConnected = append(sr.withConnected, f)
   106  }
   107  
   108  // AddMultipleServicesSuite adds a constructor for a test suite to the default runner that requires a cluster where a namespace
   109  // pair has been initialized, multiple services has been installed, and telepresence is connected.
   110  func AddMultipleServicesSuite(suffix, name string, f func(services MultipleServices) TestingSuite) {
   111  	defaultRunner.AddMultipleServicesSuite(suffix, name, f)
   112  }
   113  
   114  // AddMultipleServicesSuite adds a constructor for a test suite that requires a cluster where a namespace
   115  // pair has been initialized, multiple services has been installed, and telepresence is connected.
   116  func (r *runner) AddMultipleServicesSuite(suffix, name string, f func(services MultipleServices) TestingSuite) {
   117  	nr := r.forSuffix(suffix).forName(name)
   118  	nr.withMultipleServices = append(nr.withMultipleServices, f)
   119  }
   120  
   121  // AddSingleServiceSuite adds a constructor for a test suite to the default runner that requires a cluster where a namespace
   122  // pair has been initialized, a service has been installed, and telepresence is connected.
   123  func AddSingleServiceSuite(suffix, name string, f func(services SingleService) TestingSuite) {
   124  	defaultRunner.AddSingleServiceSuite(suffix, name, f)
   125  }
   126  
   127  // AddSingleServiceSuite adds a constructor for a test suite that requires a cluster where a namespace
   128  // pair has been initialized, a service has been installed, and telepresence is connected.
   129  func (r *runner) AddSingleServiceSuite(suffix, name string, f func(services SingleService) TestingSuite) {
   130  	nr := r.forSuffix(suffix).forName(name)
   131  	nr.withSingleService = append(nr.withSingleService, f)
   132  }
   133  
   134  func RunTests(c context.Context) {
   135  	defaultRunner.RunTests(c)
   136  }
   137  
   138  // RunTests creates all suites using the added constructors and runs them.
   139  func (r *runner) RunTests(c context.Context) { //nolint:gocognit
   140  	c = LoadEnv(c)
   141  	dtest.WithMachineLock(c, func(c context.Context) {
   142  		WithCluster(c, func(c context.Context) {
   143  			func() {
   144  				t := getT(c)
   145  				for _, f := range r.withCluster {
   146  					s := f(c)
   147  					if suiteEnabled(c, s) {
   148  						t.Run(s.SuiteName(), func(t *testing.T) {
   149  							ts := f(c)
   150  							ts.setContext(ts.AmendSuiteContext(c))
   151  							suite.Run(t, ts)
   152  						})
   153  					}
   154  				}
   155  			}()
   156  			for s, sr := range r.withSuffix {
   157  				WithNamespacePair(c, GetGlobalHarness(c).Suffix()+s, func(np NamespacePair) {
   158  					for _, f := range sr.withNamespace {
   159  						np.RunSuite(f(np))
   160  					}
   161  					if len(sr.withTrafficManager)+len(sr.withConnected)+len(sr.withName) > 0 {
   162  						WithTrafficManager(np, func(c context.Context, cnp NamespacePair) {
   163  							for _, f := range sr.withTrafficManager {
   164  								cnp.RunSuite(f(cnp))
   165  							}
   166  							if len(sr.withConnected)+len(sr.withName) > 0 {
   167  								WithConnected(np, func(c context.Context, cnp NamespacePair) {
   168  									for _, f := range sr.withConnected {
   169  										cnp.RunSuite(f(cnp))
   170  									}
   171  									for n, nr := range sr.withName {
   172  										if len(nr.withMultipleServices) > 0 {
   173  											WithMultipleServices(cnp, n, 3, func(ms MultipleServices) {
   174  												for _, f := range nr.withMultipleServices {
   175  													ms.RunSuite(f(ms))
   176  												}
   177  											})
   178  										}
   179  										if len(nr.withSingleService) > 0 {
   180  											WithSingleService(cnp, n, func(ss SingleService) {
   181  												for _, f := range nr.withSingleService {
   182  													ss.RunSuite(f(ss))
   183  												}
   184  											})
   185  										}
   186  									}
   187  								})
   188  							}
   189  						})
   190  					}
   191  				})
   192  			}
   193  		})
   194  	})
   195  }