istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tests/integration/telemetry/tracing/otelcollector/tracing_test.go (about) 1 //go:build integ 2 // +build integ 3 4 // Copyright Istio Authors. All Rights Reserved. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 // Package otelcollector allows testing a variety of tracing solutions by 19 // employing an OpenTelemetry collector that exposes receiver endpoints for 20 // various protocols and forwards the spans to a Zipkin backend (for further 21 // querying and inspection). 22 package otelcollector 23 24 import ( 25 _ "embed" 26 "errors" 27 "fmt" 28 "testing" 29 "time" 30 31 "istio.io/istio/pkg/test/framework" 32 "istio.io/istio/pkg/test/framework/components/istio" 33 "istio.io/istio/pkg/test/framework/components/opentelemetry" 34 "istio.io/istio/pkg/test/framework/label" 35 "istio.io/istio/pkg/test/framework/resource" 36 "istio.io/istio/pkg/test/util/retry" 37 "istio.io/istio/tests/integration/telemetry/tracing" 38 ) 39 40 //go:embed testdata/otel-tracing.yaml 41 var otelTracingCfg string 42 43 //go:embed testdata/otel-tracing-http.yaml 44 var otelTracingHTTPCfg string 45 46 //go:embed testdata/otel-tracing-res-detectors.yaml 47 var otelTracingResDetectorsCfg string 48 49 // TestProxyTracingOpenTelemetryProvider validates that Telemetry API configuration 50 // referencing an OpenTelemetry provider will generate traces appropriately. 51 // NOTE: This test relies on the priority of Telemetry API over MeshConfig tracing 52 // configuration. In the future, these two approaches should likely be separated 53 // into two distinct test suites. 54 func TestProxyTracingOpenTelemetryProvider(t *testing.T) { 55 testcases := []struct { 56 name string 57 customAttribute string 58 cfgFile string 59 }{ 60 { 61 name: "grpc exporter", 62 customAttribute: "provider=otel", 63 cfgFile: otelTracingCfg, 64 }, 65 { 66 name: "http exporter", 67 customAttribute: "provider=otel-http", 68 cfgFile: otelTracingHTTPCfg, 69 }, 70 { 71 name: "resource detectors", 72 customAttribute: "provider=otel-grpc-with-res-detectors", 73 cfgFile: otelTracingResDetectorsCfg, 74 }, 75 } 76 77 framework.NewTest(t). 78 Run(func(ctx framework.TestContext) { 79 appNsInst := tracing.GetAppNamespace() 80 81 for _, tc := range testcases { 82 ctx.NewSubTest(tc.name). 83 Run(func(ctx framework.TestContext) { 84 // apply Telemetry resource with OTel provider 85 ctx.ConfigIstio().YAML(appNsInst.Name(), tc.cfgFile).ApplyOrFail(ctx) 86 87 // TODO fix tracing tests in multi-network https://github.com/istio/istio/issues/28890 88 for _, cluster := range ctx.Clusters().ByNetwork()[ctx.Clusters().Default().NetworkName()] { 89 cluster := cluster 90 ctx.NewSubTest(cluster.StableName()).Run(func(ctx framework.TestContext) { 91 retry.UntilSuccessOrFail(ctx, func() error { 92 err := tracing.SendTraffic(ctx, nil, cluster) 93 if err != nil { 94 return fmt.Errorf("cannot send traffic from cluster %s: %v", cluster.Name(), err) 95 } 96 97 // the OTel collector exports to Zipkin 98 traces, err := tracing.GetZipkinInstance().QueryTraces(300, "", tc.customAttribute) 99 t.Logf("got traces %v from %s", traces, cluster) 100 if err != nil { 101 return fmt.Errorf("cannot get traces from zipkin: %v", err) 102 } 103 if !tracing.VerifyOtelEchoTraces(ctx, appNsInst.Name(), cluster.Name(), traces) { 104 return errors.New("cannot find expected traces") 105 } 106 return nil 107 }, retry.Delay(3*time.Second), retry.Timeout(80*time.Second)) 108 }) 109 } 110 }) 111 } 112 }) 113 } 114 115 func TestMain(m *testing.M) { 116 framework.NewSuite(m). 117 Label(label.CustomSetup). 118 Setup(istio.Setup(tracing.GetIstioInstance(), setupConfig)). 119 Setup(tracing.TestSetup). 120 Setup(testSetup). 121 Run() 122 } 123 124 // TODO: convert test to Telemetry API for both scenarios 125 func setupConfig(_ resource.Context, cfg *istio.Config) { 126 if cfg == nil { 127 return 128 } 129 cfg.ControlPlaneValues = ` 130 meshConfig: 131 enableTracing: true 132 extensionProviders: 133 - name: test-otel 134 opentelemetry: 135 service: opentelemetry-collector.istio-system.svc.cluster.local 136 port: 4317 137 - name: test-otel-http 138 opentelemetry: 139 service: opentelemetry-collector.istio-system.svc.cluster.local 140 port: 4318 141 http: 142 path: "v1/traces" 143 timeout: 10s 144 headers: 145 - name: "some-header" 146 value: "some-value" 147 - name: test-otel-res-detectors 148 opentelemetry: 149 service: opentelemetry-collector.istio-system.svc.cluster.local 150 port: 4317 151 resource_detectors: 152 environment: {} 153 dynatrace: {} 154 ` 155 } 156 157 func testSetup(ctx resource.Context) (err error) { 158 addrs, _ := tracing.GetIngressInstance().HTTPAddresses() 159 _, err = opentelemetry.New(ctx, opentelemetry.Config{IngressAddr: addrs[0]}) 160 return 161 }