-
Notifications
You must be signed in to change notification settings - Fork 0
/
container.go
131 lines (98 loc) 路 3 KB
/
container.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package testcontainers
import (
"context"
"fmt"
"sync"
"github.com/testcontainers/testcontainers-go"
)
// GenericContainerOption is option for starting a new generic container.
type GenericContainerOption interface {
applyOptions(o *genericContainerOptions)
}
type genericContainerOptionFunc func(o *genericContainerOptions)
func (f genericContainerOptionFunc) applyOptions(o *genericContainerOptions) {
f(o)
}
type genericContainerOptions struct {
request ContainerRequest
providerType testcontainers.ProviderType
callbacks []ContainerCallback
}
// StartGenericContainer starts a new generic container.
func StartGenericContainer(ctx context.Context, request ContainerRequest, opts ...GenericContainerOption) (Container, error) {
originalName := request.Name
o := genericContainerOptions{
request: request,
}
for _, opt := range opts {
opt.applyOptions(&o)
}
r := testcontainers.GenericContainerRequest{
ContainerRequest: o.request,
Started: true,
ProviderType: o.providerType,
}
o.request.Name = originalName
c, err := testcontainers.GenericContainer(ctx, r)
if err != nil {
return c, err
}
for _, f := range o.callbacks {
if err := f(ctx, c, o.request); err != nil {
return c, err
}
}
return c, nil
}
// StartGenericContainerRequest is request for starting a new generic container.
type StartGenericContainerRequest struct {
Request ContainerRequest
Options []GenericContainerOption
}
// StartGenericContainers starts multiple generic containers at once.
func StartGenericContainers(ctx context.Context, requests ...StartGenericContainerRequest) (containers []Container, _ error) {
var (
wg sync.WaitGroup
mu sync.Mutex
)
wg.Add(len(requests))
containers = make([]Container, 0, len(requests))
errs := make(errorCollection, 0, len(requests))
for _, r := range requests {
go func(r StartGenericContainerRequest) {
defer wg.Done()
c, sErr := StartGenericContainer(ctx, r.Request, r.Options...)
mu.Lock()
defer mu.Unlock()
if sErr != nil {
errs.Append(fmt.Errorf("could not start container %q: %w", r.Request.Name, sErr))
}
if c != nil {
containers = append(containers, c)
}
}(r)
}
wg.Wait()
return containers, errs.AsError()
}
// StopGenericContainers stops multiple containers at once.
func StopGenericContainers(ctx context.Context, containers ...Container) error {
var wg sync.WaitGroup
wg.Add(len(containers))
errs := make(errorCollection, 0, len(containers))
for _, c := range containers {
go func(c testcontainers.Container) {
defer wg.Done()
if err := c.Terminate(ctx); err != nil {
errs.Append(fmt.Errorf("could not stop container %q: %w", c.GetContainerID(), err))
}
}(c)
}
wg.Wait()
return errs.AsError()
}
// ContainerCallback is called after a container is successfully created and started.
type ContainerCallback func(ctx context.Context, c Container, r ContainerRequest) error
func (c ContainerCallback) applyOptions(o *genericContainerOptions) {
o.callbacks = append(o.callbacks, c)
}