@@ -16,6 +16,8 @@ package framework
16
16
17
17
import (
18
18
"fmt"
19
+ "io"
20
+ "os"
19
21
"os/exec"
20
22
"path/filepath"
21
23
"strings"
@@ -59,6 +61,8 @@ type Framework struct {
59
61
// we install a Cleanup action before each test and clear it after. If we
60
62
// should abort, the AfterSuite hook should run all Cleanup actions.
61
63
cleanupHandle CleanupActionHandle
64
+
65
+ werckerReportArtifactsDir string
62
66
}
63
67
64
68
// NewDefaultFramework constructs a new e2e test Framework with default options.
@@ -70,8 +74,9 @@ func NewDefaultFramework(baseName string) *Framework {
70
74
// NewFramework constructs a new e2e test Framework.
71
75
func NewFramework (baseName string , client clientset.Interface ) * Framework {
72
76
f := & Framework {
73
- BaseName : baseName ,
74
- ClientSet : client ,
77
+ BaseName : baseName ,
78
+ ClientSet : client ,
79
+ werckerReportArtifactsDir : os .Getenv ("WERCKER_REPORT_ARTIFACTS_DIR" ),
75
80
}
76
81
77
82
BeforeEach (f .BeforeEach )
@@ -248,6 +253,10 @@ func (f *Framework) BeforeEach() {
248
253
func (f * Framework ) AfterEach () {
249
254
RemoveCleanupAction (f .cleanupHandle )
250
255
256
+ if err := f .outputLogs (); err != nil {
257
+ Logf ("Failed to output container logs: %v" , err )
258
+ }
259
+
251
260
nsDeletionErrors := map [string ]error {}
252
261
253
262
// Whether to delete namespace is determined by 3 factors: delete-namespace flag, delete-namespace-on-failure flag and the test result
@@ -272,3 +281,82 @@ func (f *Framework) AfterEach() {
272
281
}
273
282
f .OperatorInstalled = false
274
283
}
284
+
285
+ func (f * Framework ) outputLogs () error {
286
+ pods , err := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).List (metav1.ListOptions {})
287
+ if err != nil {
288
+ return errors .Wrap (err , "listing test Pods" )
289
+ }
290
+
291
+ var opPod v1.Pod
292
+ var agPods []v1.Pod
293
+ for _ , pod := range pods .Items {
294
+ if strings .Contains (pod .Spec .Containers [0 ].Image , "mysql-operator" ) {
295
+ opPod = pod
296
+ continue
297
+ }
298
+ if strings .Contains (pod .Spec .Containers [0 ].Image , "mysql-agent" ) || strings .Contains (pod .Spec .Containers [0 ].Image , "mysql-server" ) {
299
+ agPods = append (agPods , pod )
300
+ }
301
+ }
302
+
303
+ // Operator Logs
304
+ if opPod .Name != "" {
305
+ if err := f .printContainerLogs (opPod .GetName (), & v1.PodLogOptions {}); err != nil {
306
+ return errors .Wrapf (err , "exporting mysql operator container logs for %s" , opPod .GetName ())
307
+ }
308
+ } else {
309
+ Logf ("MySQL Operator Pod could not be found. Logs have not been exported." )
310
+ }
311
+
312
+ for _ , agPod := range agPods {
313
+ // Server Logs
314
+ if err := f .printContainerLogs (agPod .GetName (), & v1.PodLogOptions {Container : "mysql" }); err != nil {
315
+ return errors .Wrapf (err , "exporting mysql server container logs for %s" , agPod .GetName ())
316
+ }
317
+ // Agent Logs
318
+ if err := f .printContainerLogs (agPod .GetName (), & v1.PodLogOptions {Container : "mysql-agent" }); err != nil {
319
+ return errors .Wrapf (err , "exporting mysql agent container logs for %s" , agPod .GetName ())
320
+ }
321
+ }
322
+
323
+ return nil
324
+ }
325
+
326
+ func (f * Framework ) printLogs (read io.ReadCloser , filepath string ) error {
327
+ defer read .Close ()
328
+ dst := os .Stdout
329
+ if f .werckerReportArtifactsDir != "" {
330
+ file , err := os .OpenFile (filepath , os .O_WRONLY | os .O_CREATE , 0666 )
331
+ if err != nil {
332
+ return errors .Wrapf (err , "opening log file %q" , filepath )
333
+ }
334
+ dst = file
335
+ defer dst .Close ()
336
+ }
337
+ _ , err := io .Copy (dst , read )
338
+ if err != nil {
339
+ var s string
340
+ if filepath != "" {
341
+ s = filepath
342
+ } else {
343
+ s = "stdout"
344
+ }
345
+ return errors .Wrapf (err , "writing logs to %q" , s )
346
+ }
347
+ return nil
348
+ }
349
+
350
+ func (f * Framework ) printContainerLogs (podName string , options * v1.PodLogOptions ) error {
351
+ podLogs := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).GetLogs (podName , options )
352
+ if podLogs != nil {
353
+ Logf ("Writing %s container logs to file for %s" , options .Container , podName )
354
+ read , err := podLogs .Stream ()
355
+ if err != nil {
356
+ return errors .Wrapf (err , "streaming request response for %s" , podName )
357
+ }
358
+ f .printLogs (read , fmt .Sprintf ("%s/%s%s" , f .werckerReportArtifactsDir , podName , ".log" ))
359
+ Logf ("Finished writing %s container logs for %s" , options .Container , podName )
360
+ }
361
+ return nil
362
+ }
0 commit comments