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 }