@@ -19,23 +19,51 @@ type RunContainer struct {
19
19
ctx context.Context
20
20
}
21
21
22
- func NewRunContainer (ctx context.Context , image , name string ) (* RunContainer , error ) {
23
- cmd := exec .CommandContext (ctx ,
24
- "docker" , "run" ,
25
- "--name" , name ,
22
+ type ContainerConfig struct {
23
+ Name string
24
+ Image string
25
+ Mounts map [string ]string
26
+ }
27
+
28
+ func mountArgs (m map [string ]string ) (args []string ) {
29
+ for src , dest := range m {
30
+ args = append (args , "--mount" , fmt .Sprintf ("source=%s,target=%s" , src , dest ))
31
+ }
32
+ return args
33
+ }
34
+
35
+ func preflightChecks () error {
36
+ _ , err := exec .LookPath ("docker" )
37
+ if err != nil {
38
+ return xerrors .Errorf (`"docker" not found in $PATH` )
39
+ }
40
+ return nil
41
+ }
42
+
43
+ func NewRunContainer (ctx context.Context , config * ContainerConfig ) (* RunContainer , error ) {
44
+ if err := preflightChecks (); err != nil {
45
+ return nil , err
46
+ }
47
+
48
+ args := []string {
49
+ "run" ,
50
+ "--name" , config .Name ,
26
51
"-it" , "-d" ,
27
- image ,
28
- )
52
+ }
53
+ args = append (args , mountArgs (config .Mounts )... )
54
+ args = append (args , config .Image )
55
+
56
+ cmd := exec .CommandContext (ctx , "docker" , args ... )
29
57
30
58
out , err := cmd .CombinedOutput ()
31
59
if err != nil {
32
60
return nil , xerrors .Errorf (
33
61
"failed to start testing container %q, (%s): %w" ,
34
- name , string (out ), err )
62
+ config . Name , string (out ), err )
35
63
}
36
64
37
65
return & RunContainer {
38
- name : name ,
66
+ name : config . Name ,
39
67
ctx : ctx ,
40
68
}, nil
41
69
}
@@ -57,36 +85,51 @@ func (r *RunContainer) Close() error {
57
85
}
58
86
59
87
type Assertable struct {
60
- cmd string
88
+ cmd * exec. Cmd
61
89
ctx context.Context
62
90
container * RunContainer
63
91
}
64
92
65
- func (r * RunContainer ) Run (ctx context.Context , cmd string ) * Assertable {
93
+ // Run executes the given command in the runtime container with reasonable defaults
94
+ func (r * RunContainer ) Run (ctx context.Context , command string ) * Assertable {
95
+ cmd := exec .CommandContext (ctx ,
96
+ "docker" , "exec" , "-i" , r .name ,
97
+ "sh" , "-c" , command ,
98
+ )
99
+
66
100
return & Assertable {
67
101
cmd : cmd ,
68
102
ctx : ctx ,
69
103
container : r ,
70
104
}
71
105
}
72
106
107
+ // RunCmd lifts the given *exec.Cmd into the runtime container
108
+ func (r * RunContainer ) RunCmd (cmd * exec.Cmd ) * Assertable {
109
+ path , _ := exec .LookPath ("docker" )
110
+ cmd .Path = path
111
+ command := strings .Join (cmd .Args , " " )
112
+ cmd .Args = append ([]string {"docker" , "exec" , "-i" , r .name , "sh" , "-c" , command })
113
+
114
+ return & Assertable {
115
+ cmd : cmd ,
116
+ container : r ,
117
+ }
118
+ }
119
+
73
120
func (a Assertable ) Assert (t * testing.T , option ... Assertion ) {
74
121
var cmdResult CommandResult
75
122
76
- cmd := exec .CommandContext (a .ctx ,
77
- "docker" , "exec" , a .container .name ,
78
- "sh" , "-c" , a .cmd ,
79
- )
80
123
var (
81
124
stdout bytes.Buffer
82
125
stderr bytes.Buffer
83
126
)
84
127
85
- cmd .Stdout = & stdout
86
- cmd .Stderr = & stderr
128
+ a . cmd .Stdout = & stdout
129
+ a . cmd .Stderr = & stderr
87
130
88
131
start := time .Now ()
89
- err := cmd .Run ()
132
+ err := a . cmd .Run ()
90
133
cmdResult .Duration = time .Since (start )
91
134
92
135
if exitErr , ok := err .(* exec.ExitError ); ok {
@@ -147,7 +190,7 @@ func ExitCodeIs(code int) Assertion {
147
190
return simpleFuncAssert {
148
191
valid : func (r CommandResult ) error {
149
192
if r .ExitCode != code {
150
- return xerrors .Errorf ("exit code of %s expected, got %v" , code , r .ExitCode )
193
+ return xerrors .Errorf ("exit code of %v expected, got %v" , code , r .ExitCode )
151
194
}
152
195
return nil
153
196
},
@@ -209,7 +252,10 @@ func matches(name, pattern string, target []byte) error {
209
252
return xerrors .Errorf ("failed to attempt regexp match: %w" , err )
210
253
}
211
254
if ! ok {
212
- return xerrors .Errorf ("expected to find pattern (%s) in %s, no match found" , pattern , name )
255
+ return xerrors .Errorf (
256
+ "expected to find pattern (%s) in %s, no match found in (%v)" ,
257
+ pattern , name , string (target ),
258
+ )
213
259
}
214
260
return nil
215
261
}
0 commit comments