Skip to content

Commit 7bb7833

Browse files
committed
feat: Create unit tests for NIC, NIM, NGF, and NGX
1 parent ee263e6 commit 7bb7833

10 files changed

+926
-98
lines changed

pkg/crds/crd_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"testing"
66
)
77

8-
func TestGetCRDList(t *testing.T) {
8+
func TestGetNICCRDList(t *testing.T) {
99
tests := []struct {
1010
name string
1111
want []Crd
@@ -74,8 +74,8 @@ func TestGetCRDList(t *testing.T) {
7474

7575
for _, tt := range tests {
7676
t.Run(tt.name, func(t *testing.T) {
77-
if got := GetCRDList(); !reflect.DeepEqual(got, tt.want) {
78-
t.Errorf("GetCRDList() = %v, want %v", got, tt.want)
77+
if got := GetNICCRDList(); !reflect.DeepEqual(got, tt.want) {
78+
t.Errorf("GetNICCRDList() = %v, want %v", got, tt.want)
7979
}
8080
})
8181
}

pkg/data_collector/data_collector.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ type DataCollector struct {
5252
Logger *log.Logger
5353
LogFile *os.File
5454
K8sRestConfig *rest.Config
55-
K8sCoreClientSet *kubernetes.Clientset
55+
K8sCoreClientSet kubernetes.Interface //*kubernetes.Clientset
5656
K8sCrdClientSet *crdClient.Clientset
5757
K8sMetricsClientSet *metricsClient.Clientset
5858
K8sHelmClientSet map[string]helmClient.Client
5959
ExcludeDBData bool
6060
ExcludeTimeSeriesData bool
61+
PodExecutor func(namespace, pod, container string, command []string, ctx context.Context) ([]byte, error)
62+
QueryCRD func(crd crds.Crd, namespace string, ctx context.Context) ([]byte, error)
6163
}
6264

6365
func NewDataCollector(collector *DataCollector) error {
@@ -87,6 +89,8 @@ func NewDataCollector(collector *DataCollector) error {
8789
collector.LogFile = logFile
8890
collector.Logger = log.New(logFile, "", log.LstdFlags|log.LUTC|log.Lmicroseconds|log.Lshortfile)
8991
collector.K8sHelmClientSet = make(map[string]helmClient.Client)
92+
collector.PodExecutor = collector.RealPodExecutor
93+
collector.QueryCRD = collector.RealQueryCRD
9094

9195
//Initialize clients
9296
collector.K8sRestConfig = config
@@ -199,7 +203,7 @@ func (c *DataCollector) WrapUp(product string) (string, error) {
199203
return tarballName, nil
200204
}
201205

202-
func (c *DataCollector) PodExecutor(namespace string, pod string, container string, command []string, ctx context.Context) ([]byte, error) {
206+
func (c *DataCollector) RealPodExecutor(namespace string, pod string, container string, command []string, ctx context.Context) ([]byte, error) {
203207
req := c.K8sCoreClientSet.CoreV1().RESTClient().Post().
204208
Namespace(namespace).
205209
Resource("pods").
@@ -232,7 +236,7 @@ func (c *DataCollector) PodExecutor(namespace string, pod string, container stri
232236
}
233237
}
234238

235-
func (c *DataCollector) QueryCRD(crd crds.Crd, namespace string, ctx context.Context) ([]byte, error) {
239+
func (c *DataCollector) RealQueryCRD(crd crds.Crd, namespace string, ctx context.Context) ([]byte, error) {
236240

237241
schemeGroupVersion := schema.GroupVersion{Group: crd.Group, Version: crd.Version}
238242
negotiatedSerializer := scheme.Codecs.WithoutConversion()
Lines changed: 119 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,133 @@
11
package data_collector
22

33
import (
4-
helmClient "github.com/mittwald/go-helm-client"
5-
crdClient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
6-
"k8s.io/client-go/kubernetes"
7-
"k8s.io/client-go/rest"
8-
metricsClient "k8s.io/metrics/pkg/client/clientset/versioned"
4+
"bytes"
5+
"context"
6+
"io"
97
"log"
108
"os"
9+
"path/filepath"
1110
"testing"
11+
12+
"github.com/nginxinc/nginx-k8s-supportpkg/pkg/crds"
13+
corev1 "k8s.io/api/core/v1"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
"k8s.io/client-go/kubernetes/fake"
16+
"k8s.io/client-go/rest"
1217
)
1318

14-
func TestDataCollector_AllNamespacesExist(t *testing.T) {
15-
type fields struct {
16-
BaseDir string
17-
Namespaces []string
18-
Logger *log.Logger
19-
LogFile *os.File
20-
K8sRestConfig *rest.Config
21-
K8sCoreClientSet *kubernetes.Clientset
22-
K8sCrdClientSet *crdClient.Clientset
23-
K8sMetricsClientSet *metricsClient.Clientset
24-
K8sHelmClientSet map[string]helmClient.Client
19+
func TestNewDataCollector_Success(t *testing.T) {
20+
dc := &DataCollector{Namespaces: []string{"default"}}
21+
err := NewDataCollector(dc)
22+
if err != nil {
23+
t.Fatalf("expected no error, got %v", err)
24+
}
25+
if dc.BaseDir == "" {
26+
t.Error("BaseDir should be set")
27+
}
28+
if dc.Logger == nil {
29+
t.Error("Logger should be set")
30+
}
31+
if dc.LogFile == nil {
32+
t.Error("LogFile should be set")
33+
}
34+
if dc.K8sCoreClientSet == nil {
35+
t.Error("K8sCoreClientSet should be set")
36+
}
37+
if dc.K8sCrdClientSet == nil {
38+
t.Error("K8sCrdClientSet should be set")
39+
}
40+
if dc.K8sMetricsClientSet == nil {
41+
t.Error("K8sMetricsClientSet should be set")
2542
}
43+
if dc.K8sHelmClientSet == nil {
44+
t.Error("K8sHelmClientSet should be set")
45+
}
46+
}
2647

27-
var (
28-
logger *log.Logger = log.New(os.Stdout, "TEST: ", log.LstdFlags)
29-
logFile, _ = os.Create("/path/to/logfile") // Make sure to handle the error in real code.
30-
restConfig *rest.Config = &rest.Config{ /* ... */ }
31-
//coreClientSet *kubernetes.Clientset = /* ... */
32-
//crdClientSet *crdClient.Clientset = crdClient.NewForConfig(config)
33-
//metricsClientSet *metricsClient.Clientset = /* ... */
34-
//helmClientSets map[string]helmClient.Client = /* ... */
35-
)
48+
func TestWrapUp_CreatesTarball(t *testing.T) {
49+
tmpDir := t.TempDir()
50+
logFile, _ := os.Create(filepath.Join(tmpDir, "supportpkg.log"))
51+
dc := &DataCollector{
52+
BaseDir: tmpDir,
53+
LogFile: logFile,
54+
Logger: log.New(io.Discard, "", 0),
55+
}
56+
product := "nginx"
57+
tarball, err := dc.WrapUp(product)
58+
if err != nil {
59+
t.Fatalf("WrapUp failed: %v", err)
60+
}
61+
if _, err := os.Stat(tarball); err != nil {
62+
t.Errorf("tarball not created: %v", err)
63+
}
64+
_ = os.Remove(tarball)
65+
}
3666

37-
//crdClientSet *crdClient.Clientset = crdClient.NewForConfig(config)
67+
func TestRealPodExecutor_ReturnsOutput(t *testing.T) {
68+
dc := &DataCollector{
69+
K8sCoreClientSet: fake.NewSimpleClientset(),
70+
K8sRestConfig: &rest.Config{},
71+
}
72+
// Replace RealPodExecutor with a mock for testing
73+
dc.PodExecutor = func(namespace, pod, container string, command []string, ctx context.Context) ([]byte, error) {
74+
return []byte("output"), nil
75+
}
76+
out, err := dc.PodExecutor("default", "pod", "container", []string{"echo", "hello"}, context.TODO())
77+
if err != nil {
78+
t.Fatalf("expected no error, got %v", err)
79+
}
80+
if !bytes.Contains(out, []byte("output")) {
81+
t.Errorf("expected output, got %s", string(out))
82+
}
83+
}
84+
85+
func TestRealQueryCRD_ReturnsErrorOnInvalidConfig(t *testing.T) {
86+
dc := &DataCollector{
87+
K8sRestConfig: &rest.Config{},
88+
}
89+
crd := crds.Crd{Group: "test", Version: "v1", Resource: "foos"}
90+
_, err := dc.RealQueryCRD(crd, "default", context.TODO())
91+
if err == nil {
92+
t.Error("expected error for invalid config")
93+
}
94+
}
95+
96+
func TestAllNamespacesExist_AllExist(t *testing.T) {
97+
client := fake.NewSimpleClientset(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "default"}})
98+
dc := &DataCollector{
99+
Namespaces: []string{"default"},
100+
K8sCoreClientSet: client,
101+
Logger: log.New(io.Discard, "", 0),
102+
}
103+
if !dc.AllNamespacesExist() {
104+
t.Error("expected all namespaces to exist")
105+
}
106+
}
107+
108+
func TestAllNamespacesExist_NotExist(t *testing.T) {
109+
client := fake.NewSimpleClientset()
110+
dc := &DataCollector{
111+
Namespaces: []string{"missing"},
112+
K8sCoreClientSet: client,
113+
Logger: log.New(io.Discard, "", 0),
114+
}
115+
if dc.AllNamespacesExist() {
116+
t.Error("expected namespaces to not exist")
117+
}
118+
}
38119

39-
tests := []struct {
40-
name string
41-
fields fields
42-
want bool
43-
}{
44-
{
45-
name: "Test Case 1",
46-
fields: fields{
47-
BaseDir: "/path/to/base",
48-
Namespaces: []string{"default", "kube-system"},
49-
Logger: logger,
50-
LogFile: logFile,
51-
K8sRestConfig: restConfig,
52-
//K8sCoreClientSet: coreClientSet,
53-
//K8sCrdClientSet: crdClientSet,
54-
//K8sMetricsClientSet: metricsClientSet,
55-
//K8sHelmClientSet: helmClientSets,
56-
},
57-
want: true,
58-
},
59-
// You can add more test cases as needed.
60-
}
61-
for _, tt := range tests {
62-
t.Run(tt.name, func(t *testing.T) {
63-
c := &DataCollector{
64-
BaseDir: tt.fields.BaseDir,
65-
Namespaces: tt.fields.Namespaces,
66-
Logger: tt.fields.Logger,
67-
LogFile: tt.fields.LogFile,
68-
K8sRestConfig: tt.fields.K8sRestConfig,
69-
K8sCoreClientSet: tt.fields.K8sCoreClientSet,
70-
K8sCrdClientSet: tt.fields.K8sCrdClientSet,
71-
K8sMetricsClientSet: tt.fields.K8sMetricsClientSet,
72-
K8sHelmClientSet: tt.fields.K8sHelmClientSet,
73-
}
74-
if got := c.AllNamespacesExist(); got != tt.want {
75-
t.Errorf("AllNamespacesExist() = %v, want %v", got, tt.want)
76-
}
77-
})
120+
func TestWrapUp_ErrorOnLogFileClose(t *testing.T) {
121+
tmpDir := t.TempDir()
122+
logFile, _ := os.Create(filepath.Join(tmpDir, "supportpkg.log"))
123+
logFile.Close() // Already closed
124+
dc := &DataCollector{
125+
BaseDir: tmpDir,
126+
LogFile: logFile,
127+
Logger: log.New(io.Discard, "", 0),
128+
}
129+
_, err := dc.WrapUp("nginx")
130+
if err == nil {
131+
t.Error("expected error on closing already closed log file")
78132
}
79133
}

pkg/jobs/common_job_list.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func CommonJobList() []Job {
146146
Execute: func(dc *data_collector.DataCollector, ctx context.Context, ch chan JobResult) {
147147
jobResult := JobResult{Files: make(map[string][]byte), Error: nil}
148148
for _, namespace := range dc.Namespaces {
149-
result, err := dc.K8sCoreClientSet.DiscoveryClient.ServerPreferredResources()
149+
result, err := dc.K8sCoreClientSet.Discovery().ServerPreferredResources()
150150
if err != nil {
151151
dc.Logger.Printf("\tCould not retrieve API resources list %s: %v\n", namespace, err)
152152
} else {
@@ -163,7 +163,7 @@ func CommonJobList() []Job {
163163
Execute: func(dc *data_collector.DataCollector, ctx context.Context, ch chan JobResult) {
164164
jobResult := JobResult{Files: make(map[string][]byte), Error: nil}
165165
for _, namespace := range dc.Namespaces {
166-
result, err := dc.K8sCoreClientSet.DiscoveryClient.ServerGroups()
166+
result, err := dc.K8sCoreClientSet.Discovery().ServerGroups()
167167
if err != nil {
168168
dc.Logger.Printf("\tCould not retrieve API versions list %s: %v\n", namespace, err)
169169
} else {
@@ -367,7 +367,7 @@ func CommonJobList() []Job {
367367
Timeout: time.Second * 10,
368368
Execute: func(dc *data_collector.DataCollector, ctx context.Context, ch chan JobResult) {
369369
jobResult := JobResult{Files: make(map[string][]byte), Error: nil}
370-
result, err := dc.K8sCoreClientSet.ServerVersion()
370+
result, err := dc.K8sCoreClientSet.Discovery().ServerVersion()
371371
if err != nil {
372372
dc.Logger.Printf("\tCould not retrieve server version: %v\n", err)
373373
} else {

0 commit comments

Comments
 (0)