Skip to content

Commit 961954a

Browse files
committed
added unit test to increase test coverage
1 parent 06e701d commit 961954a

File tree

2 files changed

+211
-2
lines changed

2 files changed

+211
-2
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// Copyright (c) F5, Inc.
2+
//
3+
// This source code is licensed under the Apache License, Version 2.0 license found in the
4+
// LICENSE file in the root directory of this source tree.
5+
6+
package stubstatus
7+
8+
import (
9+
"context"
10+
"crypto/rand"
11+
"crypto/rsa"
12+
"crypto/tls"
13+
"crypto/x509"
14+
"crypto/x509/pkix"
15+
"encoding/pem"
16+
"math/big"
17+
"net"
18+
"net/http"
19+
"net/http/httptest"
20+
"os"
21+
"path/filepath"
22+
"testing"
23+
"time"
24+
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
"go.opentelemetry.io/collector/component"
28+
"go.opentelemetry.io/collector/component/componenttest"
29+
"go.opentelemetry.io/collector/receiver/receivertest"
30+
31+
"github.com/nginx/agent/v3/internal/collector/nginxossreceiver/internal/config"
32+
)
33+
34+
func TestStubStatusScraperTLS(t *testing.T) {
35+
// Create a test CA certificate and key
36+
ca := &x509.Certificate{
37+
SerialNumber: big.NewInt(1),
38+
Subject: pkix.Name{
39+
Organization: []string{"NGINX Agent Test CA"},
40+
},
41+
NotBefore: time.Now(),
42+
NotAfter: time.Now().AddDate(10, 0, 0),
43+
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
44+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
45+
BasicConstraintsValid: true,
46+
IsCA: true,
47+
}
48+
49+
caPrivKey, err := rsa.GenerateKey(rand.Reader, 2048)
50+
require.NoError(t, err)
51+
52+
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
53+
require.NoError(t, err)
54+
55+
// Create a test server certificate signed by the CA
56+
cert := &x509.Certificate{
57+
SerialNumber: big.NewInt(2),
58+
Subject: pkix.Name{
59+
Organization: []string{"NGINX Agent Test"},
60+
},
61+
NotBefore: time.Now(),
62+
NotAfter: time.Now().AddDate(10, 0, 0),
63+
SubjectKeyId: []byte{1, 2, 3, 4, 6},
64+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
65+
KeyUsage: x509.KeyUsageDigitalSignature,
66+
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1)},
67+
DNSNames: []string{"localhost"},
68+
}
69+
70+
certPrivKey, err := rsa.GenerateKey(rand.Reader, 2048)
71+
require.NoError(t, err)
72+
73+
certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey)
74+
require.NoError(t, err)
75+
76+
// Create a temporary directory for test files
77+
tempDir := t.TempDir()
78+
79+
// Save CA certificate to a file
80+
caFile := filepath.Join(tempDir, "ca.crt")
81+
caPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caBytes})
82+
err = os.WriteFile(caFile, caPEM, 0o600)
83+
require.NoError(t, err)
84+
85+
// Create a TLS config for the server
86+
serverTLSConfig := &tls.Config{
87+
Certificates: []tls.Certificate{
88+
{
89+
Certificate: [][]byte{certBytes},
90+
PrivateKey: certPrivKey,
91+
},
92+
},
93+
}
94+
95+
// Create a test server with TLS
96+
server := httptest.NewUnstartedServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
97+
if req.URL.Path == "/status" {
98+
rw.WriteHeader(http.StatusOK)
99+
_, _ = rw.Write([]byte(`Active connections: 291
100+
server accepts handled requests
101+
16630948 16630946 31070465
102+
Reading: 6 Writing: 179 Waiting: 106
103+
`))
104+
return
105+
}
106+
rw.WriteHeader(http.StatusNotFound)
107+
}))
108+
109+
server.TLS = serverTLSConfig
110+
server.StartTLS()
111+
defer server.Close()
112+
113+
// Test with TLS configuration
114+
t.Run("with TLS CA", func(t *testing.T) {
115+
cfg, ok := config.CreateDefaultConfig().(*config.Config)
116+
require.True(t, ok)
117+
118+
cfg.APIDetails.URL = server.URL + "/status"
119+
cfg.APIDetails.Ca = caFile
120+
121+
scraper := NewScraper(receivertest.NewNopSettings(component.Type{}), cfg)
122+
123+
err := scraper.Start(context.Background(), componenttest.NewNopHost())
124+
require.NoError(t, err)
125+
126+
_, err = scraper.Scrape(context.Background())
127+
assert.NoError(t, err)
128+
})
129+
}
130+
131+
func TestStubStatusScraperUnixSocket(t *testing.T) {
132+
tempDir, err := os.MkdirTemp("", "TestStubStatusScraperUnixSocket")
133+
require.NoError(t, err)
134+
t.Cleanup(func() { os.RemoveAll(tempDir) })
135+
socketPath := filepath.Join(tempDir, "nginx.sock")
136+
137+
// Create a Unix domain socket listener
138+
listener, err := net.Listen("unix", socketPath)
139+
require.NoError(t, err)
140+
defer listener.Close()
141+
142+
// Start a simple HTTP server on the Unix socket
143+
server := &http.Server{
144+
Handler: http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
145+
if req.URL.Path == "/status" {
146+
rw.WriteHeader(http.StatusOK)
147+
_, _ = rw.Write([]byte(`Active connections: 291
148+
server accepts handled requests
149+
16630948 16630946 31070465
150+
Reading: 6 Writing: 179 Waiting: 106
151+
`))
152+
return
153+
}
154+
rw.WriteHeader(http.StatusNotFound)
155+
}),
156+
}
157+
158+
go func() {
159+
_ = server.Serve(listener)
160+
}()
161+
defer server.Close()
162+
163+
// Test with Unix socket
164+
t.Run("with Unix socket", func(t *testing.T) {
165+
cfg, ok := config.CreateDefaultConfig().(*config.Config)
166+
require.True(t, ok)
167+
168+
cfg.APIDetails.URL = "http://unix/status"
169+
cfg.APIDetails.Listen = "unix:" + socketPath
170+
171+
scraper := NewScraper(receivertest.NewNopSettings(component.Type{}), cfg)
172+
173+
err := scraper.Start(context.Background(), componenttest.NewNopHost())
174+
require.NoError(t, err)
175+
176+
_, err = scraper.Scrape(context.Background())
177+
assert.NoError(t, err)
178+
})
179+
}

internal/resource/resource_service_test.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"context"
1010
"errors"
1111
"fmt"
12+
"os"
1213
"testing"
1314

1415
"github.com/nginx/agent/v3/internal/model"
@@ -26,6 +27,7 @@ import (
2627
"github.com/nginx/agent/v3/api/grpc/mpi/v1"
2728
"github.com/nginx/agent/v3/test/protos"
2829
"github.com/stretchr/testify/assert"
30+
"github.com/stretchr/testify/require"
2931
)
3032

3133
func TestResourceService_AddInstance(t *testing.T) {
@@ -237,6 +239,15 @@ func TestResourceService_GetResource(t *testing.T) {
237239
}
238240

239241
func TestResourceService_createPlusClient(t *testing.T) {
242+
// Create a temporary file for testing CA certificate
243+
tempCAFile, err := os.CreateTemp("", "test-ca.crt")
244+
require.NoError(t, err)
245+
defer os.Remove(tempCAFile.Name())
246+
247+
_, err = tempCAFile.Write([]byte("-----BEGIN CERTIFICATE-----\nMII...\n-----END CERTIFICATE-----"))
248+
require.NoError(t, err)
249+
tempCAFile.Close()
250+
240251
instanceWithAPI := protos.NginxPlusInstance([]string{})
241252
instanceWithAPI.InstanceRuntime.GetNginxPlusRuntimeInfo().PlusApi = &v1.APIDetails{
242253
Location: "/api",
@@ -249,6 +260,13 @@ func TestResourceService_createPlusClient(t *testing.T) {
249260
Location: "/api",
250261
}
251262

263+
instanceWithCACert := protos.NginxPlusInstance([]string{})
264+
instanceWithCACert.InstanceRuntime.GetNginxPlusRuntimeInfo().PlusApi = &v1.APIDetails{
265+
Location: "/api",
266+
Listen: "localhost:443",
267+
Ca: tempCAFile.Name(),
268+
}
269+
252270
ctx := context.Background()
253271
tests := []struct {
254272
err error
@@ -266,7 +284,12 @@ func TestResourceService_createPlusClient(t *testing.T) {
266284
err: nil,
267285
},
268286
{
269-
name: "Test 3: Fail Creating Client - API not Configured",
287+
name: "Test 3: Create Plus Client with CA Certificate",
288+
instance: instanceWithCACert,
289+
err: nil,
290+
},
291+
{
292+
name: "Test 4: Fail Creating Client - API not Configured",
270293
instance: protos.NginxPlusInstance([]string{}),
271294
err: errors.New("failed to preform API action, NGINX Plus API is not configured"),
272295
},
@@ -281,7 +304,14 @@ func TestResourceService_createPlusClient(t *testing.T) {
281304
}
282305

283306
_, err := resourceService.createPlusClient(test.instance)
284-
assert.Equal(tt, test.err, err)
307+
if test.err != nil {
308+
assert.Error(tt, err)
309+
assert.Contains(tt, err.Error(), test.err.Error())
310+
} else {
311+
assert.NoError(tt, err)
312+
// For the CA cert test, we can't easily verify the internal http.Client configuration
313+
// without exporting it or adding test hooks, so we'll just verify no error is returned
314+
}
285315
})
286316
}
287317
}

0 commit comments

Comments
 (0)