Skip to content

Commit 788d171

Browse files
authored
add nil check to generateCollectorHealth to prevent nil pointer when starttime is not set (#2581)
1 parent 1b2662b commit 788d171

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

cmd/operator-opamp-bridge/agent/agent.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,14 @@ func (agent *Agent) generateCollectorHealth(selectorLabels map[string]string, na
163163
if item.Status.Phase != "Running" {
164164
healthy = false
165165
}
166+
var startTime int64
167+
if item.Status.StartTime != nil {
168+
startTime = item.Status.StartTime.UnixNano()
169+
} else {
170+
healthy = false
171+
}
166172
healthMap[key.String()] = &protobufs.ComponentHealth{
167-
StartTimeUnixNano: uint64(item.Status.StartTime.UnixNano()),
173+
StartTimeUnixNano: uint64(startTime),
168174
StatusTimeUnixNano: uint64(agent.clock.Now().UnixNano()),
169175
Status: string(item.Status.Phase),
170176
Healthy: healthy,

cmd/operator-opamp-bridge/agent/agent_test.go

+69-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@ var (
103103
},
104104
},
105105
}}
106+
mockPodListUnhealthy = &v1.PodList{
107+
TypeMeta: metav1.TypeMeta{
108+
Kind: "PodList",
109+
APIVersion: "v1",
110+
},
111+
Items: []v1.Pod{
112+
{
113+
ObjectMeta: metav1.ObjectMeta{
114+
Name: thirdCollectorName + "-1",
115+
Namespace: otherCollectorName,
116+
Labels: map[string]string{
117+
"app.kubernetes.io/managed-by": "opentelemetry-operator",
118+
"app.kubernetes.io/instance": fmt.Sprintf("%s.%s", otherCollectorName, thirdCollectorName),
119+
"app.kubernetes.io/part-of": "opentelemetry",
120+
"app.kubernetes.io/component": "opentelemetry-collector",
121+
},
122+
},
123+
Spec: v1.PodSpec{},
124+
Status: v1.PodStatus{
125+
StartTime: nil,
126+
Phase: v1.PodRunning,
127+
},
128+
},
129+
}}
106130
)
107131

108132
func getConfigHash(key, file string) string {
@@ -187,6 +211,7 @@ func TestAgent_getHealth(t *testing.T) {
187211
ctx context.Context
188212
// List of mappings from namespace/name to a config file, tests are run in order of list
189213
configs []map[string]string
214+
podList *v1.PodList
190215
}
191216
tests := []struct {
192217
name string
@@ -203,6 +228,7 @@ func TestAgent_getHealth(t *testing.T) {
203228
args: args{
204229
ctx: context.Background(),
205230
configs: nil,
231+
podList: mockPodList,
206232
},
207233
want: []*protobufs.ComponentHealth{
208234
{
@@ -227,6 +253,7 @@ func TestAgent_getHealth(t *testing.T) {
227253
testCollectorKey: collectorBasicFile,
228254
},
229255
},
256+
podList: mockPodList,
230257
},
231258
want: []*protobufs.ComponentHealth{
232259
{
@@ -259,6 +286,7 @@ func TestAgent_getHealth(t *testing.T) {
259286
otherCollectorKey: collectorUpdatedFile,
260287
},
261288
},
289+
podList: mockPodList,
262290
},
263291
want: []*protobufs.ComponentHealth{
264292
{
@@ -298,6 +326,7 @@ func TestAgent_getHealth(t *testing.T) {
298326
thirdCollectorKey: collectorBasicFile,
299327
},
300328
},
329+
podList: mockPodList,
301330
},
302331
want: []*protobufs.ComponentHealth{
303332
{
@@ -324,14 +353,53 @@ func TestAgent_getHealth(t *testing.T) {
324353
},
325354
},
326355
},
356+
{
357+
name: "with pod health, nil start time",
358+
fields: fields{
359+
configFile: agentTestFileName,
360+
},
361+
args: args{
362+
ctx: context.Background(),
363+
configs: []map[string]string{
364+
{
365+
thirdCollectorKey: collectorBasicFile,
366+
},
367+
},
368+
podList: mockPodListUnhealthy,
369+
},
370+
want: []*protobufs.ComponentHealth{
371+
{
372+
Healthy: true,
373+
StartTimeUnixNano: uint64(fakeClock.Now().UnixNano()),
374+
StatusTimeUnixNano: uint64(fakeClock.Now().UnixNano()),
375+
ComponentHealthMap: map[string]*protobufs.ComponentHealth{
376+
"other/third": {
377+
Healthy: false, // we're working with mocks so the status will never be reconciled.
378+
StartTimeUnixNano: collectorStartTime,
379+
LastError: "",
380+
Status: "",
381+
StatusTimeUnixNano: uint64(fakeClock.Now().UnixNano()),
382+
ComponentHealthMap: map[string]*protobufs.ComponentHealth{
383+
otherCollectorName + "/" + thirdCollectorName + "-1": {
384+
Healthy: false,
385+
Status: "Running",
386+
StatusTimeUnixNano: uint64(fakeClock.Now().UnixNano()),
387+
StartTimeUnixNano: uint64(0),
388+
},
389+
},
390+
},
391+
},
392+
},
393+
},
394+
},
327395
}
328396
for _, tt := range tests {
329397
t.Run(tt.name, func(t *testing.T) {
330398
mockClient := &mockOpampClient{}
331399
conf := config.NewConfig(logr.Discard())
332400
loadErr := config.LoadFromFile(conf, tt.fields.configFile)
333401
require.NoError(t, loadErr, "should be able to load config")
334-
applier := getFakeApplier(t, conf, mockPodList)
402+
applier := getFakeApplier(t, conf, tt.args.podList)
335403
agent := NewAgent(l, applier, conf, mockClient)
336404
agent.clock = fakeClock
337405
err := agent.Start()

0 commit comments

Comments
 (0)