istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/tracing_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package core
    16  
    17  import (
    18  	"testing"
    19  
    20  	core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
    21  	tracingcfg "github.com/envoyproxy/go-control-plane/envoy/config/trace/v3"
    22  	hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
    23  	resourcedetectors "github.com/envoyproxy/go-control-plane/envoy/extensions/tracers/opentelemetry/resource_detectors/v3"
    24  	otelsamplers "github.com/envoyproxy/go-control-plane/envoy/extensions/tracers/opentelemetry/samplers/v3"
    25  	tracing "github.com/envoyproxy/go-control-plane/envoy/type/tracing/v3"
    26  	xdstype "github.com/envoyproxy/go-control-plane/envoy/type/v3"
    27  	"github.com/google/go-cmp/cmp"
    28  	"google.golang.org/protobuf/testing/protocmp"
    29  	"google.golang.org/protobuf/types/known/durationpb"
    30  	"google.golang.org/protobuf/types/known/wrapperspb"
    31  
    32  	meshconfig "istio.io/api/mesh/v1alpha1"
    33  	tpb "istio.io/api/telemetry/v1alpha1"
    34  	"istio.io/istio/pilot/pkg/model"
    35  	"istio.io/istio/pilot/pkg/util/protoconv"
    36  	"istio.io/istio/pilot/pkg/xds/requestidextension"
    37  	"istio.io/istio/pkg/ptr"
    38  	"istio.io/istio/pkg/slices"
    39  	"istio.io/istio/pkg/test/util/assert"
    40  )
    41  
    42  func TestConfigureTracingExhaustiveness(t *testing.T) {
    43  	model.AssertProvidersHandled(configureFromProviderConfigHandled)
    44  }
    45  
    46  func TestConfigureTracing(t *testing.T) {
    47  	clusterName := "testcluster"
    48  	authority := "testhost"
    49  
    50  	clusterLookupFn = func(push *model.PushContext, service string, port int) (hostname string, cluster string, err error) {
    51  		return authority, clusterName, nil
    52  	}
    53  	defer func() {
    54  		clusterLookupFn = model.LookupCluster
    55  	}()
    56  
    57  	defaultUUIDExtensionCtx := requestidextension.UUIDRequestIDExtensionContext{
    58  		UseRequestIDForTraceSampling: true,
    59  	}
    60  
    61  	testcases := []struct {
    62  		name            string
    63  		opts            gatewayListenerOpts
    64  		inSpec          *model.TracingConfig
    65  		want            *hcm.HttpConnectionManager_Tracing
    66  		wantReqIDExtCtx *requestidextension.UUIDRequestIDExtensionContext
    67  	}{
    68  		{
    69  			name:            "no telemetry api",
    70  			opts:            fakeOptsNoTelemetryAPI(),
    71  			want:            fakeTracingConfigNoProvider(55.55, 13, append(defaultTracingTags(), fakeEnvTag)),
    72  			wantReqIDExtCtx: nil,
    73  		},
    74  		{
    75  			name: "default providers",
    76  			inSpec: &model.TracingConfig{
    77  				ClientSpec: model.TracingSpec{
    78  					Disabled: true,
    79  				},
    80  				ServerSpec: model.TracingSpec{
    81  					Provider: fakeZipkin(),
    82  				},
    83  			},
    84  			opts:            fakeOptsWithDefaultProviders(),
    85  			want:            fakeTracingConfig(fakeZipkinProvider(clusterName, authority, true), 55.5, 256, defaultTracingTags()),
    86  			wantReqIDExtCtx: &requestidextension.UUIDRequestIDExtensionContext{},
    87  		},
    88  		{
    89  			name:            "no telemetry api and nil custom tag",
    90  			opts:            fakeOptsNoTelemetryAPIWithNilCustomTag(),
    91  			want:            fakeTracingConfigNoProvider(55.55, 13, defaultTracingTags()),
    92  			wantReqIDExtCtx: nil,
    93  		},
    94  		{
    95  			name:            "only telemetry api (no provider)",
    96  			inSpec:          fakeTracingSpecNoProvider(99.999, false, true),
    97  			opts:            fakeOptsOnlyZipkinTelemetryAPI(),
    98  			want:            fakeTracingConfigNoProvider(99.999, 0, append(defaultTracingTags(), fakeEnvTag)),
    99  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   100  		},
   101  		{
   102  			name:   "only telemetry api (no provider) with nil custom tag",
   103  			inSpec: fakeTracingSpecNoProviderWithNilCustomTag(99.999, false, true),
   104  			opts:   fakeOptsOnlyZipkinTelemetryAPI(),
   105  			want:   fakeTracingConfigNoProvider(99.999, 0, defaultTracingTags()),
   106  
   107  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   108  		},
   109  		{
   110  			name:            "only telemetry api (with provider)",
   111  			inSpec:          fakeTracingSpec(fakeZipkin(), 99.999, false, true),
   112  			opts:            fakeOptsOnlyZipkinTelemetryAPI(),
   113  			want:            fakeTracingConfig(fakeZipkinProvider(clusterName, authority, true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   114  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   115  		},
   116  		{
   117  			name:            "zipkin enable 64bit trace id",
   118  			inSpec:          fakeTracingSpec(fakeZipkinEnable64bitTraceID(), 99.999, false, true),
   119  			opts:            fakeOptsOnlyZipkinTelemetryAPI(),
   120  			want:            fakeTracingConfig(fakeZipkinProvider(clusterName, authority, false), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   121  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   122  		},
   123  		{
   124  			name:            "both tracing enabled (no provider)",
   125  			inSpec:          fakeTracingSpecNoProvider(99.999, false, true),
   126  			opts:            fakeOptsMeshAndTelemetryAPI(true /* enable tracing */),
   127  			want:            fakeTracingConfigNoProvider(99.999, 13, append(defaultTracingTags(), fakeEnvTag)),
   128  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   129  		},
   130  		{
   131  			name:            "both tracing disabled (no provider)",
   132  			inSpec:          fakeTracingSpecNoProvider(99.999, false, true),
   133  			opts:            fakeOptsMeshAndTelemetryAPI(false /* no enable tracing */),
   134  			want:            fakeTracingConfigNoProvider(99.999, 13, append(defaultTracingTags(), fakeEnvTag)),
   135  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   136  		},
   137  		{
   138  			name:            "both tracing enabled (with provider)",
   139  			inSpec:          fakeTracingSpec(fakeZipkin(), 99.999, false, true),
   140  			opts:            fakeOptsMeshAndTelemetryAPI(true /* enable tracing */),
   141  			want:            fakeTracingConfig(fakeZipkinProvider(clusterName, authority, true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   142  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   143  		},
   144  		{
   145  			name:   "both tracing disabled (with provider)",
   146  			inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true),
   147  			opts:   fakeOptsMeshAndTelemetryAPI(false /* no enable tracing */),
   148  			want:   fakeTracingConfig(fakeZipkinProvider(clusterName, authority, true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   149  
   150  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   151  		},
   152  		{
   153  			name:   "basic config (with datadog provider)",
   154  			inSpec: fakeTracingSpec(fakeDatadog(), 99.999, false, true),
   155  			opts:   fakeOptsOnlyDatadogTelemetryAPI(),
   156  			want:   fakeTracingConfig(fakeDatadogProvider("fake-cluster", "testhost", clusterName), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   157  
   158  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   159  		},
   160  		{
   161  			name:            "basic config (with skywalking provider)",
   162  			inSpec:          fakeTracingSpec(fakeSkywalking(), 99.999, false, false),
   163  			opts:            fakeOptsOnlySkywalkingTelemetryAPI(),
   164  			want:            fakeTracingConfigForSkywalking(fakeSkywalkingProvider(clusterName, authority), 99.999, 0, append(defaultTracingTags(), fakeEnvTag)),
   165  			wantReqIDExtCtx: &requestidextension.UUIDRequestIDExtensionContext{UseRequestIDForTraceSampling: false},
   166  		},
   167  		{
   168  			name:   "basic config (with opentelemetry provider via grpc)",
   169  			inSpec: fakeTracingSpec(fakeOpenTelemetryGrpc(), 99.999, false, true),
   170  			opts:   fakeOptsOnlyOpenTelemetryGrpcTelemetryAPI(),
   171  			want:   fakeTracingConfig(fakeOpenTelemetryGrpcProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   172  
   173  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   174  		},
   175  		{
   176  			name:            "basic config (with opentelemetry provider via http)",
   177  			inSpec:          fakeTracingSpec(fakeOpenTelemetryHTTP(), 99.999, false, true),
   178  			opts:            fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI(),
   179  			want:            fakeTracingConfig(fakeOpenTelemetryHTTPProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   180  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   181  		},
   182  		{
   183  			name:   "basic config (with opentelemetry provider with resource detectors)",
   184  			inSpec: fakeTracingSpec(fakeOpenTelemetryResourceDetectors(), 99.999, false, true),
   185  			opts:   fakeOptsOnlyOpenTelemetryResourceDetectorsTelemetryAPI(),
   186  			want: fakeTracingConfig(
   187  				fakeOpenTelemetryResourceDetectorsProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)),
   188  
   189  			wantReqIDExtCtx: &defaultUUIDExtensionCtx,
   190  		},
   191  		{
   192  			name:            "client-only config for server",
   193  			inSpec:          fakeClientOnlyTracingSpec(fakeSkywalking(), 99.999, false, false),
   194  			opts:            fakeInboundOptsOnlySkywalkingTelemetryAPI(),
   195  			want:            nil,
   196  			wantReqIDExtCtx: nil,
   197  		},
   198  		{
   199  			name:            "server-only config for skywalking server",
   200  			inSpec:          fakeServerOnlyTracingSpec(fakeSkywalking(), 99.999, false, false),
   201  			opts:            fakeInboundOptsOnlySkywalkingTelemetryAPI(),
   202  			want:            fakeTracingConfigForSkywalking(fakeSkywalkingProvider(clusterName, authority), 99.999, 0, append(defaultTracingTags(), fakeEnvTag)),
   203  			wantReqIDExtCtx: &requestidextension.UUIDRequestIDExtensionContext{UseRequestIDForTraceSampling: false},
   204  		},
   205  		{
   206  			name:            "invalid provider",
   207  			inSpec:          fakeTracingSpec(fakePrometheus(), 99.999, false, true),
   208  			opts:            fakeOptsMeshAndTelemetryAPI(true /* enable tracing */),
   209  			want:            nil,
   210  			wantReqIDExtCtx: nil,
   211  		},
   212  	}
   213  
   214  	for _, tc := range testcases {
   215  		t.Run(tc.name, func(t *testing.T) {
   216  			hcm := &hcm.HttpConnectionManager{}
   217  			gotReqIDExtCtx := configureTracingFromTelemetry(tc.inSpec, tc.opts.push, tc.opts.proxy, hcm, 0)
   218  			if diff := cmp.Diff(tc.want, hcm.Tracing, protocmp.Transform()); diff != "" {
   219  				t.Fatalf("configureTracing returned unexpected diff (-want +got):\n%s", diff)
   220  			}
   221  			assert.Equal(t, tc.want, hcm.Tracing)
   222  			assert.Equal(t, tc.wantReqIDExtCtx, gotReqIDExtCtx)
   223  		})
   224  	}
   225  }
   226  
   227  func TestConfigureDynatraceSampler(t *testing.T) {
   228  	clusterName := "testcluster"
   229  	authority := "testhost"
   230  	dtTenant := "abc"
   231  	var dtClusterID int32 = 123
   232  	clusterLookupFn = func(push *model.PushContext, service string, port int) (hostname string, cluster string, err error) {
   233  		return authority, clusterName, nil
   234  	}
   235  	defer func() {
   236  		clusterLookupFn = model.LookupCluster
   237  	}()
   238  
   239  	testcases := []struct {
   240  		name        string
   241  		dtTenant    string
   242  		dtClusterID int32
   243  		spansPerMin uint32
   244  		expectedURI string
   245  	}{
   246  		{
   247  			name:        "re-use otlp http headers",
   248  			dtTenant:    dtTenant,
   249  			dtClusterID: dtClusterID,
   250  			expectedURI: authority + "/api/v2/samplingConfiguration",
   251  		},
   252  		{
   253  			name:        "custom root spans per minute fallback",
   254  			dtTenant:    dtTenant,
   255  			dtClusterID: dtClusterID,
   256  			expectedURI: authority + "/api/v2/samplingConfiguration",
   257  			spansPerMin: 9999,
   258  		},
   259  	}
   260  
   261  	for _, tc := range testcases {
   262  		t.Run(tc.name, func(t *testing.T) {
   263  			httpProvider := fakeOpenTelemetryHTTP()
   264  			httpProvider.GetOpentelemetry().Sampling = &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler_{
   265  				DynatraceSampler: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler{
   266  					Tenant:             tc.dtTenant,
   267  					ClusterId:          tc.dtClusterID,
   268  					RootSpansPerMinute: tc.spansPerMin,
   269  				},
   270  			}
   271  
   272  			// Use a different value for RandomSamplingPercentage to ensure it is changed to 100%
   273  			// when a custom sampler is used for the OTel tracing provider
   274  			inSpec := &model.TracingConfig{
   275  				ClientSpec: tracingSpec(httpProvider, 50, false, false),
   276  				ServerSpec: tracingSpec(httpProvider, 50, false, false),
   277  			}
   278  
   279  			opts := fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI()
   280  			ep := opts.push.Mesh.ExtensionProviders[0]
   281  			ep.GetOpentelemetry().Sampling = &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler_{
   282  				DynatraceSampler: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler{
   283  					Tenant:             tc.dtTenant,
   284  					ClusterId:          tc.dtClusterID,
   285  					RootSpansPerMinute: tc.spansPerMin,
   286  				},
   287  			}
   288  
   289  			// Envoy expected config
   290  			fakeOTelHTTPProviderConfig := &tracingcfg.OpenTelemetryConfig{
   291  				HttpService: &core.HttpService{
   292  					HttpUri: &core.HttpUri{
   293  						Uri: authority + "/v1/traces",
   294  						HttpUpstreamType: &core.HttpUri_Cluster{
   295  							Cluster: clusterName,
   296  						},
   297  						Timeout: &durationpb.Duration{Seconds: 3},
   298  					},
   299  					RequestHeadersToAdd: []*core.HeaderValueOption{
   300  						{
   301  							Header: &core.HeaderValue{
   302  								Key:   "custom-header",
   303  								Value: "custom-value",
   304  							},
   305  							AppendAction: core.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
   306  						},
   307  					},
   308  				},
   309  				Sampler: &core.TypedExtensionConfig{
   310  					Name: "envoy.tracers.opentelemetry.samplers.dynatrace",
   311  					TypedConfig: protoconv.MessageToAny(&otelsamplers.DynatraceSamplerConfig{
   312  						Tenant:             tc.dtTenant,
   313  						ClusterId:          tc.dtClusterID,
   314  						RootSpansPerMinute: tc.spansPerMin,
   315  						HttpService: &core.HttpService{
   316  							HttpUri: &core.HttpUri{
   317  								Uri: tc.expectedURI,
   318  								HttpUpstreamType: &core.HttpUri_Cluster{
   319  									Cluster: clusterName,
   320  								},
   321  								Timeout: &durationpb.Duration{Seconds: 3},
   322  							},
   323  							RequestHeadersToAdd: []*core.HeaderValueOption{
   324  								{
   325  									Header: &core.HeaderValue{
   326  										Key:   "custom-header",
   327  										Value: "custom-value",
   328  									},
   329  									AppendAction: core.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
   330  								},
   331  							},
   332  						},
   333  					}),
   334  				},
   335  			}
   336  
   337  			fakeOtelHTTPAny := &tracingcfg.Tracing_Http{
   338  				Name:       envoyOpenTelemetry,
   339  				ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: protoconv.MessageToAny(fakeOTelHTTPProviderConfig)},
   340  			}
   341  			want := fakeTracingConfig(fakeOtelHTTPAny, 100, 256, append(defaultTracingTags(), fakeEnvTag))
   342  
   343  			hcm := &hcm.HttpConnectionManager{}
   344  			configureTracingFromTelemetry(inSpec, opts.push, opts.proxy, hcm, 0)
   345  
   346  			if diff := cmp.Diff(want, hcm.Tracing, protocmp.Transform()); diff != "" {
   347  				t.Fatalf("configureTracing returned unexpected diff (-want +got):\n%s", diff)
   348  			}
   349  			assert.Equal(t, want, hcm.Tracing)
   350  		})
   351  	}
   352  }
   353  
   354  func TestConfigureDynatraceSamplerWithCustomHttp(t *testing.T) {
   355  	clusterName := "testcluster"
   356  	authority := "testhost"
   357  
   358  	dtClusterName := "dtcluster"
   359  	dtAuthority := "dthost"
   360  	expectedTenant := "abc"
   361  	var expectedClusterID int32 = 123
   362  	expectedHeader := "sampler-custom"
   363  	expectedToken := "sampler-value"
   364  
   365  	clusterLookupFn = func(push *model.PushContext, service string, port int) (hostname string, cluster string, err error) {
   366  		if service == dtAuthority {
   367  			return dtAuthority, dtClusterName, nil
   368  		}
   369  		return authority, clusterName, nil
   370  	}
   371  	defer func() {
   372  		clusterLookupFn = model.LookupCluster
   373  	}()
   374  
   375  	httpProvider := fakeOpenTelemetryHTTP()
   376  	httpProvider.GetOpentelemetry().Sampling = &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler_{
   377  		DynatraceSampler: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler{
   378  			Tenant:             expectedTenant,
   379  			ClusterId:          expectedClusterID,
   380  			RootSpansPerMinute: 2000,
   381  			HttpService: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler_DynatraceApi{
   382  				Service: dtAuthority,
   383  				Port:    123,
   384  				Http: &meshconfig.MeshConfig_ExtensionProvider_HttpService{
   385  					Path:    "api/v2/samplingConfiguration",
   386  					Timeout: &durationpb.Duration{Seconds: 3},
   387  					Headers: []*meshconfig.MeshConfig_ExtensionProvider_HttpHeader{
   388  						{
   389  							Name:  expectedHeader,
   390  							Value: expectedToken,
   391  						},
   392  					},
   393  				},
   394  			},
   395  		},
   396  	}
   397  
   398  	// Use a different value for RandomSamplingPercentage to ensure it is changed to 100%
   399  	// when a custom sampler is used for the OTel tracing provider
   400  	inSpec := &model.TracingConfig{
   401  		ClientSpec: tracingSpec(httpProvider, 50, false, false),
   402  		ServerSpec: tracingSpec(httpProvider, 50, false, false),
   403  	}
   404  
   405  	opts := fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI()
   406  	ep := opts.push.Mesh.ExtensionProviders[0]
   407  	ep.GetOpentelemetry().Sampling = &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler_{
   408  		DynatraceSampler: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler{
   409  			Tenant:             expectedTenant,
   410  			ClusterId:          expectedClusterID,
   411  			RootSpansPerMinute: 2000,
   412  			HttpService: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider_DynatraceSampler_DynatraceApi{
   413  				Service: dtAuthority,
   414  				Port:    123,
   415  				Http: &meshconfig.MeshConfig_ExtensionProvider_HttpService{
   416  					Path:    "api/v2/samplingConfiguration",
   417  					Timeout: &durationpb.Duration{Seconds: 3},
   418  					Headers: []*meshconfig.MeshConfig_ExtensionProvider_HttpHeader{
   419  						{
   420  							Name:  expectedHeader,
   421  							Value: expectedToken,
   422  						},
   423  					},
   424  				},
   425  			},
   426  		},
   427  	}
   428  
   429  	// Envoy expected config
   430  	fakeOTelHTTPProviderConfig := &tracingcfg.OpenTelemetryConfig{
   431  		HttpService: &core.HttpService{
   432  			HttpUri: &core.HttpUri{
   433  				Uri: authority + "/v1/traces",
   434  				HttpUpstreamType: &core.HttpUri_Cluster{
   435  					Cluster: clusterName,
   436  				},
   437  				Timeout: &durationpb.Duration{Seconds: 3},
   438  			},
   439  			RequestHeadersToAdd: []*core.HeaderValueOption{
   440  				{
   441  					Header: &core.HeaderValue{
   442  						Key:   "custom-header",
   443  						Value: "custom-value",
   444  					},
   445  					AppendAction: core.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
   446  				},
   447  			},
   448  		},
   449  		Sampler: &core.TypedExtensionConfig{
   450  			Name: "envoy.tracers.opentelemetry.samplers.dynatrace",
   451  			TypedConfig: protoconv.MessageToAny(&otelsamplers.DynatraceSamplerConfig{
   452  				Tenant:             expectedTenant,
   453  				ClusterId:          expectedClusterID,
   454  				RootSpansPerMinute: 2000,
   455  				HttpService: &core.HttpService{
   456  					HttpUri: &core.HttpUri{
   457  						Uri: dtAuthority + "/api/v2/samplingConfiguration",
   458  						HttpUpstreamType: &core.HttpUri_Cluster{
   459  							Cluster: dtClusterName,
   460  						},
   461  						Timeout: &durationpb.Duration{Seconds: 3},
   462  					},
   463  					RequestHeadersToAdd: []*core.HeaderValueOption{
   464  						{
   465  							Header: &core.HeaderValue{
   466  								Key:   expectedHeader,
   467  								Value: expectedToken,
   468  							},
   469  							AppendAction: core.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
   470  						},
   471  					},
   472  				},
   473  			}),
   474  		},
   475  	}
   476  
   477  	fakeOtelHTTPAny := &tracingcfg.Tracing_Http{
   478  		Name:       envoyOpenTelemetry,
   479  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: protoconv.MessageToAny(fakeOTelHTTPProviderConfig)},
   480  	}
   481  	want := fakeTracingConfig(fakeOtelHTTPAny, 100, 256, append(defaultTracingTags(), fakeEnvTag))
   482  
   483  	hcm := &hcm.HttpConnectionManager{}
   484  	configureTracingFromTelemetry(inSpec, opts.push, opts.proxy, hcm, 0)
   485  
   486  	if diff := cmp.Diff(want, hcm.Tracing, protocmp.Transform()); diff != "" {
   487  		t.Fatalf("configureTracing returned unexpected diff (-want +got):\n%s", diff)
   488  	}
   489  	assert.Equal(t, want, hcm.Tracing)
   490  }
   491  
   492  func defaultTracingTags() []*tracing.CustomTag {
   493  	return append(slices.Clone(optionalPolicyTags),
   494  		&tracing.CustomTag{
   495  			Tag: "istio.canonical_revision",
   496  			Type: &tracing.CustomTag_Literal_{
   497  				Literal: &tracing.CustomTag_Literal{
   498  					Value: "latest",
   499  				},
   500  			},
   501  		},
   502  		&tracing.CustomTag{
   503  			Tag: "istio.canonical_service",
   504  			Type: &tracing.CustomTag_Literal_{
   505  				Literal: &tracing.CustomTag_Literal{
   506  					Value: "unknown",
   507  				},
   508  			},
   509  		},
   510  		&tracing.CustomTag{
   511  			Tag: "istio.cluster_id",
   512  			Type: &tracing.CustomTag_Literal_{
   513  				Literal: &tracing.CustomTag_Literal{
   514  					Value: "unknown",
   515  				},
   516  			},
   517  		},
   518  		&tracing.CustomTag{
   519  			Tag: "istio.mesh_id",
   520  			Type: &tracing.CustomTag_Literal_{
   521  				Literal: &tracing.CustomTag_Literal{
   522  					Value: "unknown",
   523  				},
   524  			},
   525  		},
   526  		&tracing.CustomTag{
   527  			Tag: "istio.namespace",
   528  			Type: &tracing.CustomTag_Literal_{
   529  				Literal: &tracing.CustomTag_Literal{
   530  					Value: "default",
   531  				},
   532  			},
   533  		})
   534  }
   535  
   536  func fakeOptsWithDefaultProviders() gatewayListenerOpts {
   537  	var opts gatewayListenerOpts
   538  	opts.push = &model.PushContext{
   539  		Mesh: &meshconfig.MeshConfig{
   540  			EnableTracing: true,
   541  			DefaultConfig: &meshconfig.ProxyConfig{
   542  				Tracing: &meshconfig.Tracing{
   543  					Sampling: 55.5,
   544  				},
   545  			},
   546  			DefaultProviders: &meshconfig.MeshConfig_DefaultProviders{
   547  				Tracing: []string{
   548  					"foo",
   549  				},
   550  			},
   551  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   552  				{
   553  					Name: "foo",
   554  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Zipkin{
   555  						Zipkin: &meshconfig.MeshConfig_ExtensionProvider_ZipkinTracingProvider{
   556  							Service:      "zipkin",
   557  							Port:         9411,
   558  							MaxTagLength: 256,
   559  						},
   560  					},
   561  				},
   562  			},
   563  		},
   564  	}
   565  	opts.proxy = &model.Proxy{
   566  		Metadata: &model.NodeMetadata{},
   567  	}
   568  
   569  	return opts
   570  }
   571  
   572  func fakeOptsNoTelemetryAPI() gatewayListenerOpts {
   573  	var opts gatewayListenerOpts
   574  	opts.push = &model.PushContext{
   575  		Mesh: &meshconfig.MeshConfig{
   576  			EnableTracing: true,
   577  		},
   578  	}
   579  	opts.proxy = &model.Proxy{
   580  		Metadata: &model.NodeMetadata{
   581  			ProxyConfig: &model.NodeMetaProxyConfig{
   582  				Tracing: &meshconfig.Tracing{
   583  					Sampling:         55.55,
   584  					MaxPathTagLength: 13,
   585  					CustomTags: map[string]*meshconfig.Tracing_CustomTag{
   586  						"test": {
   587  							Type: &meshconfig.Tracing_CustomTag_Environment{
   588  								Environment: &meshconfig.Tracing_Environment{
   589  									Name: "FOO",
   590  								},
   591  							},
   592  						},
   593  					},
   594  				},
   595  			},
   596  		},
   597  	}
   598  
   599  	return opts
   600  }
   601  
   602  func fakeOptsNoTelemetryAPIWithNilCustomTag() gatewayListenerOpts {
   603  	var opts gatewayListenerOpts
   604  	opts.push = &model.PushContext{
   605  		Mesh: &meshconfig.MeshConfig{
   606  			EnableTracing: true,
   607  		},
   608  	}
   609  	opts.proxy = &model.Proxy{
   610  		Metadata: &model.NodeMetadata{
   611  			ProxyConfig: &model.NodeMetaProxyConfig{
   612  				Tracing: &meshconfig.Tracing{
   613  					Sampling:         55.55,
   614  					MaxPathTagLength: 13,
   615  					CustomTags: map[string]*meshconfig.Tracing_CustomTag{
   616  						"test": nil,
   617  					},
   618  				},
   619  			},
   620  		},
   621  	}
   622  
   623  	return opts
   624  }
   625  
   626  func fakeOptsOnlyZipkinTelemetryAPI() gatewayListenerOpts {
   627  	var opts gatewayListenerOpts
   628  	opts.push = &model.PushContext{
   629  		Mesh: &meshconfig.MeshConfig{
   630  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   631  				{
   632  					Name: "foo",
   633  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Zipkin{
   634  						Zipkin: &meshconfig.MeshConfig_ExtensionProvider_ZipkinTracingProvider{
   635  							Service:      "zipkin",
   636  							Port:         9411,
   637  							MaxTagLength: 256,
   638  						},
   639  					},
   640  				},
   641  			},
   642  		},
   643  	}
   644  	opts.proxy = &model.Proxy{
   645  		Metadata: &model.NodeMetadata{
   646  			ProxyConfig: &model.NodeMetaProxyConfig{},
   647  		},
   648  	}
   649  
   650  	return opts
   651  }
   652  
   653  func fakeZipkin() *meshconfig.MeshConfig_ExtensionProvider {
   654  	return &meshconfig.MeshConfig_ExtensionProvider{
   655  		Name: "foo",
   656  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Zipkin{
   657  			Zipkin: &meshconfig.MeshConfig_ExtensionProvider_ZipkinTracingProvider{
   658  				Service:      "zipkin",
   659  				Port:         9411,
   660  				MaxTagLength: 256,
   661  			},
   662  		},
   663  	}
   664  }
   665  
   666  func fakePrometheus() *meshconfig.MeshConfig_ExtensionProvider {
   667  	return &meshconfig.MeshConfig_ExtensionProvider{
   668  		Name:     "foo",
   669  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Prometheus{},
   670  	}
   671  }
   672  
   673  func fakeZipkinEnable64bitTraceID() *meshconfig.MeshConfig_ExtensionProvider {
   674  	return &meshconfig.MeshConfig_ExtensionProvider{
   675  		Name: "foo",
   676  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Zipkin{
   677  			Zipkin: &meshconfig.MeshConfig_ExtensionProvider_ZipkinTracingProvider{
   678  				Service:             "zipkin",
   679  				Port:                9411,
   680  				MaxTagLength:        256,
   681  				Enable_64BitTraceId: true,
   682  			},
   683  		},
   684  	}
   685  }
   686  
   687  func fakeDatadog() *meshconfig.MeshConfig_ExtensionProvider {
   688  	return &meshconfig.MeshConfig_ExtensionProvider{
   689  		Name: "datadog",
   690  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Datadog{
   691  			Datadog: &meshconfig.MeshConfig_ExtensionProvider_DatadogTracingProvider{
   692  				Service:      "datadog",
   693  				Port:         8126,
   694  				MaxTagLength: 256,
   695  			},
   696  		},
   697  	}
   698  }
   699  
   700  func fakeOptsOnlyDatadogTelemetryAPI() gatewayListenerOpts {
   701  	var opts gatewayListenerOpts
   702  	opts.push = &model.PushContext{
   703  		Mesh: &meshconfig.MeshConfig{
   704  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   705  				{
   706  					Name: "datadog",
   707  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Datadog{
   708  						Datadog: &meshconfig.MeshConfig_ExtensionProvider_DatadogTracingProvider{
   709  							Service:      "datadog",
   710  							Port:         8126,
   711  							MaxTagLength: 256,
   712  						},
   713  					},
   714  				},
   715  			},
   716  		},
   717  	}
   718  	opts.proxy = &model.Proxy{
   719  		Metadata: &model.NodeMetadata{
   720  			ProxyConfig: &model.NodeMetaProxyConfig{},
   721  		},
   722  		XdsNode: &core.Node{
   723  			Cluster: "fake-cluster",
   724  		},
   725  	}
   726  
   727  	return opts
   728  }
   729  
   730  func fakeOptsMeshAndTelemetryAPI(enableTracing bool) gatewayListenerOpts {
   731  	var opts gatewayListenerOpts
   732  	opts.push = &model.PushContext{
   733  		Mesh: &meshconfig.MeshConfig{
   734  			EnableTracing: enableTracing,
   735  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   736  				{
   737  					Name: "foo",
   738  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Zipkin{
   739  						Zipkin: &meshconfig.MeshConfig_ExtensionProvider_ZipkinTracingProvider{
   740  							Service:      "zipkin",
   741  							Port:         9411,
   742  							MaxTagLength: 256,
   743  						},
   744  					},
   745  				},
   746  			},
   747  		},
   748  	}
   749  	opts.proxy = &model.Proxy{
   750  		Metadata: &model.NodeMetadata{
   751  			ProxyConfig: &model.NodeMetaProxyConfig{
   752  				Tracing: &meshconfig.Tracing{
   753  					Sampling:         55.55,
   754  					MaxPathTagLength: 13,
   755  					CustomTags: map[string]*meshconfig.Tracing_CustomTag{
   756  						"test": {
   757  							Type: &meshconfig.Tracing_CustomTag_Environment{
   758  								Environment: &meshconfig.Tracing_Environment{
   759  									Name: "FOO",
   760  								},
   761  							},
   762  						},
   763  					},
   764  				},
   765  			},
   766  		},
   767  	}
   768  
   769  	return opts
   770  }
   771  
   772  func fakeSkywalking() *meshconfig.MeshConfig_ExtensionProvider {
   773  	return &meshconfig.MeshConfig_ExtensionProvider{
   774  		Name: "foo",
   775  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Skywalking{
   776  			Skywalking: &meshconfig.MeshConfig_ExtensionProvider_SkyWalkingTracingProvider{
   777  				Service: "skywalking-oap.istio-system.svc.cluster.local",
   778  				Port:    11800,
   779  			},
   780  		},
   781  	}
   782  }
   783  
   784  func fakeOptsOnlySkywalkingTelemetryAPI() gatewayListenerOpts {
   785  	var opts gatewayListenerOpts
   786  	opts.push = &model.PushContext{
   787  		Mesh: &meshconfig.MeshConfig{
   788  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   789  				{
   790  					Name: "foo",
   791  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Skywalking{
   792  						Skywalking: &meshconfig.MeshConfig_ExtensionProvider_SkyWalkingTracingProvider{
   793  							Service: "skywalking-oap.istio-system.svc.cluster.local",
   794  							Port:    11800,
   795  						},
   796  					},
   797  				},
   798  			},
   799  		},
   800  	}
   801  	opts.proxy = &model.Proxy{
   802  		Metadata: &model.NodeMetadata{
   803  			ProxyConfig: &model.NodeMetaProxyConfig{},
   804  		},
   805  	}
   806  
   807  	return opts
   808  }
   809  
   810  func fakeOpenTelemetryGrpc() *meshconfig.MeshConfig_ExtensionProvider {
   811  	return &meshconfig.MeshConfig_ExtensionProvider{
   812  		Name: "opentelemetry",
   813  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Opentelemetry{
   814  			Opentelemetry: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider{
   815  				Service:      "otel-collector",
   816  				Port:         4317,
   817  				MaxTagLength: 256,
   818  			},
   819  		},
   820  	}
   821  }
   822  
   823  func fakeOpenTelemetryHTTP() *meshconfig.MeshConfig_ExtensionProvider {
   824  	return &meshconfig.MeshConfig_ExtensionProvider{
   825  		Name: "opentelemetry",
   826  		Provider: &meshconfig.MeshConfig_ExtensionProvider_Opentelemetry{
   827  			Opentelemetry: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider{
   828  				Service:      "my-o11y-backend",
   829  				Port:         443,
   830  				MaxTagLength: 256,
   831  				Http: &meshconfig.MeshConfig_ExtensionProvider_HttpService{
   832  					Path:    "/v1/traces",
   833  					Timeout: &durationpb.Duration{Seconds: 3},
   834  					Headers: []*meshconfig.MeshConfig_ExtensionProvider_HttpHeader{
   835  						{
   836  							Name:  "custom-header",
   837  							Value: "custom-value",
   838  						},
   839  					},
   840  				},
   841  			},
   842  		},
   843  	}
   844  }
   845  
   846  func fakeOpenTelemetryResourceDetectors() *meshconfig.MeshConfig_ExtensionProvider {
   847  	ep := fakeOpenTelemetryHTTP()
   848  
   849  	ep.GetOpentelemetry().ResourceDetectors = &meshconfig.MeshConfig_ExtensionProvider_ResourceDetectors{
   850  		Environment: &meshconfig.MeshConfig_ExtensionProvider_ResourceDetectors_EnvironmentResourceDetector{},
   851  		Dynatrace:   &meshconfig.MeshConfig_ExtensionProvider_ResourceDetectors_DynatraceResourceDetector{},
   852  	}
   853  
   854  	return ep
   855  }
   856  
   857  func fakeOptsOnlyOpenTelemetryGrpcTelemetryAPI() gatewayListenerOpts {
   858  	var opts gatewayListenerOpts
   859  	opts.push = &model.PushContext{
   860  		Mesh: &meshconfig.MeshConfig{
   861  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   862  				{
   863  					Name: "opentelemetry",
   864  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Opentelemetry{
   865  						Opentelemetry: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider{
   866  							Service:      "otel-collector",
   867  							Port:         4317,
   868  							MaxTagLength: 256,
   869  						},
   870  					},
   871  				},
   872  			},
   873  		},
   874  	}
   875  	opts.proxy = &model.Proxy{
   876  		Metadata: &model.NodeMetadata{
   877  			ProxyConfig: &model.NodeMetaProxyConfig{},
   878  		},
   879  	}
   880  
   881  	return opts
   882  }
   883  
   884  func fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI() gatewayListenerOpts {
   885  	var opts gatewayListenerOpts
   886  	opts.push = &model.PushContext{
   887  		Mesh: &meshconfig.MeshConfig{
   888  			ExtensionProviders: []*meshconfig.MeshConfig_ExtensionProvider{
   889  				{
   890  					Name: "opentelemetry",
   891  					Provider: &meshconfig.MeshConfig_ExtensionProvider_Opentelemetry{
   892  						Opentelemetry: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider{
   893  							Service:      "otel-collector",
   894  							Port:         4317,
   895  							MaxTagLength: 256,
   896  							Http: &meshconfig.MeshConfig_ExtensionProvider_HttpService{
   897  								Path:    "/v1/traces",
   898  								Timeout: &durationpb.Duration{Seconds: 3},
   899  								Headers: []*meshconfig.MeshConfig_ExtensionProvider_HttpHeader{
   900  									{
   901  										Name:  "custom-header",
   902  										Value: "custom-value",
   903  									},
   904  								},
   905  							},
   906  						},
   907  					},
   908  				},
   909  			},
   910  		},
   911  	}
   912  	opts.proxy = &model.Proxy{
   913  		Metadata: &model.NodeMetadata{
   914  			ProxyConfig: &model.NodeMetaProxyConfig{},
   915  		},
   916  	}
   917  
   918  	return opts
   919  }
   920  
   921  func fakeOptsOnlyOpenTelemetryResourceDetectorsTelemetryAPI() gatewayListenerOpts {
   922  	opts := fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI()
   923  
   924  	ep := opts.push.Mesh.ExtensionProviders[0]
   925  	ep.GetOpentelemetry().ResourceDetectors = &meshconfig.MeshConfig_ExtensionProvider_ResourceDetectors{
   926  		Environment: &meshconfig.MeshConfig_ExtensionProvider_ResourceDetectors_EnvironmentResourceDetector{},
   927  		Dynatrace:   &meshconfig.MeshConfig_ExtensionProvider_ResourceDetectors_DynatraceResourceDetector{},
   928  	}
   929  
   930  	return opts
   931  }
   932  
   933  func fakeInboundOptsOnlySkywalkingTelemetryAPI() gatewayListenerOpts {
   934  	opts := fakeOptsOnlySkywalkingTelemetryAPI()
   935  	return opts
   936  }
   937  
   938  func fakeTracingSpecNoProvider(sampling float64, disableReporting bool, useRequestIDForTraceSampling bool) *model.TracingConfig {
   939  	return fakeTracingSpec(nil, sampling, disableReporting, useRequestIDForTraceSampling)
   940  }
   941  
   942  func fakeTracingSpecNoProviderWithNilCustomTag(sampling float64, disableReporting bool, useRequestIDForTraceSampling bool) *model.TracingConfig {
   943  	return fakeTracingSpecWithNilCustomTag(nil, sampling, disableReporting, useRequestIDForTraceSampling)
   944  }
   945  
   946  func fakeTracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool,
   947  	useRequestIDForTraceSampling bool,
   948  ) *model.TracingConfig {
   949  	t := &model.TracingConfig{
   950  		ClientSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling),
   951  		ServerSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling),
   952  	}
   953  	return t
   954  }
   955  
   956  func fakeClientOnlyTracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool,
   957  	useRequestIDForTraceSampling bool,
   958  ) *model.TracingConfig {
   959  	t := &model.TracingConfig{
   960  		ClientSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling),
   961  		ServerSpec: model.TracingSpec{
   962  			Disabled: true,
   963  		},
   964  	}
   965  	return t
   966  }
   967  
   968  func fakeServerOnlyTracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool,
   969  	useRequestIDForTraceSampling bool,
   970  ) *model.TracingConfig {
   971  	t := &model.TracingConfig{
   972  		ClientSpec: model.TracingSpec{
   973  			Disabled: true,
   974  		},
   975  		ServerSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling),
   976  	}
   977  	return t
   978  }
   979  
   980  func tracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool,
   981  	useRequestIDForTraceSampling bool,
   982  ) model.TracingSpec {
   983  	return model.TracingSpec{
   984  		Provider:                 provider,
   985  		Disabled:                 disableReporting,
   986  		RandomSamplingPercentage: ptr.Of(sampling),
   987  		CustomTags: map[string]*tpb.Tracing_CustomTag{
   988  			"test": {
   989  				Type: &tpb.Tracing_CustomTag_Environment{
   990  					Environment: &tpb.Tracing_Environment{
   991  						Name: "FOO",
   992  					},
   993  				},
   994  			},
   995  		},
   996  		UseRequestIDForTraceSampling: useRequestIDForTraceSampling,
   997  	}
   998  }
   999  
  1000  func fakeTracingSpecWithNilCustomTag(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool,
  1001  	useRequestIDForTraceSampling bool,
  1002  ) *model.TracingConfig {
  1003  	t := &model.TracingConfig{
  1004  		ClientSpec: model.TracingSpec{
  1005  			Provider:                 provider,
  1006  			Disabled:                 disableReporting,
  1007  			RandomSamplingPercentage: ptr.Of(sampling),
  1008  			CustomTags: map[string]*tpb.Tracing_CustomTag{
  1009  				"test": nil,
  1010  			},
  1011  			UseRequestIDForTraceSampling: useRequestIDForTraceSampling,
  1012  		},
  1013  		ServerSpec: model.TracingSpec{
  1014  			Provider:                 provider,
  1015  			Disabled:                 disableReporting,
  1016  			RandomSamplingPercentage: ptr.Of(sampling),
  1017  			CustomTags: map[string]*tpb.Tracing_CustomTag{
  1018  				"test": nil,
  1019  			},
  1020  			UseRequestIDForTraceSampling: useRequestIDForTraceSampling,
  1021  		},
  1022  	}
  1023  	return t
  1024  }
  1025  
  1026  func fakeTracingConfigNoProvider(randomSampling float64, maxLen uint32, tags []*tracing.CustomTag) *hcm.HttpConnectionManager_Tracing {
  1027  	return fakeTracingConfig(nil, randomSampling, maxLen, tags)
  1028  }
  1029  
  1030  func fakeTracingConfig(provider *tracingcfg.Tracing_Http, randomSampling float64, maxLen uint32, tags []*tracing.CustomTag) *hcm.HttpConnectionManager_Tracing {
  1031  	t := &hcm.HttpConnectionManager_Tracing{
  1032  		ClientSampling: &xdstype.Percent{
  1033  			Value: 100.0,
  1034  		},
  1035  		OverallSampling: &xdstype.Percent{
  1036  			Value: 100.0,
  1037  		},
  1038  		RandomSampling: &xdstype.Percent{
  1039  			Value: randomSampling,
  1040  		},
  1041  		CustomTags: tags,
  1042  	}
  1043  	if maxLen != 0 {
  1044  		t.MaxPathTagLength = wrapperspb.UInt32(maxLen)
  1045  	}
  1046  	if provider != nil {
  1047  		t.Provider = provider
  1048  	}
  1049  	return t
  1050  }
  1051  
  1052  // nolint: lll
  1053  func fakeTracingConfigForSkywalking(provider *tracingcfg.Tracing_Http, randomSampling float64, maxLen uint32, tags []*tracing.CustomTag) *hcm.HttpConnectionManager_Tracing {
  1054  	cfg := fakeTracingConfig(provider, randomSampling, maxLen, tags)
  1055  	cfg.SpawnUpstreamSpan = wrapperspb.Bool(true)
  1056  	return cfg
  1057  }
  1058  
  1059  var fakeEnvTag = &tracing.CustomTag{
  1060  	Tag: "test",
  1061  	Type: &tracing.CustomTag_Environment_{
  1062  		Environment: &tracing.CustomTag_Environment{
  1063  			Name: "FOO",
  1064  		},
  1065  	},
  1066  }
  1067  
  1068  func fakeZipkinProvider(expectClusterName, expectAuthority string, enableTraceID bool) *tracingcfg.Tracing_Http {
  1069  	fakeZipkinProviderConfig := &tracingcfg.ZipkinConfig{
  1070  		CollectorCluster:         expectClusterName,
  1071  		CollectorEndpoint:        "/api/v2/spans",
  1072  		CollectorEndpointVersion: tracingcfg.ZipkinConfig_HTTP_JSON,
  1073  		CollectorHostname:        expectAuthority,
  1074  		TraceId_128Bit:           enableTraceID,
  1075  		SharedSpanContext:        wrapperspb.Bool(false),
  1076  	}
  1077  	fakeZipkinAny := protoconv.MessageToAny(fakeZipkinProviderConfig)
  1078  	return &tracingcfg.Tracing_Http{
  1079  		Name:       envoyZipkin,
  1080  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: fakeZipkinAny},
  1081  	}
  1082  }
  1083  
  1084  func fakeSkywalkingProvider(expectClusterName, expectAuthority string) *tracingcfg.Tracing_Http {
  1085  	fakeSkywalkingProviderConfig := &tracingcfg.SkyWalkingConfig{
  1086  		GrpcService: &core.GrpcService{
  1087  			TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1088  				EnvoyGrpc: &core.GrpcService_EnvoyGrpc{
  1089  					ClusterName: expectClusterName,
  1090  					Authority:   expectAuthority,
  1091  				},
  1092  			},
  1093  		},
  1094  	}
  1095  	fakeSkywalkingAny := protoconv.MessageToAny(fakeSkywalkingProviderConfig)
  1096  	return &tracingcfg.Tracing_Http{
  1097  		Name:       envoySkywalking,
  1098  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: fakeSkywalkingAny},
  1099  	}
  1100  }
  1101  
  1102  func fakeDatadogProvider(expectServcieName, expectHostName, expectClusterName string) *tracingcfg.Tracing_Http {
  1103  	fakeDatadogProviderConfig := &tracingcfg.DatadogConfig{
  1104  		CollectorCluster:  expectClusterName,
  1105  		ServiceName:       expectServcieName,
  1106  		CollectorHostname: expectHostName,
  1107  	}
  1108  	fakeAny := protoconv.MessageToAny(fakeDatadogProviderConfig)
  1109  	return &tracingcfg.Tracing_Http{
  1110  		Name:       envoyDatadog,
  1111  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: fakeAny},
  1112  	}
  1113  }
  1114  
  1115  func fakeOpenTelemetryGrpcProvider(expectClusterName, expectAuthority string) *tracingcfg.Tracing_Http {
  1116  	fakeOTelGrpcProviderConfig := &tracingcfg.OpenTelemetryConfig{
  1117  		GrpcService: &core.GrpcService{
  1118  			TargetSpecifier: &core.GrpcService_EnvoyGrpc_{
  1119  				EnvoyGrpc: &core.GrpcService_EnvoyGrpc{
  1120  					ClusterName: expectClusterName,
  1121  					Authority:   expectAuthority,
  1122  				},
  1123  			},
  1124  		},
  1125  	}
  1126  	fakeOtelGrpcAny := protoconv.MessageToAny(fakeOTelGrpcProviderConfig)
  1127  	return &tracingcfg.Tracing_Http{
  1128  		Name:       envoyOpenTelemetry,
  1129  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: fakeOtelGrpcAny},
  1130  	}
  1131  }
  1132  
  1133  func fakeOpenTelemetryHTTPProvider(expectClusterName, expectAuthority string) *tracingcfg.Tracing_Http {
  1134  	fakeOTelHTTPProviderConfig := &tracingcfg.OpenTelemetryConfig{
  1135  		HttpService: &core.HttpService{
  1136  			HttpUri: &core.HttpUri{
  1137  				Uri: expectAuthority + "/v1/traces",
  1138  				HttpUpstreamType: &core.HttpUri_Cluster{
  1139  					Cluster: expectClusterName,
  1140  				},
  1141  				Timeout: &durationpb.Duration{Seconds: 3},
  1142  			},
  1143  			RequestHeadersToAdd: []*core.HeaderValueOption{
  1144  				{
  1145  					Header: &core.HeaderValue{
  1146  						Key:   "custom-header",
  1147  						Value: "custom-value",
  1148  					},
  1149  					AppendAction: core.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  1150  				},
  1151  			},
  1152  		},
  1153  	}
  1154  	fakeOtelHTTPAny := protoconv.MessageToAny(fakeOTelHTTPProviderConfig)
  1155  	return &tracingcfg.Tracing_Http{
  1156  		Name:       envoyOpenTelemetry,
  1157  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: fakeOtelHTTPAny},
  1158  	}
  1159  }
  1160  
  1161  func fakeOpenTelemetryResourceDetectorsProvider(expectClusterName, expectAuthority string) *tracingcfg.Tracing_Http {
  1162  	fakeOTelHTTPProviderConfig := &tracingcfg.OpenTelemetryConfig{
  1163  		HttpService: &core.HttpService{
  1164  			HttpUri: &core.HttpUri{
  1165  				Uri: expectAuthority + "/v1/traces",
  1166  				HttpUpstreamType: &core.HttpUri_Cluster{
  1167  					Cluster: expectClusterName,
  1168  				},
  1169  				Timeout: &durationpb.Duration{Seconds: 3},
  1170  			},
  1171  			RequestHeadersToAdd: []*core.HeaderValueOption{
  1172  				{
  1173  					Header: &core.HeaderValue{
  1174  						Key:   "custom-header",
  1175  						Value: "custom-value",
  1176  					},
  1177  					AppendAction: core.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD,
  1178  				},
  1179  			},
  1180  		},
  1181  		ResourceDetectors: []*core.TypedExtensionConfig{
  1182  			{
  1183  				Name:        "envoy.tracers.opentelemetry.resource_detectors.environment",
  1184  				TypedConfig: protoconv.MessageToAny(&resourcedetectors.EnvironmentResourceDetectorConfig{}),
  1185  			},
  1186  			{
  1187  				Name:        "envoy.tracers.opentelemetry.resource_detectors.dynatrace",
  1188  				TypedConfig: protoconv.MessageToAny(&resourcedetectors.DynatraceResourceDetectorConfig{}),
  1189  			},
  1190  		},
  1191  	}
  1192  	fakeOtelHTTPAny := protoconv.MessageToAny(fakeOTelHTTPProviderConfig)
  1193  	return &tracingcfg.Tracing_Http{
  1194  		Name:       envoyOpenTelemetry,
  1195  		ConfigType: &tracingcfg.Tracing_Http_TypedConfig{TypedConfig: fakeOtelHTTPAny},
  1196  	}
  1197  }