Skip to content

Commit 7c780b1

Browse files
committed
Review: Address comments
* Add test for failing to get pod-list from k8s * Replace deprecated NewSimpleClientset() with NewClientset()
1 parent b4dbe43 commit 7c780b1

File tree

6 files changed

+811
-10
lines changed

6 files changed

+811
-10
lines changed

pkg/data_collector/data_collector_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func TestWrapUp_CreatesTarball(t *testing.T) {
6666

6767
func TestRealPodExecutor_ReturnsOutput(t *testing.T) {
6868
dc := &DataCollector{
69-
K8sCoreClientSet: fake.NewSimpleClientset(),
69+
K8sCoreClientSet: fake.NewClientset(),
7070
K8sRestConfig: &rest.Config{},
7171
}
7272
// Replace RealPodExecutor with a mock for testing
@@ -94,7 +94,7 @@ func TestRealQueryCRD_ReturnsErrorOnInvalidConfig(t *testing.T) {
9494
}
9595

9696
func TestAllNamespacesExist_AllExist(t *testing.T) {
97-
client := fake.NewSimpleClientset(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}})
97+
client := fake.NewClientset(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}})
9898
dc := &DataCollector{
9999
Namespaces: []string{"default"},
100100
K8sCoreClientSet: client,
@@ -106,7 +106,7 @@ func TestAllNamespacesExist_AllExist(t *testing.T) {
106106
}
107107

108108
func TestAllNamespacesExist_NotExist(t *testing.T) {
109-
client := fake.NewSimpleClientset()
109+
client := fake.NewClientset()
110110
dc := &DataCollector{
111111
Namespaces: []string{"missing"},
112112
K8sCoreClientSet: client,

pkg/jobs/common_job_list_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func TestCommonJobList_PodListError(t *testing.T) {
9696
defer ctrl.Finish()
9797

9898
// Create mock clients
99-
mockClient := fake.NewSimpleClientset()
99+
mockClient := fake.NewClientset()
100100

101101
// Add a reactor that returns an error for pod list operations
102102
mockClient.PrependReactor("list", "pods", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {

pkg/jobs/ngf_job_list_test.go

Lines changed: 208 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
package jobs
22

33
import (
4+
"bytes"
45
"context"
6+
"fmt"
57
"io"
68
"log"
79
"strings"
810
"testing"
911

12+
"github.com/nginxinc/nginx-k8s-supportpkg/pkg/data_collector"
1013
"github.com/nginxinc/nginx-k8s-supportpkg/pkg/mock"
14+
"github.com/stretchr/testify/assert"
1115
corev1 "k8s.io/api/core/v1"
1216
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17+
"k8s.io/apimachinery/pkg/runtime"
1318
"k8s.io/client-go/kubernetes/fake"
19+
k8stesting "k8s.io/client-go/testing"
1420
)
1521

1622
func TestNGFJobList(t *testing.T) {
@@ -38,7 +44,7 @@ func TestNGFJobList(t *testing.T) {
3844
}
3945

4046
func TestNGFJobExecNginxGatewayVersion(t *testing.T) {
41-
client := fake.NewSimpleClientset(&corev1.Pod{
47+
client := fake.NewClientset(&corev1.Pod{
4248
ObjectMeta: metav1.ObjectMeta{
4349
Name: "nginx-gateway-test-pod",
4450
Namespace: "default",
@@ -92,7 +98,7 @@ func TestNGFJobExecNginxGatewayVersion(t *testing.T) {
9298
}
9399

94100
func TestNGFJobExecNginxT(t *testing.T) {
95-
client := fake.NewSimpleClientset(&corev1.Pod{
101+
client := fake.NewClientset(&corev1.Pod{
96102
ObjectMeta: metav1.ObjectMeta{
97103
Name: "nginx-gateway-test-pod",
98104
Namespace: "default",
@@ -146,3 +152,203 @@ func TestNGFJobExecNginxT(t *testing.T) {
146152
t.Error("expected nginx-t.txt file to be created")
147153
}
148154
}
155+
156+
func TestNGFJobList_ExecNginxGatewayVersion_PodListError(t *testing.T) {
157+
tmpDir := t.TempDir()
158+
var logOutput bytes.Buffer
159+
160+
// Create a fake client that will return an error for pod listing
161+
client := fake.NewClientset()
162+
client.PrependReactor("list", "pods", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
163+
return true, nil, fmt.Errorf("failed to retrieve pod list")
164+
})
165+
166+
dc := &data_collector.DataCollector{
167+
BaseDir: tmpDir,
168+
Namespaces: []string{"default", "nginx-gateway"},
169+
Logger: log.New(&logOutput, "", 0),
170+
K8sCoreClientSet: client,
171+
PodExecutor: func(namespace, podName, containerName string, command []string, ctx context.Context) ([]byte, error) {
172+
return []byte("mock output"), nil
173+
},
174+
}
175+
176+
// Get the exec-nginx-gateway-version job
177+
jobs := NGFJobList()
178+
var execJob Job
179+
for _, job := range jobs {
180+
if job.Name == "exec-nginx-gateway-version" {
181+
execJob = job
182+
break
183+
}
184+
}
185+
186+
// Execute the job
187+
ctx := context.Background()
188+
ch := make(chan JobResult, 1)
189+
execJob.Execute(dc, ctx, ch)
190+
191+
result := <-ch
192+
logContent := logOutput.String()
193+
194+
// Verify the error was logged for each namespace
195+
assert.Contains(t, logContent, "Could not retrieve pod list for namespace default: failed to retrieve pod list")
196+
assert.Contains(t, logContent, "Could not retrieve pod list for namespace nginx-gateway: failed to retrieve pod list")
197+
198+
// Verify no files were created since pod listing failed
199+
assert.Empty(t, result.Files, "No files should be created when pod list fails")
200+
assert.Nil(t, result.Error, "Job should not fail, just log the error")
201+
}
202+
203+
func TestNGFJobList_ExecNginxT_PodListError(t *testing.T) {
204+
tmpDir := t.TempDir()
205+
var logOutput bytes.Buffer
206+
207+
// Create a fake client that will return an error for pod listing
208+
client := fake.NewClientset()
209+
client.PrependReactor("list", "pods", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
210+
return true, nil, fmt.Errorf("pod list API error")
211+
})
212+
213+
dc := &data_collector.DataCollector{
214+
BaseDir: tmpDir,
215+
Namespaces: []string{"test-namespace"},
216+
Logger: log.New(&logOutput, "", 0),
217+
K8sCoreClientSet: client,
218+
PodExecutor: func(namespace, podName, containerName string, command []string, ctx context.Context) ([]byte, error) {
219+
return []byte("mock nginx config"), nil
220+
},
221+
}
222+
223+
// Get the exec-nginx-t job
224+
jobs := NGFJobList()
225+
var execJob Job
226+
for _, job := range jobs {
227+
if job.Name == "exec-nginx-t" {
228+
execJob = job
229+
break
230+
}
231+
}
232+
233+
// Execute the job
234+
ctx := context.Background()
235+
ch := make(chan JobResult, 1)
236+
execJob.Execute(dc, ctx, ch)
237+
238+
result := <-ch
239+
logContent := logOutput.String()
240+
241+
// Verify the error was logged
242+
assert.Contains(t, logContent, "Could not retrieve pod list for namespace test-namespace: pod list API error")
243+
assert.Empty(t, result.Files, "No files should be created when pod list fails")
244+
assert.Nil(t, result.Error, "Job should not fail, just log the error")
245+
}
246+
247+
func TestNGFJobList_MultipleNamespaces_PodListErrors(t *testing.T) {
248+
tmpDir := t.TempDir()
249+
var logOutput bytes.Buffer
250+
251+
// Create a fake client that returns different errors for different namespaces
252+
client := fake.NewClientset()
253+
client.PrependReactor("list", "pods", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
254+
listAction := action.(k8stesting.ListAction)
255+
namespace := listAction.GetNamespace()
256+
257+
switch namespace {
258+
case "error-ns1":
259+
return true, nil, fmt.Errorf("network timeout")
260+
case "error-ns2":
261+
return true, nil, fmt.Errorf("permission denied")
262+
default:
263+
// Let other namespaces succeed
264+
return false, nil, nil
265+
}
266+
})
267+
268+
dc := &data_collector.DataCollector{
269+
BaseDir: tmpDir,
270+
Namespaces: []string{"error-ns1", "error-ns2", "success-ns"},
271+
Logger: log.New(&logOutput, "", 0),
272+
K8sCoreClientSet: client,
273+
PodExecutor: func(namespace, podName, containerName string, command []string, ctx context.Context) ([]byte, error) {
274+
return []byte("mock output"), nil
275+
},
276+
}
277+
278+
// Test both jobs that have the same error handling pattern
279+
jobs := NGFJobList()
280+
281+
for _, jobName := range []string{"exec-nginx-gateway-version", "exec-nginx-t"} {
282+
t.Run(jobName, func(t *testing.T) {
283+
var targetJob Job
284+
for _, job := range jobs {
285+
if job.Name == jobName {
286+
targetJob = job
287+
break
288+
}
289+
}
290+
291+
// Clear log output for this subtest
292+
logOutput.Reset()
293+
294+
ctx := context.Background()
295+
ch := make(chan JobResult, 1)
296+
targetJob.Execute(dc, ctx, ch)
297+
298+
result := <-ch
299+
logContent := logOutput.String()
300+
301+
// Verify errors are logged for the failing namespaces
302+
assert.Contains(t, logContent, "Could not retrieve pod list for namespace error-ns1: network timeout")
303+
assert.Contains(t, logContent, "Could not retrieve pod list for namespace error-ns2: permission denied")
304+
305+
// success-ns should not have error logs
306+
assert.NotContains(t, logContent, "Could not retrieve pod list for namespace success-ns")
307+
308+
// No files should be created since no nginx-gateway pods exist in success-ns
309+
assert.Empty(t, result.Files)
310+
assert.Nil(t, result.Error)
311+
})
312+
}
313+
}
314+
315+
func TestNGFJobList_PodListError_LogFormat(t *testing.T) {
316+
tmpDir := t.TempDir()
317+
var logOutput bytes.Buffer
318+
319+
client := fake.NewClientset()
320+
client.PrependReactor("list", "pods", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
321+
return true, nil, fmt.Errorf("specific error message for testing")
322+
})
323+
324+
dc := &data_collector.DataCollector{
325+
BaseDir: tmpDir,
326+
Namespaces: []string{"test-ns"},
327+
Logger: log.New(&logOutput, "", 0),
328+
K8sCoreClientSet: client,
329+
PodExecutor: func(namespace, podName, containerName string, command []string, ctx context.Context) ([]byte, error) {
330+
return []byte("output"), nil
331+
},
332+
}
333+
334+
jobs := NGFJobList()
335+
execJob := jobs[0] // exec-nginx-gateway-version
336+
337+
ctx := context.Background()
338+
ch := make(chan JobResult, 1)
339+
execJob.Execute(dc, ctx, ch)
340+
341+
<-ch
342+
logContent := logOutput.String()
343+
344+
// Verify the exact log format
345+
expectedLogMessage := "\tCould not retrieve pod list for namespace test-ns: specific error message for testing"
346+
assert.Contains(t, logContent, expectedLogMessage)
347+
348+
// Verify it starts with tab character for indentation
349+
assert.Contains(t, logContent, "\tCould not retrieve pod list")
350+
351+
// Verify it contains the namespace and error
352+
assert.Contains(t, logContent, "test-ns")
353+
assert.Contains(t, logContent, "specific error message for testing")
354+
}

0 commit comments

Comments
 (0)