|
| 1 | +package ads |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + "testing" |
| 7 | + |
| 8 | + mapset "github.com/deckarep/golang-set" |
| 9 | + xds_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" |
| 10 | + "github.com/google/uuid" |
| 11 | + corev1 "k8s.io/api/core/v1" |
| 12 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 13 | + k8sClientFake "k8s.io/client-go/kubernetes/fake" |
| 14 | + |
| 15 | + configv1alpha2 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2" |
| 16 | + "github.com/openservicemesh/osm/pkg/catalog" |
| 17 | + "github.com/openservicemesh/osm/pkg/endpoint" |
| 18 | + "github.com/openservicemesh/osm/pkg/k8s/informers" |
| 19 | + "github.com/openservicemesh/osm/pkg/logger" |
| 20 | + "github.com/openservicemesh/osm/pkg/messaging" |
| 21 | + "github.com/openservicemesh/osm/pkg/policy" |
| 22 | + "github.com/openservicemesh/osm/pkg/providers/kube" |
| 23 | + "github.com/openservicemesh/osm/pkg/signals" |
| 24 | + "github.com/openservicemesh/osm/pkg/smi" |
| 25 | + |
| 26 | + "github.com/openservicemesh/osm/pkg/certificate" |
| 27 | + |
| 28 | + "github.com/openservicemesh/osm/pkg/configurator" |
| 29 | + "github.com/openservicemesh/osm/pkg/constants" |
| 30 | + "github.com/openservicemesh/osm/pkg/envoy" |
| 31 | + "github.com/openservicemesh/osm/pkg/envoy/registry" |
| 32 | + configFake "github.com/openservicemesh/osm/pkg/gen/client/config/clientset/versioned/fake" |
| 33 | + policyFake "github.com/openservicemesh/osm/pkg/gen/client/policy/clientset/versioned/fake" |
| 34 | + "github.com/openservicemesh/osm/pkg/k8s" |
| 35 | + "github.com/openservicemesh/osm/pkg/service" |
| 36 | + "github.com/openservicemesh/osm/pkg/tests" |
| 37 | +) |
| 38 | + |
| 39 | +var ( |
| 40 | + proxy *envoy.Proxy |
| 41 | + server xds_discovery.AggregatedDiscoveryService_StreamAggregatedResourcesServer |
| 42 | + osmConfigurator *configurator.Client |
| 43 | + adsServer *Server |
| 44 | +) |
| 45 | + |
| 46 | +func setupTestServer(b *testing.B) { |
| 47 | + stop := signals.RegisterExitHandlers() |
| 48 | + msgBroker := messaging.NewBroker(stop) |
| 49 | + kubeClient := k8sClientFake.NewSimpleClientset() |
| 50 | + configClient := configFake.NewSimpleClientset() |
| 51 | + policyClient := policyFake.NewSimpleClientset() |
| 52 | + informerCollection, err := informers.NewInformerCollection(tests.MeshName, stop, |
| 53 | + informers.WithKubeClient(kubeClient), |
| 54 | + informers.WithConfigClient(configClient, tests.OsmMeshConfigName, tests.OsmNamespace), |
| 55 | + ) |
| 56 | + if err != nil { |
| 57 | + b.Fatalf("Failed to create informer collection: %s", err) |
| 58 | + } |
| 59 | + kubeController := k8s.NewKubernetesController(informerCollection, policyClient, msgBroker) |
| 60 | + policyController := policy.NewPolicyController(informerCollection, kubeController, msgBroker) |
| 61 | + osmConfigurator = configurator.NewConfigurator(informerCollection, tests.OsmNamespace, tests.OsmMeshConfigName, msgBroker) |
| 62 | + kubeProvider := kube.NewClient(kubeController, osmConfigurator) |
| 63 | + |
| 64 | + meshConfig := configv1alpha2.MeshConfig{ |
| 65 | + TypeMeta: metav1.TypeMeta{ |
| 66 | + APIVersion: "config.openservicemesh.io", |
| 67 | + Kind: "MeshConfig", |
| 68 | + }, |
| 69 | + ObjectMeta: metav1.ObjectMeta{ |
| 70 | + Namespace: tests.OsmNamespace, |
| 71 | + Name: tests.OsmMeshConfigName, |
| 72 | + }, Spec: configv1alpha2.MeshConfigSpec{ |
| 73 | + Certificate: configv1alpha2.CertificateSpec{ |
| 74 | + CertKeyBitSize: 2048, |
| 75 | + ServiceCertValidityDuration: "1h", |
| 76 | + }, |
| 77 | + Traffic: configv1alpha2.TrafficSpec{ |
| 78 | + EnableEgress: true, |
| 79 | + EnablePermissiveTrafficPolicyMode: true, |
| 80 | + }, |
| 81 | + Observability: configv1alpha2.ObservabilitySpec{ |
| 82 | + EnableDebugServer: false, |
| 83 | + Tracing: configv1alpha2.TracingSpec{ |
| 84 | + Enable: false, |
| 85 | + }, |
| 86 | + }, |
| 87 | + FeatureFlags: configv1alpha2.FeatureFlags{ |
| 88 | + EnableWASMStats: false, |
| 89 | + EnableEgressPolicy: false, |
| 90 | + }, |
| 91 | + }, |
| 92 | + } |
| 93 | + _, err = configClient.ConfigV1alpha2().MeshConfigs(tests.OsmNamespace).Create(context.Background(), &meshConfig, metav1.CreateOptions{}) |
| 94 | + if err != nil { |
| 95 | + b.Fatalf("Failed to create mesh config: %v", err) |
| 96 | + } |
| 97 | + |
| 98 | + certManager, err := certificate.FakeCertManager() |
| 99 | + if err != nil { |
| 100 | + b.Fatalf("Failed to create fake cert manager: %v", err) |
| 101 | + } |
| 102 | + |
| 103 | + // --- setup |
| 104 | + namespace := tests.Namespace |
| 105 | + proxyService := service.MeshService{ |
| 106 | + Name: tests.BookstoreV1ServiceName, |
| 107 | + Namespace: namespace, |
| 108 | + } |
| 109 | + proxySvcAccount := tests.BookstoreServiceAccount |
| 110 | + |
| 111 | + certPEM, _ := certManager.IssueCertificate(proxySvcAccount.ToServiceIdentity().String(), certificate.Service) |
| 112 | + cert, _ := certificate.DecodePEMCertificate(certPEM.GetCertificateChain()) |
| 113 | + server, _ = tests.NewFakeXDSServer(cert, nil, nil) |
| 114 | + |
| 115 | + proxyUUID := uuid.New() |
| 116 | + labels := map[string]string{constants.EnvoyUniqueIDLabelName: proxyUUID.String()} |
| 117 | + meshSpec := smi.NewSMIClient(informerCollection, tests.OsmNamespace, kubeController, msgBroker) |
| 118 | + mc := catalog.NewMeshCatalog( |
| 119 | + kubeController, |
| 120 | + meshSpec, |
| 121 | + certManager, |
| 122 | + policyController, |
| 123 | + stop, |
| 124 | + osmConfigurator, |
| 125 | + []service.Provider{kubeProvider}, |
| 126 | + []endpoint.Provider{kubeProvider}, |
| 127 | + msgBroker, |
| 128 | + ) |
| 129 | + |
| 130 | + proxyRegistry := registry.NewProxyRegistry(registry.ExplicitProxyServiceMapper(func(*envoy.Proxy) ([]service.MeshService, error) { |
| 131 | + return nil, nil |
| 132 | + }), nil) |
| 133 | + |
| 134 | + pod := tests.NewPodFixture(namespace, fmt.Sprintf("pod-0-%s", proxyUUID), tests.BookstoreServiceAccountName, tests.PodLabels) |
| 135 | + pod.Labels[constants.EnvoyUniqueIDLabelName] = proxyUUID.String() |
| 136 | + _, err = kubeClient.CoreV1().Pods(namespace).Create(context.Background(), pod, metav1.CreateOptions{}) |
| 137 | + if err != nil { |
| 138 | + b.Fatalf("Failed to create pod: %v", err) |
| 139 | + } |
| 140 | + |
| 141 | + // monitor namespace |
| 142 | + nsObj := corev1.Namespace{ |
| 143 | + ObjectMeta: metav1.ObjectMeta{ |
| 144 | + Name: namespace, |
| 145 | + Labels: map[string]string{constants.OSMKubeResourceMonitorAnnotation: tests.MeshName}, |
| 146 | + }, |
| 147 | + } |
| 148 | + if err := informerCollection.Add(informers.InformerKeyNamespace, &nsObj, &testing.T{}); err != nil { |
| 149 | + b.Fatalf("Failed to add namespace to informer collection: %s", err) |
| 150 | + } |
| 151 | + |
| 152 | + svc := tests.NewServiceFixture(proxyService.Name, namespace, labels) |
| 153 | + _, err = kubeClient.CoreV1().Services(namespace).Create(context.Background(), svc, metav1.CreateOptions{}) |
| 154 | + if err != nil { |
| 155 | + b.Fatalf("Failed to create service: %v", err) |
| 156 | + } |
| 157 | + |
| 158 | + proxy = envoy.NewProxy(envoy.KindSidecar, proxyUUID, proxySvcAccount.ToServiceIdentity(), nil) |
| 159 | + |
| 160 | + adsServer = NewADSServer(mc, proxyRegistry, true, tests.Namespace, osmConfigurator, certManager, kubeController, nil) |
| 161 | +} |
| 162 | + |
| 163 | +func BenchmarkSendXDSResponse(b *testing.B) { |
| 164 | + // TODO(allenlsy): Add EDS to the list |
| 165 | + testingXdsTypes := []envoy.TypeURI{ |
| 166 | + envoy.TypeLDS, |
| 167 | + envoy.TypeSDS, |
| 168 | + envoy.TypeRDS, |
| 169 | + envoy.TypeCDS, |
| 170 | + } |
| 171 | + |
| 172 | + if err := logger.SetLogLevel("error"); err != nil { |
| 173 | + b.Logf("Failed to set log level to error: %s", err) |
| 174 | + } |
| 175 | + |
| 176 | + for _, xdsType := range testingXdsTypes { |
| 177 | + b.Run(string(xdsType), func(b *testing.B) { |
| 178 | + setupTestServer(b) |
| 179 | + |
| 180 | + // Set subscribed resources |
| 181 | + proxy.SetSubscribedResources(xdsType, mapset.NewSetWith("service-cert:default/bookstore", "root-cert-for-mtls-inbound:default/bookstore|80")) |
| 182 | + |
| 183 | + b.ResetTimer() |
| 184 | + b.StartTimer() |
| 185 | + for i := 0; i < b.N; i++ { |
| 186 | + if err := adsServer.sendResponse(proxy, &server, nil, osmConfigurator, xdsType); err != nil { |
| 187 | + b.Fatalf("Failed to send response: %s", err) |
| 188 | + } |
| 189 | + } |
| 190 | + b.StopTimer() |
| 191 | + }) |
| 192 | + } |
| 193 | +} |
0 commit comments