Skip to content

Commit

Permalink
add test for proxy
Browse files Browse the repository at this point in the history
Signed-off-by: hejianpeng <[email protected]>
  • Loading branch information
zirain committed Apr 11, 2023
1 parent 141f1a6 commit 59ee7b3
Show file tree
Hide file tree
Showing 13 changed files with 727 additions and 432 deletions.
8 changes: 8 additions & 0 deletions internal/infrastructure/kubernetes/proxy/resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ func (r *ResourceRender) Service() (*corev1.Service, error) {
serviceSpec.Selector = utils.GetSelector(labels).MatchLabels

svc := &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: r.Namespace,
Name: utils.ExpectedResourceHashedName(r.infra.Proxy.Name),
Expand All @@ -128,6 +132,10 @@ func (r *ResourceRender) ConfigMap() (*corev1.ConfigMap, error) {
}

return &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: r.Namespace,
Name: utils.ExpectedResourceHashedName(r.infra.Proxy.Name),
Expand Down
250 changes: 250 additions & 0 deletions internal/infrastructure/kubernetes/proxy/resource_provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

package proxy

import (
"fmt"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/utils/pointer"
"sigs.k8s.io/yaml"

egcfgv1a1 "github.com/envoyproxy/gateway/api/config/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
"github.com/envoyproxy/gateway/internal/ir"
)

const (
// envoyHTTPPort is the container port number of Envoy's HTTP endpoint.
envoyHTTPPort = int32(8080)
// envoyHTTPSPort is the container port number of Envoy's HTTPS endpoint.
envoyHTTPSPort = int32(8443)
)

func newTestInfra() *ir.Infra {
i := ir.NewInfra()

i.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
i.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = i.Proxy.Name
i.Proxy.Listeners = []ir.ProxyListener{
{
Ports: []ir.ListenerPort{
{
Name: "EnvoyHTTPPort",
Protocol: ir.TCPProtocolType,
ContainerPort: envoyHTTPPort,
},
{
Name: "EnvoyHTTPSPort",
Protocol: ir.TCPProtocolType,
ContainerPort: envoyHTTPSPort,
},
},
},
}

return i
}

func TestDeployment(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)

cases := []struct {
caseName string
infra *ir.Infra
deploy *egcfgv1a1.KubernetesDeploymentSpec
bootstrap string
}{
{
caseName: "default",
infra: newTestInfra(),
deploy: nil,
},
{
caseName: "custom",
infra: newTestInfra(),
deploy: &egcfgv1a1.KubernetesDeploymentSpec{
Replicas: pointer.Int32(2),
Pod: &egcfgv1a1.KubernetesPodSpec{
Annotations: map[string]string{
"prometheus.io/scrape": "true",
},
SecurityContext: &corev1.PodSecurityContext{
RunAsUser: pointer.Int64(1000),
},
},
Container: &egcfgv1a1.KubernetesContainerSpec{
Resources: &corev1.ResourceRequirements{
Limits: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("400m"),
corev1.ResourceMemory: resource.MustParse("2Gi"),
},
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("200m"),
corev1.ResourceMemory: resource.MustParse("1Gi"),
},
},
SecurityContext: &corev1.SecurityContext{
Privileged: pointer.Bool(true),
},
},
},
},
{
caseName: "bootstrap",
infra: newTestInfra(),
deploy: nil,
bootstrap: `test bootstrap config`,
},
// TODO: add test cases for custom ProxyLogging
}
for _, tc := range cases {
t.Run(tc.caseName, func(t *testing.T) {
kube := tc.infra.GetProxyInfra().GetProxyConfig().GetEnvoyProxyProvider().GetEnvoyProxyKubeProvider()
if tc.deploy != nil {
kube.EnvoyDeployment = tc.deploy
}

if tc.bootstrap != "" {
tc.infra.Proxy.Config.Spec.Bootstrap = &tc.bootstrap
}

r := NewResourceRender(cfg.Namespace, tc.infra)
dp, err := r.Deployment()
require.NoError(t, err)

expected, err := loadDeployment(tc.caseName)
require.NoError(t, err)

assert.Equal(t, expected, dp)
})
}
}

func loadDeployment(caseName string) (*appsv1.Deployment, error) {
deploymentYAML, err := os.ReadFile(fmt.Sprintf("testdata/deployments/%s.yaml", caseName))
if err != nil {
return nil, err
}
deployment := &appsv1.Deployment{}
_ = yaml.Unmarshal(deploymentYAML, deployment)
return deployment, nil
}

func TestService(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)

svcType := egcfgv1a1.ServiceTypeClusterIP
cases := []struct {
caseName string
infra *ir.Infra
service *egcfgv1a1.KubernetesServiceSpec
}{
{
caseName: "default",
infra: newTestInfra(),
service: nil,
},
{
caseName: "custom",
infra: newTestInfra(),
service: &egcfgv1a1.KubernetesServiceSpec{
Annotations: map[string]string{
"key1": "value1",
},
Type: &svcType,
},
},
}
for _, tc := range cases {
t.Run(tc.caseName, func(t *testing.T) {
provider := tc.infra.GetProxyInfra().GetProxyConfig().GetEnvoyProxyProvider().GetEnvoyProxyKubeProvider()
if tc.service != nil {
provider.EnvoyService = tc.service
}

r := NewResourceRender(cfg.Namespace, tc.infra)
svc, err := r.Service()
require.NoError(t, err)

expected, err := loadService(tc.caseName)
require.NoError(t, err)

assert.Equal(t, expected, svc)
})
}
}

func loadService(caseName string) (*corev1.Service, error) {
serviceYAML, err := os.ReadFile(fmt.Sprintf("testdata/services/%s.yaml", caseName))
if err != nil {
return nil, err
}
svc := &corev1.Service{}
_ = yaml.Unmarshal(serviceYAML, svc)
return svc, nil
}

func TestConfigMap(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)

infra := newTestInfra()

r := NewResourceRender(cfg.Namespace, infra)
cm, err := r.ConfigMap()
require.NoError(t, err)

expected, err := loadConfigmap()
require.NoError(t, err)

assert.Equal(t, expected, cm)
}

func loadConfigmap() (*corev1.ConfigMap, error) {
cmYAML, err := os.ReadFile("testdata/configmap.yaml")
if err != nil {
return nil, err
}
cm := &corev1.ConfigMap{}
_ = yaml.Unmarshal(cmYAML, cm)
return cm, nil
}

func TestServiceAccount(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)

infra := newTestInfra()

r := NewResourceRender(cfg.Namespace, infra)
sa, err := r.ServiceAccount()
require.NoError(t, err)

expected, err := loadServiceAccount()
require.NoError(t, err)

assert.Equal(t, expected, sa)
}

func loadServiceAccount() (*corev1.ServiceAccount, error) {
saYAML, err := os.ReadFile("testdata/serviceaccount.yaml")
if err != nil {
return nil, err
}
sa := &corev1.ServiceAccount{}
_ = yaml.Unmarshal(saYAML, sa)
return sa, nil
}
12 changes: 12 additions & 0 deletions internal/infrastructure/kubernetes/proxy/testdata/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.gateway.envoyproxy.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
name: envoy-default-64656661
namespace: envoy-gateway-system
data:
xds-certificate.json: '{"resources":[{"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret","name":"xds_certificate","tls_certificate":{"certificate_chain":{"filename":"/certs/tls.crt"},"private_key":{"filename":"/certs/tls.key"}}}]}'
xds-trusted-ca.json: '{"resources":[{"@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret","name":"xds_trusted_ca","validation_context":{"trusted_ca":{"filename":"/certs/ca.crt"},"match_typed_subject_alt_names":[{"san_type":"DNS","matcher":{"exact":"envoy-gateway"}}]}}]}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.gateway.envoyproxy.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
name: envoy-default-64656661
namespace: envoy-gateway-system
spec:
replicas: 1
selector:
matchLabels:
app.gateway.envoyproxy.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
template:
metadata:
labels:
app.gateway.envoyproxy.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
spec:
automountServiceAccountToken: false
containers:
- args:
- --service-cluster default
- --service-node $(ENVOY_POD_NAME)
- --config-yaml test bootstrap config
- --log-level info
command:
- envoy
env:
- name: ENVOY_GATEWAY_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: ENVOY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: envoyproxy/envoy-dev:latest
imagePullPolicy: IfNotPresent
name: envoy
ports:
- containerPort: 8080
name: EnvoyHTTPPort
protocol: TCP
- containerPort: 8443
name: EnvoyHTTPSPort
protocol: TCP
resources:
requests:
cpu: 100m
memory: 512Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /certs
name: certs
readOnly: true
- mountPath: /sds
name: sds
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
serviceAccountName: envoy-default-64656661
terminationGracePeriodSeconds: 300
volumes:
- name: certs
secret:
secretName: envoy
- configMap:
defaultMode: 420
items:
- key: xds-trusted-ca.json
path: xds-trusted-ca.json
- key: xds-certificate.json
path: xds-certificate.json
name: envoy-default-64656661
optional: false
name: sds
Loading

0 comments on commit 59ee7b3

Please sign in to comment.