summaryrefslogtreecommitdiff
path: root/vendor/github.com/onsi/ginkgo/internal/remote/forwarding_reporter.go
blob: 284bc62e5e893a49aa2970a0c3548d7365d07e4a (plain)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package remote

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"

	"github.com/onsi/ginkgo/internal/writer"
	"github.com/onsi/ginkgo/reporters"
	"github.com/onsi/ginkgo/reporters/stenographer"

	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/types"
)

//An interface to net/http's client to allow the injection of fakes under test
type Poster interface {
	Post(url string, bodyType string, body io.Reader) (resp *http.Response, err error)
}

/*
The ForwardingReporter is a Ginkgo reporter that forwards information to
a Ginkgo remote server.

When streaming parallel test output, this repoter is automatically installed by Ginkgo.

This is accomplished by passing in the GINKGO_REMOTE_REPORTING_SERVER environment variable to `go test`, the Ginkgo test runner
detects this environment variable (which should contain the host of the server) and automatically installs a ForwardingReporter
in place of Ginkgo's DefaultReporter.
*/

type ForwardingReporter struct {
	serverHost        string
	poster            Poster
	outputInterceptor OutputInterceptor
	debugMode         bool
	debugFile         *os.File
	nestedReporter    *reporters.DefaultReporter
}

func NewForwardingReporter(config config.DefaultReporterConfigType, serverHost string, poster Poster, outputInterceptor OutputInterceptor, ginkgoWriter *writer.Writer, debugFile string) *ForwardingReporter {
	reporter := &ForwardingReporter{
		serverHost:        serverHost,
		poster:            poster,
		outputInterceptor: outputInterceptor,
	}

	if debugFile != "" {
		var err error
		reporter.debugMode = true
		reporter.debugFile, err = os.Create(debugFile)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}

		if !config.Verbose {
			//if verbose is true then the GinkgoWriter emits to stdout.  Don't _also_ redirect GinkgoWriter output as that will result in duplication.
			ginkgoWriter.AndRedirectTo(reporter.debugFile)
		}
		outputInterceptor.StreamTo(reporter.debugFile) //This is not working

		stenographer := stenographer.New(false, true, reporter.debugFile)
		config.Succinct = false
		config.Verbose = true
		config.FullTrace = true
		reporter.nestedReporter = reporters.NewDefaultReporter(config, stenographer)
	}

	return reporter
}

func (reporter *ForwardingReporter) post(path string, data interface{}) {
	encoded, _ := json.Marshal(data)
	buffer := bytes.NewBuffer(encoded)
	reporter.poster.Post(reporter.serverHost+path, "application/json", buffer)
}

func (reporter *ForwardingReporter) SpecSuiteWillBegin(conf config.GinkgoConfigType, summary *types.SuiteSummary) {
	data := struct {
		Config  config.GinkgoConfigType `json:"config"`
		Summary *types.SuiteSummary     `json:"suite-summary"`
	}{
		conf,
		summary,
	}

	reporter.outputInterceptor.StartInterceptingOutput()
	if reporter.debugMode {
		reporter.nestedReporter.SpecSuiteWillBegin(conf, summary)
		reporter.debugFile.Sync()
	}
	reporter.post("/SpecSuiteWillBegin", data)
}

func (reporter *ForwardingReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
	output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput()
	reporter.outputInterceptor.StartInterceptingOutput()
	setupSummary.CapturedOutput = output
	if reporter.debugMode {
		reporter.nestedReporter.BeforeSuiteDidRun(setupSummary)
		reporter.debugFile.Sync()
	}
	reporter.post("/BeforeSuiteDidRun", setupSummary)
}

func (reporter *ForwardingReporter) SpecWillRun(specSummary *types.SpecSummary) {
	if reporter.debugMode {
		reporter.nestedReporter.SpecWillRun(specSummary)
		reporter.debugFile.Sync()
	}
	reporter.post("/SpecWillRun", specSummary)
}

func (reporter *ForwardingReporter) SpecDidComplete(specSummary *types.SpecSummary) {
	output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput()
	reporter.outputInterceptor.StartInterceptingOutput()
	specSummary.CapturedOutput = output
	if reporter.debugMode {
		reporter.nestedReporter.SpecDidComplete(specSummary)
		reporter.debugFile.Sync()
	}
	reporter.post("/SpecDidComplete", specSummary)
}

func (reporter *ForwardingReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
	output, _ := reporter.outputInterceptor.StopInterceptingAndReturnOutput()
	reporter.outputInterceptor.StartInterceptingOutput()
	setupSummary.CapturedOutput = output
	if reporter.debugMode {
		reporter.nestedReporter.AfterSuiteDidRun(setupSummary)
		reporter.debugFile.Sync()
	}
	reporter.post("/AfterSuiteDidRun", setupSummary)
}

func (reporter *ForwardingReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
	reporter.outputInterceptor.StopInterceptingAndReturnOutput()
	if reporter.debugMode {
		reporter.nestedReporter.SpecSuiteDidEnd(summary)
		reporter.debugFile.Sync()
	}
	reporter.post("/SpecSuiteDidEnd", summary)
}