@@ -11,6 +11,7 @@ import (
11
11
"context"
12
12
"encoding/json"
13
13
"fmt"
14
+ "io"
14
15
"os"
15
16
"os/exec"
16
17
"path/filepath"
@@ -91,27 +92,60 @@ func TestComponentBuildHashInDiagnostics(t *testing.T) {
91
92
"failed to install start agent [output: %s]" , string (output ))
92
93
93
94
stateBuff := bytes.Buffer {}
95
+ var status atesting.AgentStatusOutput
94
96
allHealthy := func () bool {
95
97
stateBuff .Reset ()
96
98
97
- status , err : = f .ExecStatus (ctx )
99
+ status , err = f .ExecStatus (ctx )
98
100
if err != nil {
99
101
stateBuff .WriteString (fmt .Sprintf ("failed to get agent status: %v" ,
100
102
err ))
101
103
return false
102
104
}
103
105
106
+ if client .State (status .State ) != client .Healthy {
107
+ stateBuff .WriteString (fmt .Sprintf (
108
+ "agent isn't healthy: %s-%s" ,
109
+ client .State (status .State ), status .Message ))
110
+ return false
111
+ }
112
+
113
+ if len (status .Components ) == 0 {
114
+ stateBuff .WriteString (fmt .Sprintf (
115
+ "healthy but without components: agent status: %s-%s" ,
116
+ client .State (status .State ), status .Message ))
117
+ return false
118
+ }
119
+
120
+ // the agent might be healthy but waiting its first configuration,
121
+ // in that case, there would be no components yet. Therefore, ensure
122
+ // the agent received the policy with components before proceeding with
123
+ // the test.
104
124
for _ , c := range status .Components {
125
+ bs , err := json .MarshalIndent (status , "" , " " )
126
+ if err != nil {
127
+ stateBuff .WriteString (fmt .Sprintf (
128
+ "%s not healthy, could not marshal status outptu: %v" ,
129
+ c .Name , err ))
130
+ return false
131
+ }
132
+
105
133
state := client .State (c .State )
106
134
if state != client .Healthy {
107
- bs , err := json .MarshalIndent (status , "" , " " )
108
- if err != nil {
109
- stateBuff .WriteString (fmt .Sprintf ("%s not health, could not marshal status outptu: %v" ,
110
- c .Name , err ))
111
- return false
112
- }
113
-
114
- stateBuff .WriteString (fmt .Sprintf ("%s not health, agent status output: %s" ,
135
+ stateBuff .WriteString (fmt .Sprintf (
136
+ "%s not health, agent status output: %s" ,
137
+ c .Name , bs ))
138
+ return false
139
+ }
140
+
141
+ // there is a rare a race condition unlike to happen on a
142
+ // production scenario where the component is healthy but the
143
+ // version info delays to update. As the Status command and the
144
+ // diagnostics fetch this information in the same way, it guarantees
145
+ // the version info is up-to-date before proceeding with the test.
146
+ if c .VersionInfo .Meta .Commit == "" {
147
+ stateBuff .WriteString (fmt .Sprintf (
148
+ "%s health, but no versionInfo. agent status output: %s" ,
115
149
c .Name , bs ))
116
150
return false
117
151
}
@@ -123,6 +157,13 @@ func TestComponentBuildHashInDiagnostics(t *testing.T) {
123
157
allHealthy ,
124
158
5 * time .Minute , 10 * time .Second ,
125
159
"agent never became healthy. Last status: %v" , & stateBuff )
160
+ defer func () {
161
+ if ! t .Failed () {
162
+ return
163
+ }
164
+
165
+ t .Logf ("test failed: last status output: %#v" , status )
166
+ }()
126
167
127
168
agentbeat := "agentbeat"
128
169
if runtime .GOOS == "windows" {
@@ -159,6 +200,28 @@ func TestComponentBuildHashInDiagnostics(t *testing.T) {
159
200
160
201
diag := t .TempDir ()
161
202
extractZipArchive (t , diagZip , diag )
203
+ // if the test fails, the diagnostics used is useful for debugging.
204
+ defer func () {
205
+ if ! t .Failed () {
206
+ return
207
+ }
208
+
209
+ t .Logf ("the test failed: trying to save the diagnostics used on the test" )
210
+ diagDir , err := f .DiagDir ()
211
+ if err != nil {
212
+ t .Logf ("could not get diagnostics directory to save the diagnostics used on the test" )
213
+ return
214
+ }
215
+
216
+ err = os .Rename (diagZip , filepath .Join (diagDir ,
217
+ fmt .Sprintf ("TestComponentBuildHashInDiagnostics-used-diag-%d.zip" ,
218
+ time .Now ().Unix ())))
219
+ if err != nil {
220
+ t .Logf ("could not move diagnostics used in the test to %s: %v" ,
221
+ diagDir , err )
222
+ return
223
+ }
224
+ }()
162
225
163
226
stateFilePath := filepath .Join (diag , "state.yaml" )
164
227
stateYAML , err := os .Open (stateFilePath )
@@ -192,6 +255,19 @@ func TestComponentBuildHashInDiagnostics(t *testing.T) {
192
255
assert .Equalf (t , wantBuildHash , c .State .VersionInfo .Meta .Commit ,
193
256
"component %s: VersionInfo.Meta.Commit mismatch" , c .ID )
194
257
}
258
+
259
+ if t .Failed () {
260
+ _ , seek := stateYAML .Seek (0 , 0 )
261
+ if seek != nil {
262
+ t .Logf ("could not reset state.yaml offset to print it" )
263
+ return
264
+ }
265
+ data , err := io .ReadAll (stateYAML )
266
+ if err != nil {
267
+ t .Logf ("could not read state.yaml: %v" , err )
268
+ }
269
+ t .Logf ("test failed: state.yaml contents: %q" , string (data ))
270
+ }
195
271
}
196
272
197
273
func testVersionWithRunningAgent (runCtx context.Context , f * atesting.Fixture ) func (* testing.T ) {
0 commit comments