@@ -174,55 +174,47 @@ func (r *ContainerRunner) RunCmd(cmd *exec.Cmd) *Assertable {
174
174
// Assert runs the Assertable and
175
175
func (a Assertable ) Assert (t * testing.T , option ... Assertion ) {
176
176
slog .Helper ()
177
- var cmdResult CommandResult
178
-
179
177
var (
180
178
stdout bytes.Buffer
181
179
stderr bytes.Buffer
180
+ result CommandResult
182
181
)
183
182
184
183
a .cmd .Stdout = & stdout
185
184
a .cmd .Stderr = & stderr
186
185
187
186
start := time .Now ()
188
187
err := a .cmd .Run ()
189
- cmdResult .Duration = time .Since (start )
188
+ result .Duration = time .Since (start )
190
189
191
190
if exitErr , ok := err .(* exec.ExitError ); ok {
192
- cmdResult .ExitCode = exitErr .ExitCode ()
191
+ result .ExitCode = exitErr .ExitCode ()
193
192
} else if err != nil {
194
- cmdResult .ExitCode = - 1
193
+ // TODO: handle this case better
194
+ result .ExitCode = - 1
195
195
} else {
196
- cmdResult .ExitCode = 0
196
+ result .ExitCode = 0
197
197
}
198
198
199
- cmdResult .Stdout = stdout .Bytes ()
200
- cmdResult .Stderr = stderr .Bytes ()
199
+ result .Stdout = stdout .Bytes ()
200
+ result .Stderr = stderr .Bytes ()
201
201
202
202
slogtest .Info (t , "command output" ,
203
203
slog .F ("command" , a .cmd ),
204
- slog .F ("stdout" , string (cmdResult .Stdout )),
205
- slog .F ("stderr" , string (cmdResult .Stderr )),
206
- slog .F ("exit-code " , cmdResult .ExitCode ),
207
- slog .F ("duration" , cmdResult .Duration ),
204
+ slog .F ("stdout" , string (result .Stdout )),
205
+ slog .F ("stderr" , string (result .Stderr )),
206
+ slog .F ("exit_code " , result .ExitCode ),
207
+ slog .F ("duration" , result .Duration ),
208
208
)
209
209
210
- for _ , o := range option {
211
- o . Valid (t , & cmdResult )
210
+ for _ , assertion := range option {
211
+ assertion (t , & result )
212
212
}
213
213
}
214
214
215
215
// Assertion specifies an assertion on the given CommandResult.
216
- // Pass custom Assertion types to cover special cases.
217
- type Assertion interface {
218
- Valid (t * testing.T , r * CommandResult )
219
- }
220
-
221
- // Named is an optional extension of Assertion that provides a helpful label
222
- // to *testing.T
223
- type Named interface {
224
- Name () string
225
- }
216
+ // Pass custom Assertion functions to cover special cases.
217
+ type Assertion func (t * testing.T , r * CommandResult )
226
218
227
219
// CommandResult contains the aggregated result of a command execution
228
220
type CommandResult struct {
@@ -231,20 +223,6 @@ type CommandResult struct {
231
223
Duration time.Duration
232
224
}
233
225
234
- type simpleFuncAssert struct {
235
- valid func (t * testing.T , r * CommandResult )
236
- name string
237
- }
238
-
239
- func (s simpleFuncAssert ) Valid (t * testing.T , r * CommandResult ) {
240
- slog .Helper ()
241
- s .valid (t , r )
242
- }
243
-
244
- func (s simpleFuncAssert ) Name () string {
245
- return s .name
246
- }
247
-
248
226
// Success asserts that the command exited with an exit code of 0
249
227
func Success () Assertion {
250
228
slog .Helper ()
@@ -253,112 +231,75 @@ func Success() Assertion {
253
231
254
232
// Error asserts that the command exited with a nonzero exit code
255
233
func Error () Assertion {
256
- return simpleFuncAssert {
257
- valid : func (t * testing.T , r * CommandResult ) {
258
- slog .Helper ()
259
- assert .True (t , "exit code is nonzero" , r .ExitCode != 0 )
260
- },
261
- name : fmt .Sprintf ("error" ),
234
+ return func (t * testing.T , r * CommandResult ) {
235
+ slog .Helper ()
236
+ assert .True (t , "exit code is nonzero" , r .ExitCode != 0 )
262
237
}
263
238
}
264
239
265
240
// ExitCodeIs asserts that the command exited with the given code
266
241
func ExitCodeIs (code int ) Assertion {
267
- return simpleFuncAssert {
268
- valid : func (t * testing.T , r * CommandResult ) {
269
- slog .Helper ()
270
- assert .Equal (t , "exit code is as expected" , code , r .ExitCode )
271
- },
272
- name : fmt .Sprintf ("exitcode" ),
242
+ return func (t * testing.T , r * CommandResult ) {
243
+ slog .Helper ()
244
+ assert .Equal (t , "exit code is as expected" , code , r .ExitCode )
273
245
}
274
246
}
275
247
276
248
// StdoutEmpty asserts that the command did not write any data to Stdout
277
249
func StdoutEmpty () Assertion {
278
- return simpleFuncAssert {
279
- valid : func (t * testing.T , r * CommandResult ) {
280
- slog .Helper ()
281
- empty (t , "stdout" , r .Stdout )
282
- },
283
- name : fmt .Sprintf ("stdout-empty" ),
250
+ return func (t * testing.T , r * CommandResult ) {
251
+ slog .Helper ()
252
+ empty (t , "stdout" , r .Stdout )
284
253
}
285
254
}
286
255
287
256
// GetResult offers an escape hatch from tcli
288
257
// The pointer passed as "result" will be assigned to the command's *CommandResult
289
258
func GetResult (result * * CommandResult ) Assertion {
290
- return simpleFuncAssert {
291
- valid : func (t * testing.T , r * CommandResult ) {
292
- slog .Helper ()
293
- empty (t , "stdout" , r .Stdout )
294
- * result = r
295
- },
296
- name : "get-result" ,
259
+ return func (t * testing.T , r * CommandResult ) {
260
+ slog .Helper ()
261
+ * result = r
297
262
}
298
263
}
299
264
300
265
// StderrEmpty asserts that the command did not write any data to Stderr
301
266
func StderrEmpty () Assertion {
302
- return simpleFuncAssert {
303
- valid : func (t * testing.T , r * CommandResult ) {
304
- slog .Helper ()
305
- empty (t , "stderr" , r .Stderr )
306
- },
307
- name : fmt .Sprintf ("stderr-empty" ),
267
+ return func (t * testing.T , r * CommandResult ) {
268
+ slog .Helper ()
269
+ empty (t , "stderr" , r .Stderr )
308
270
}
309
271
}
310
272
311
273
// StdoutMatches asserts that Stdout contains a substring which matches the given regexp
312
274
func StdoutMatches (pattern string ) Assertion {
313
- return simpleFuncAssert {
314
- valid : func (t * testing.T , r * CommandResult ) {
315
- slog .Helper ()
316
- matches (t , "stdout" , pattern , r .Stdout )
317
- },
318
- name : fmt .Sprintf ("stdout-matches" ),
275
+ return func (t * testing.T , r * CommandResult ) {
276
+ slog .Helper ()
277
+ matches (t , "stdout" , pattern , r .Stdout )
319
278
}
320
279
}
321
280
322
281
// StderrMatches asserts that Stderr contains a substring which matches the given regexp
323
282
func StderrMatches (pattern string ) Assertion {
324
- return simpleFuncAssert {
325
- valid : func (t * testing.T , r * CommandResult ) {
326
- slog .Helper ()
327
- matches (t , "stderr" , pattern , r .Stderr )
328
- },
329
- name : fmt .Sprintf ("stderr-matches" ),
330
- }
331
- }
332
-
333
- // CombinedMatches asserts that either Stdout or Stderr a substring which matches the given regexp
334
- func CombinedMatches (pattern string ) Assertion {
335
- return simpleFuncAssert {
336
- valid : func (t * testing.T , r * CommandResult ) {
337
- slog .Helper ()
338
- StdoutMatches (pattern ).Valid (t , r )
339
- StderrMatches (pattern ).Valid (t , r )
340
- },
341
- name : fmt .Sprintf ("combined-matches" ),
283
+ return func (t * testing.T , r * CommandResult ) {
284
+ slog .Helper ()
285
+ matches (t , "stderr" , pattern , r .Stderr )
342
286
}
343
287
}
344
288
345
289
func matches (t * testing.T , name , pattern string , target []byte ) {
346
290
slog .Helper ()
291
+ fields := []slog.Field {
292
+ slog .F ("pattern" , pattern ),
293
+ slog .F ("target" , string (target )),
294
+ slog .F ("sink" , name ),
295
+ }
347
296
348
297
ok , err := regexp .Match (pattern , target )
349
298
if err != nil {
350
- slogtest .Fatal (t , "failed to attempt regexp match" , slog .Error (err ),
351
- slog .F ("pattern" , pattern ),
352
- slog .F ("target" , string (target )),
353
- slog .F ("sink" , name ),
354
- )
299
+ slogtest .Fatal (t , "failed to attempt regexp match" , append (fields , slog .Error (err ))... )
355
300
}
356
301
if ! ok {
357
- slogtest .Fatal (t , "expected to find pattern, no match found" ,
358
- slog .F ("pattern" , pattern ),
359
- slog .F ("target" , string (target )),
360
- slog .F ("sink" , name ),
361
- )
302
+ slogtest .Fatal (t , "expected to find pattern, no match found" , fields ... )
362
303
}
363
304
}
364
305
@@ -371,32 +312,26 @@ func empty(t *testing.T, name string, a []byte) {
371
312
372
313
// DurationLessThan asserts that the command completed in less than the given duration
373
314
func DurationLessThan (dur time.Duration ) Assertion {
374
- return simpleFuncAssert {
375
- valid : func (t * testing.T , r * CommandResult ) {
376
- slog .Helper ()
377
- if r .Duration > dur {
378
- slogtest .Fatal (t , "duration longer than expected" ,
379
- slog .F ("expected_less_than" , dur .String ),
380
- slog .F ("actual" , r .Duration .String ()),
381
- )
382
- }
383
- },
384
- name : fmt .Sprintf ("duration-lessthan" ),
315
+ return func (t * testing.T , r * CommandResult ) {
316
+ slog .Helper ()
317
+ if r .Duration > dur {
318
+ slogtest .Fatal (t , "duration longer than expected" ,
319
+ slog .F ("expected_less_than" , dur .String ),
320
+ slog .F ("actual" , r .Duration .String ()),
321
+ )
322
+ }
385
323
}
386
324
}
387
325
388
326
// DurationGreaterThan asserts that the command completed in greater than the given duration
389
327
func DurationGreaterThan (dur time.Duration ) Assertion {
390
- return simpleFuncAssert {
391
- valid : func (t * testing.T , r * CommandResult ) {
392
- slog .Helper ()
393
- if r .Duration < dur {
394
- slogtest .Fatal (t , "duration shorter than expected" ,
395
- slog .F ("expected_greater_than" , dur .String ),
396
- slog .F ("actual" , r .Duration .String ()),
397
- )
398
- }
399
- },
400
- name : fmt .Sprintf ("duration-greaterthan" ),
328
+ return func (t * testing.T , r * CommandResult ) {
329
+ slog .Helper ()
330
+ if r .Duration < dur {
331
+ slogtest .Fatal (t , "duration shorter than expected" ,
332
+ slog .F ("expected_greater_than" , dur .String ),
333
+ slog .F ("actual" , r .Duration .String ()),
334
+ )
335
+ }
401
336
}
402
337
}
0 commit comments