@@ -15,6 +15,7 @@ import (
15
15
"github.com/testcontainers/testcontainers-go"
16
16
"github.com/testcontainers/testcontainers-go/wait"
17
17
orderedmap "github.com/wk8/go-ordered-map/v2"
18
+ "log"
18
19
"net/http"
19
20
"os"
20
21
"os/exec"
@@ -43,7 +44,7 @@ type OctopusContainer struct {
43
44
URI string
44
45
}
45
46
46
- type mysqlContainer struct {
47
+ type MysqlContainer struct {
47
48
testcontainers.Container
48
49
port string
49
50
ip string
@@ -99,7 +100,7 @@ func (o *OctopusContainerTest) setupNetwork(ctx context.Context) (testcontainers
99
100
}
100
101
101
102
// setupDatabase creates a MSSQL container
102
- func (o * OctopusContainerTest ) setupDatabase (ctx context.Context , network string ) (* mysqlContainer , error ) {
103
+ func (o * OctopusContainerTest ) setupDatabase (ctx context.Context , network string ) (* MysqlContainer , error ) {
103
104
req := testcontainers.ContainerRequest {
104
105
Name : "mssql-" + uuid .New ().String (),
105
106
Image : "mcr.microsoft.com/mssql/server" ,
@@ -135,7 +136,7 @@ func (o *OctopusContainerTest) setupDatabase(ctx context.Context, network string
135
136
return nil , err
136
137
}
137
138
138
- return & mysqlContainer {
139
+ return & MysqlContainer {
139
140
Container : container ,
140
141
ip : ip ,
141
142
port : mappedPort .Port (),
@@ -170,7 +171,7 @@ func (o *OctopusContainerTest) getRetryCount() uint {
170
171
}
171
172
172
173
// setupOctopus creates an Octopus container
173
- func (o * OctopusContainerTest ) setupOctopus (ctx context.Context , connString string , network string , t * testing. T ) (* OctopusContainer , error ) {
174
+ func (o * OctopusContainerTest ) setupOctopus (ctx context.Context , connString string , network string ) (* OctopusContainer , error ) {
174
175
if os .Getenv ("LICENSE" ) == "" {
175
176
return nil , errors .New ("the LICENSE environment variable must be set to a base 64 encoded Octopus license key" )
176
177
}
@@ -203,7 +204,7 @@ func (o *OctopusContainerTest) setupOctopus(ctx context.Context, connString stri
203
204
network ,
204
205
},
205
206
}
206
- t . Log ("Creating Octopus container" )
207
+ log . Println ("Creating Octopus container" )
207
208
container , err := testcontainers .GenericContainer (ctx , testcontainers.GenericContainerRequest {
208
209
ContainerRequest : req ,
209
210
Started : true ,
@@ -212,7 +213,7 @@ func (o *OctopusContainerTest) setupOctopus(ctx context.Context, connString stri
212
213
if err != nil {
213
214
return nil , err
214
215
}
215
- t . Log ("Finished creating Octopus container" )
216
+ log . Println ("Finished creating Octopus container" )
216
217
217
218
// Display the container logs
218
219
if os .Getenv ("OCTODISABLEOCTOCONTAINERLOGGING" ) != "true" {
@@ -237,7 +238,7 @@ func (o *OctopusContainerTest) setupOctopus(ctx context.Context, connString stri
237
238
// createDockerInfrastructure attemptes to create the complete Docker stack containing a
238
239
// network, MSSQL container, and Octopus container. The return values include as much of
239
240
// the partial stack as possible in the case of an error.
240
- func (o * OctopusContainerTest ) createDockerInfrastructure (t * testing.T , ctx context.Context ) (testcontainers.Network , * OctopusContainer , * mysqlContainer , error ) {
241
+ func (o * OctopusContainerTest ) createDockerInfrastructure (t * testing.T , ctx context.Context ) (testcontainers.Network , * OctopusContainer , * MysqlContainer , error ) {
241
242
242
243
network , networkName , err := o .setupNetwork (ctx )
243
244
if err != nil {
@@ -262,7 +263,7 @@ func (o *OctopusContainerTest) createDockerInfrastructure(t *testing.T, ctx cont
262
263
t .Log ("SQL Server IP: " + sqlIp )
263
264
t .Log ("SQL Server Container Name: " + sqlName )
264
265
265
- octopusContainer , err := o .setupOctopus (ctx , "Server=" + sqlIp + ",1433;Database=OctopusDeploy;User=sa;Password=Password01!" , networkName , t )
266
+ octopusContainer , err := o .setupOctopus (ctx , "Server=" + sqlIp + ",1433;Database=OctopusDeploy;User=sa;Password=Password01!" , networkName )
266
267
if err != nil {
267
268
return network , octopusContainer , sqlServer , err
268
269
}
@@ -283,6 +284,120 @@ func (o *OctopusContainerTest) createDockerInfrastructure(t *testing.T, ctx cont
283
284
return network , octopusContainer , sqlServer , nil
284
285
}
285
286
287
+ // ArrangeTestContainer is wrapper that initialises Octopus, and returns the container for future test runs
288
+ func (o * OctopusContainerTest ) ArrangeContainer (m * testing.M ) (* OctopusContainer , * client.Client , * MysqlContainer , testcontainers.Network , error ) {
289
+ var octopusContainer * OctopusContainer
290
+ var octoClient * client.Client
291
+ var network testcontainers.Network
292
+ var networkName string
293
+ var sqlServer * MysqlContainer
294
+
295
+ err := retry .Do (
296
+ func () error {
297
+ ctx := context .Background ()
298
+
299
+ var err error
300
+ network , networkName , err = o .setupNetwork (ctx )
301
+ if err != nil {
302
+ return err
303
+ }
304
+
305
+ sqlServer , err = o .setupDatabase (ctx , networkName )
306
+ if err != nil {
307
+ return err
308
+ }
309
+
310
+ sqlIp , err := sqlServer .Container .ContainerIP (ctx )
311
+ if err != nil {
312
+ return err
313
+ }
314
+
315
+ sqlName , err := sqlServer .Container .Name (ctx )
316
+ if err != nil {
317
+ return err
318
+ }
319
+
320
+ log .Println ("SQL Server IP: " + sqlIp )
321
+ log .Println ("SQL Server Container Name: " + sqlName )
322
+
323
+ octopusContainer , err = o .setupOctopus (ctx , "Server=" + sqlIp + ",1433;Database=OctopusDeploy;User=sa;Password=Password01!" , networkName )
324
+ if err != nil {
325
+ return err
326
+ }
327
+
328
+ octoIp , err := octopusContainer .Container .ContainerIP (ctx )
329
+ if err != nil {
330
+ return err
331
+ }
332
+
333
+ octoName , err := octopusContainer .Container .Name (ctx )
334
+ if err != nil {
335
+ return err
336
+ }
337
+
338
+ log .Println ("Octopus IP: " + octoIp )
339
+ log .Println ("Octopus Container Name: " + octoName )
340
+
341
+ // give the server 5 minutes to start up
342
+ err = lintwait .WaitForResource (func () error {
343
+ resp , err := http .Get (octopusContainer .URI + "/api" )
344
+ if err != nil || resp .StatusCode != http .StatusOK {
345
+ return errors .New ("the api endpoint was not available" )
346
+ }
347
+ return nil
348
+ }, 5 * time .Minute )
349
+
350
+ if err != nil {
351
+ return err
352
+ }
353
+
354
+ octoClient , err = octoclient .CreateClient (octopusContainer .URI , "" , ApiKey )
355
+ if err != nil {
356
+ return err
357
+ }
358
+
359
+ return nil
360
+ },
361
+ retry .Attempts (o .getRetryCount ()),
362
+ retry .Delay (30 * time .Second ),
363
+ )
364
+
365
+ if err != nil {
366
+ log .Println (err .Error ())
367
+ return nil , nil , nil , nil , err
368
+ }
369
+
370
+ return octopusContainer , octoClient , sqlServer , network , nil
371
+ }
372
+
373
+ // Clean up the container after the test is complete
374
+ func (o * OctopusContainerTest ) CleanUp (ctx context.Context , octoContainer * OctopusContainer , sqlServer * MysqlContainer , network testcontainers.Network ) error {
375
+ // Stop the containers
376
+ stopTime := 1 * time .Minute
377
+ if octoStopErr := octoContainer .Stop (ctx , & stopTime ); octoStopErr != nil {
378
+ log .Println ("Failed to stop the Octopus container:" , octoStopErr )
379
+ }
380
+
381
+ if sqlStopErr := sqlServer .Container .Stop (ctx , & stopTime ); sqlStopErr != nil {
382
+ log .Println ("Failed to stop the SQL Server container:" , sqlStopErr )
383
+ }
384
+
385
+ // Terminate the containers
386
+ if octoTerminateErr := octoContainer .Terminate (ctx ); octoTerminateErr != nil {
387
+ log .Printf ("Failed to terminate the Octopus container: %v" , octoTerminateErr )
388
+ }
389
+
390
+ if sqlTerminateErr := sqlServer .Container .Terminate (ctx ); sqlTerminateErr != nil {
391
+ log .Printf ("Failed to terminate the SQL Server container: %v" , sqlTerminateErr )
392
+ }
393
+
394
+ if networkErr := network .Remove (ctx ); networkErr != nil {
395
+ log .Printf ("Failed to remove network: %v" , networkErr )
396
+ }
397
+
398
+ return nil
399
+ }
400
+
286
401
// ArrangeTest is wrapper that initialises Octopus, runs a test, and cleans up the containers
287
402
func (o * OctopusContainerTest ) ArrangeTest (t * testing.T , testFunc func (t * testing.T , container * OctopusContainer , client * client.Client ) error ) {
288
403
err := retry .Do (
0 commit comments