4
4
package integration
5
5
6
6
import (
7
+ "bytes"
7
8
"context"
9
+ "encoding/json"
8
10
"fmt"
9
11
"io"
10
12
"net/http"
11
13
"os"
12
14
"os/exec"
13
15
"path/filepath"
16
+ "strings"
14
17
"testing"
15
18
"time"
16
19
@@ -41,6 +44,7 @@ type E2EStorageIntegration struct {
41
44
42
45
SkipStorageCleaner bool
43
46
ConfigFile string
47
+ BinaryName string
44
48
HealthCheckEndpoint string
45
49
}
46
50
@@ -49,32 +53,34 @@ type E2EStorageIntegration struct {
49
53
// This function should be called before any of the tests start.
50
54
func (s * E2EStorageIntegration ) e2eInitialize (t * testing.T , storage string ) {
51
55
logger := zaptest .NewLogger (t , zaptest .WrapOptions (zap .AddCaller ()))
56
+ if s .BinaryName == "" {
57
+ s .BinaryName = "jaeger-v2"
58
+ }
52
59
configFile := s .ConfigFile
53
60
if ! s .SkipStorageCleaner {
54
61
configFile = createStorageCleanerConfig (t , s .ConfigFile , storage )
55
62
}
56
-
57
63
configFile , err := filepath .Abs (configFile )
58
64
require .NoError (t , err , "Failed to get absolute path of the config file" )
59
65
require .FileExists (t , configFile , "Config file does not exist at the resolved path" )
60
66
61
- t .Logf ("Starting Jaeger-v2 in the background with config file %s" , configFile )
67
+ t .Logf ("Starting %s in the background with config file %s" , s . BinaryName , configFile )
62
68
63
69
outFile , err := os .OpenFile (
64
70
filepath .Join (t .TempDir (), "jaeger_output_logs.txt" ),
65
71
os .O_CREATE | os .O_WRONLY ,
66
72
os .ModePerm ,
67
73
)
68
74
require .NoError (t , err )
69
- t .Logf ("Writing the Jaeger-v2 output logs into %s" , outFile .Name ())
75
+ t .Logf ("Writing the %s output logs into %s" , s . BinaryName , outFile .Name ())
70
76
71
77
errFile , err := os .OpenFile (
72
78
filepath .Join (t .TempDir (), "jaeger_error_logs.txt" ),
73
79
os .O_CREATE | os .O_WRONLY ,
74
80
os .ModePerm ,
75
81
)
76
82
require .NoError (t , err )
77
- t .Logf ("Writing the Jaeger-v2 error logs into %s" , errFile .Name ())
83
+ t .Logf ("Writing the %s error logs into %s" , s . BinaryName , errFile .Name ())
78
84
79
85
cmd := exec.Cmd {
80
86
Path : "./cmd/jaeger/jaeger" ,
@@ -88,57 +94,38 @@ func (s *E2EStorageIntegration) e2eInitialize(t *testing.T, storage string) {
88
94
}
89
95
t .Logf ("Running command: %v" , cmd .Args )
90
96
require .NoError (t , cmd .Start ())
91
-
92
- // Wait for the binary to start and become ready to serve requests.
93
- healthCheckEndpoint := s .HealthCheckEndpoint
94
- if healthCheckEndpoint == "" {
95
- healthCheckEndpoint = fmt .Sprintf ("http://localhost:%d/" , ports .QueryHTTP )
96
- }
97
- require .Eventually (t , func () bool {
98
- t .Logf ("Checking if Jaeger-v2 is available on %s" , healthCheckEndpoint )
99
- ctx , cancel := context .WithTimeout (context .Background (), 3 * time .Second )
100
- defer cancel ()
101
- req , err := http .NewRequestWithContext (ctx , http .MethodGet , healthCheckEndpoint , nil )
102
- if err != nil {
103
- t .Logf ("HTTP request creation failed: %v" , err )
104
- return false
105
- }
106
- resp , err := http .DefaultClient .Do (req )
107
- if err != nil {
108
- t .Logf ("HTTP request failed: %v" , err )
109
- return false
110
- }
111
- defer resp .Body .Close ()
112
- return resp .StatusCode == http .StatusOK
113
- }, 60 * time .Second , 3 * time .Second , "Jaeger-v2 did not start" )
114
- t .Log ("Jaeger-v2 is ready" )
115
97
t .Cleanup (func () {
116
98
if err := cmd .Process .Kill (); err != nil {
117
- t .Errorf ("Failed to kill Jaeger-v2 process: %v" , err )
99
+ t .Errorf ("Failed to kill %s process: %v" , s . BinaryName , err )
118
100
}
119
101
if t .Failed () {
120
102
// A Github Actions special annotation to create a foldable section
121
103
// in the Github runner output.
122
104
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines
123
- fmt .Println ("::group::🚧 🚧 🚧 Jaeger-v2 binary logs" )
105
+ fmt .Printf ("::group::🚧 🚧 🚧 %s binary logs\n " , s . BinaryName )
124
106
outLogs , err := os .ReadFile (outFile .Name ())
125
107
if err != nil {
126
108
t .Errorf ("Failed to read output logs: %v" , err )
127
109
} else {
128
- fmt .Printf ("🚧 🚧 🚧 Jaeger-v2 output logs:\n %s" , outLogs )
110
+ fmt .Printf ("🚧 🚧 🚧 %s output logs:\n %s" , s . BinaryName , outLogs )
129
111
}
130
112
131
113
errLogs , err := os .ReadFile (errFile .Name ())
132
114
if err != nil {
133
115
t .Errorf ("Failed to read error logs: %v" , err )
134
116
} else {
135
- fmt .Printf ("🚧 🚧 🚧 Jaeger-v2 error logs:\n %s" , errLogs )
117
+ fmt .Printf ("🚧 🚧 🚧 %s error logs:\n %s" , s . BinaryName , errLogs )
136
118
}
137
119
// End of Github Actions foldable section annotation.
138
120
fmt .Println ("::endgroup::" )
139
121
}
140
122
})
141
123
124
+ // Wait for the binary to start and become ready to serve requests.
125
+ require .Eventually (t , func () bool { return s .doHealthCheck (t ) },
126
+ 60 * time .Second , 3 * time .Second , "%s did not start" , s .BinaryName )
127
+ t .Logf ("%s is ready" , s .BinaryName )
128
+
142
129
s .SpanWriter , err = createSpanWriter (logger , otlpPort )
143
130
require .NoError (t , err )
144
131
s .SpanReader , err = createSpanReader (logger , ports .QueryGRPC )
@@ -150,6 +137,56 @@ func (s *E2EStorageIntegration) e2eInitialize(t *testing.T, storage string) {
150
137
})
151
138
}
152
139
140
+ func (s * E2EStorageIntegration ) doHealthCheck (t * testing.T ) bool {
141
+ healthCheckEndpoint := s .HealthCheckEndpoint
142
+ if healthCheckEndpoint == "" {
143
+ healthCheckEndpoint = "http://localhost:13133/status"
144
+ }
145
+ t .Logf ("Checking if %s is available on %s" , s .BinaryName , healthCheckEndpoint )
146
+ ctx , cancel := context .WithTimeout (context .Background (), 3 * time .Second )
147
+ defer cancel ()
148
+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , healthCheckEndpoint , nil )
149
+ if err != nil {
150
+ t .Logf ("HTTP request creation failed: %v" , err )
151
+ return false
152
+ }
153
+ resp , err := http .DefaultClient .Do (req )
154
+ if err != nil {
155
+ t .Logf ("HTTP request failed: %v" , err )
156
+ return false
157
+ }
158
+ defer resp .Body .Close ()
159
+ body , err := io .ReadAll (resp .Body )
160
+ if err != nil {
161
+ t .Logf ("Failed to read HTTP response body: %v" , err )
162
+ return false
163
+ }
164
+ if resp .StatusCode != http .StatusOK {
165
+ t .Logf ("HTTP response not OK: %v" , string (body ))
166
+ return false
167
+ }
168
+ // for backwards compatibility with other healthchecks
169
+ if ! strings .HasSuffix (healthCheckEndpoint , "/status" ) {
170
+ t .Logf ("OK HTTP from endpoint that is not healthcheckv2" )
171
+ return true
172
+ }
173
+
174
+ var healthResponse struct {
175
+ Status string `json:"status"`
176
+ }
177
+ if err := json .NewDecoder (bytes .NewReader (body )).Decode (& healthResponse ); err != nil {
178
+ t .Logf ("Failed to decode JSON response '%s': %v" , string (body ), err )
179
+ return false
180
+ }
181
+
182
+ // Check if the status field in the JSON is "StatusOK"
183
+ if healthResponse .Status != "StatusOK" {
184
+ t .Logf ("Received non-K status %s: %s" , healthResponse .Status , string (body ))
185
+ return false
186
+ }
187
+ return true
188
+ }
189
+
153
190
// e2eCleanUp closes the SpanReader and SpanWriter gRPC connection.
154
191
// This function should be called after all the tests are finished.
155
192
func (s * E2EStorageIntegration ) e2eCleanUp (t * testing.T ) {
@@ -205,6 +242,7 @@ func createStorageCleanerConfig(t *testing.T, configFile string, storage string)
205
242
err = os .WriteFile (tempFile , newData , 0o600 )
206
243
require .NoError (t , err )
207
244
245
+ t .Logf ("Transformed configuration file %s to %s" , configFile , tempFile )
208
246
return tempFile
209
247
}
210
248
0 commit comments