Skip to content

Commit 8bbb4f1

Browse files
coverage
Signed-off-by: Adrian Cole <[email protected]>
1 parent 1ed6120 commit 8bbb4f1

File tree

1 file changed

+216
-14
lines changed

1 file changed

+216
-14
lines changed

internal/infrastructure/host/proxy_infra_test.go

Lines changed: 216 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
"bytes"
1010
"fmt"
1111
"io"
12+
"os"
1213
"path"
14+
"path/filepath"
1315
"testing"
1416
"time"
1517

@@ -24,9 +26,10 @@ import (
2426
"github.com/envoyproxy/gateway/internal/infrastructure/common"
2527
"github.com/envoyproxy/gateway/internal/ir"
2628
"github.com/envoyproxy/gateway/internal/logging"
29+
"github.com/envoyproxy/gateway/internal/utils"
2730
"github.com/envoyproxy/gateway/internal/utils/file"
2831
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
29-
"github.com/envoyproxy/gateway/test/utils"
32+
testutils "github.com/envoyproxy/gateway/test/utils"
3033
)
3134

3235
func newMockInfra(t *testing.T, cfg *config.Server) *Infra {
@@ -65,31 +68,188 @@ func TestInfraCreateProxy(t *testing.T) {
6568

6669
// TODO: add more tests once it supports configurable homeDir and runDir.
6770
testCases := []struct {
68-
name string
69-
expect bool
70-
infra *ir.Infra
71+
name string
72+
infra *ir.Infra
73+
expectedError string
7174
}{
7275
{
73-
name: "nil cfg",
74-
expect: false,
75-
infra: nil,
76+
name: "nil cfg",
77+
infra: nil,
78+
expectedError: "infra ir is nil",
7679
},
7780
{
78-
name: "nil proxy",
79-
expect: false,
81+
name: "nil proxy",
8082
infra: &ir.Infra{
8183
Proxy: nil,
8284
},
85+
expectedError: "infra proxy ir is nil",
8386
},
8487
}
8588

8689
for _, tc := range testCases {
8790
t.Run(tc.name, func(t *testing.T) {
88-
err = infra.CreateOrUpdateProxyInfra(t.Context(), tc.infra)
89-
if tc.expect {
90-
require.NoError(t, err)
91+
actual := infra.CreateOrUpdateProxyInfra(t.Context(), tc.infra)
92+
require.EqualError(t, actual, tc.expectedError)
93+
})
94+
}
95+
}
96+
97+
func TestInfra_CreateOrUpdateProxyInfra_Success(t *testing.T) {
98+
tmpdir := t.TempDir()
99+
// Ensures that all the required binaries are available.
100+
err := func_e.Run(t.Context(), []string{"--version"}, api.HomeDir(tmpdir))
101+
require.NoError(t, err)
102+
103+
cfg, err := config.New(io.Discard, io.Discard)
104+
require.NoError(t, err)
105+
infra := newMockInfra(t, cfg)
106+
107+
testCases := []struct {
108+
name string
109+
proxyName string
110+
expectProxyLoaded bool
111+
}{
112+
{
113+
name: "create new proxy",
114+
proxyName: "test-proxy",
115+
expectProxyLoaded: true,
116+
},
117+
{
118+
name: "idempotent - proxy already exists",
119+
proxyName: "test-proxy-idempotent",
120+
expectProxyLoaded: true,
121+
},
122+
}
123+
124+
for _, tc := range testCases {
125+
t.Run(tc.name, func(t *testing.T) {
126+
infraIR := &ir.Infra{
127+
Proxy: &ir.ProxyInfra{
128+
Name: tc.proxyName,
129+
Namespace: "default",
130+
Config: &egv1a1.EnvoyProxy{
131+
Spec: egv1a1.EnvoyProxySpec{
132+
Logging: egv1a1.ProxyLogging{
133+
Level: map[egv1a1.ProxyLogComponent]egv1a1.LogLevel{
134+
egv1a1.LogComponentDefault: egv1a1.LogLevelInfo,
135+
},
136+
},
137+
},
138+
},
139+
},
140+
}
141+
142+
hashedName := utils.GetHashedName(tc.proxyName, 64)
143+
t.Cleanup(func() { infra.stopEnvoy(hashedName) })
144+
145+
// First call should create the proxy
146+
actual := infra.CreateOrUpdateProxyInfra(t.Context(), infraIR)
147+
require.NoError(t, actual)
148+
149+
// Verify proxy context was stored
150+
_, loaded := infra.proxyContextMap.Load(hashedName)
151+
require.Equal(t, tc.expectProxyLoaded, loaded)
152+
153+
// Second call should be idempotent (early return)
154+
actual = infra.CreateOrUpdateProxyInfra(t.Context(), infraIR)
155+
require.NoError(t, actual)
156+
157+
// Verify proxy is still loaded
158+
_, loaded = infra.proxyContextMap.Load(hashedName)
159+
require.Equal(t, tc.expectProxyLoaded, loaded)
160+
})
161+
}
162+
}
163+
164+
func TestInfra_DeleteProxyInfra(t *testing.T) {
165+
tmpdir := t.TempDir()
166+
// Ensures that all the required binaries are available.
167+
err := func_e.Run(t.Context(), []string{"--version"}, api.HomeDir(tmpdir))
168+
require.NoError(t, err)
169+
170+
cfg, err := config.New(io.Discard, io.Discard)
171+
require.NoError(t, err)
172+
infra := newMockInfra(t, cfg)
173+
174+
testCases := []struct {
175+
name string
176+
setupProxy bool
177+
proxyName string
178+
infraIR *ir.Infra
179+
expectedError string
180+
expectRemoved bool
181+
}{
182+
{
183+
name: "delete existing proxy",
184+
setupProxy: true,
185+
proxyName: "test-proxy-delete",
186+
infraIR: &ir.Infra{
187+
Proxy: &ir.ProxyInfra{
188+
Name: "test-proxy-delete",
189+
Namespace: "default",
190+
Config: &egv1a1.EnvoyProxy{
191+
Spec: egv1a1.EnvoyProxySpec{
192+
Logging: egv1a1.ProxyLogging{
193+
Level: map[egv1a1.ProxyLogComponent]egv1a1.LogLevel{
194+
egv1a1.LogComponentDefault: egv1a1.LogLevelInfo,
195+
},
196+
},
197+
},
198+
},
199+
},
200+
},
201+
expectedError: "",
202+
expectRemoved: true,
203+
},
204+
{
205+
name: "delete non-existent proxy",
206+
setupProxy: false,
207+
proxyName: "non-existent-proxy",
208+
infraIR: &ir.Infra{
209+
Proxy: &ir.ProxyInfra{
210+
Name: "non-existent-proxy",
211+
Namespace: "default",
212+
Config: &egv1a1.EnvoyProxy{},
213+
},
214+
},
215+
expectedError: "",
216+
expectRemoved: false,
217+
},
218+
{
219+
name: "nil infra",
220+
setupProxy: false,
221+
infraIR: nil,
222+
expectedError: "infra ir is nil",
223+
},
224+
}
225+
226+
for _, tc := range testCases {
227+
t.Run(tc.name, func(t *testing.T) {
228+
var hashedName string
229+
if tc.setupProxy {
230+
// Create a proxy first
231+
actual := infra.CreateOrUpdateProxyInfra(t.Context(), tc.infraIR)
232+
require.NoError(t, actual)
233+
234+
hashedName = utils.GetHashedName(tc.proxyName, 64)
235+
t.Cleanup(func() { infra.stopEnvoy(hashedName) })
236+
237+
_, loaded := infra.proxyContextMap.Load(hashedName)
238+
require.True(t, loaded, "proxy should be loaded before deletion")
239+
}
240+
241+
// Delete the proxy
242+
actual := infra.DeleteProxyInfra(t.Context(), tc.infraIR)
243+
if tc.expectedError != "" {
244+
require.EqualError(t, actual, tc.expectedError)
91245
} else {
92-
require.Error(t, err)
246+
require.NoError(t, actual)
247+
}
248+
249+
// Verify deletion
250+
if tc.expectRemoved {
251+
_, loaded := infra.proxyContextMap.Load(hashedName)
252+
require.False(t, loaded, "proxy should be removed after deletion")
93253
}
94254
})
95255
}
@@ -206,7 +366,7 @@ func TestInfra_runEnvoy_OutputRedirection(t *testing.T) {
206366
require.NoError(t, err)
207367

208368
// Create separate buffers for stdout and stderr
209-
buffers := utils.DumpLogsOnFail(t, "stdout", "stderr")
369+
buffers := testutils.DumpLogsOnFail(t, "stdout", "stderr")
210370
stdout := buffers[0]
211371
stderr := buffers[1]
212372

@@ -323,6 +483,48 @@ func TestGetEnvoyVersion(t *testing.T) {
323483
// TestTopologyInjectorDisabledInHostMode verifies we don't cause a 15+ second
324484
// startup delay in standalone mode as Envoy waits for endpoint discovery.
325485
// See: https://github.com/envoyproxy/gateway/issues/7080
486+
func TestNewInfra(t *testing.T) {
487+
// This test verifies successful creation of Infra using defaults.
488+
// NewInfra uses hardcoded paths like defaultHomeDir and defaultLocalCertPathDir,
489+
// so we can only test the success case where those directories exist.
490+
cfg, err := config.New(io.Discard, io.Discard)
491+
require.NoError(t, err)
492+
493+
actual, err := NewInfra(t.Context(), cfg, logging.DefaultLogger(io.Discard, egv1a1.LogLevelInfo))
494+
require.NoError(t, err)
495+
require.NotNil(t, actual)
496+
require.Equal(t, defaultHomeDir, actual.HomeDir)
497+
require.Equal(t, defaultLocalCertPathDir, actual.sdsConfigPath)
498+
require.NotNil(t, actual.Logger)
499+
require.NotNil(t, actual.EnvoyGateway)
500+
require.Equal(t, egv1a1.DefaultEnvoyProxyImage, actual.defaultEnvoyImage)
501+
require.NotNil(t, actual.Stdout)
502+
require.NotNil(t, actual.Stderr)
503+
}
504+
505+
func TestCreateSdsConfig(t *testing.T) {
506+
dir := t.TempDir()
507+
// Create required cert files
508+
require.NoError(t, file.WriteDir([]byte("test ca"), dir, XdsTLSCaFilename))
509+
require.NoError(t, file.WriteDir([]byte("test cert"), dir, XdsTLSCertFilename))
510+
require.NoError(t, file.WriteDir([]byte("test key"), dir, XdsTLSKeyFilename))
511+
512+
actual := createSdsConfig(dir)
513+
require.NoError(t, actual)
514+
515+
// Verify CA config was created
516+
caConfigPath := filepath.Join(dir, common.SdsCAFilename)
517+
actualCAConfig, err := os.ReadFile(caConfigPath)
518+
require.NoError(t, err)
519+
require.NotEmpty(t, actualCAConfig)
520+
521+
// Verify cert config was created
522+
certConfigPath := filepath.Join(dir, common.SdsCertFilename)
523+
actualCertConfig, err := os.ReadFile(certConfigPath)
524+
require.NoError(t, err)
525+
require.NotEmpty(t, actualCertConfig)
526+
}
527+
326528
func TestTopologyInjectorDisabledInHostMode(t *testing.T) {
327529
testCases := []struct {
328530
name string

0 commit comments

Comments
 (0)