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  }