55
66package io .opentelemetry .javaagent .instrumentation .kubernetesclient ;
77
8+ import static io .opentelemetry .api .common .AttributeKey .stringKey ;
89import static io .opentelemetry .instrumentation .testing .util .TelemetryDataUtil .orderByRootSpanName ;
910import static io .opentelemetry .sdk .testing .assertj .OpenTelemetryAssertions .equalTo ;
1011import static io .opentelemetry .semconv .ErrorAttributes .ERROR_TYPE ;
2021import io .kubernetes .client .openapi .ApiClient ;
2122import io .kubernetes .client .openapi .ApiException ;
2223import io .kubernetes .client .openapi .apis .CoreV1Api ;
23- import io .opentelemetry .api .common .AttributeKey ;
2424import io .opentelemetry .api .trace .SpanKind ;
2525import io .opentelemetry .instrumentation .testing .junit .AgentInstrumentationExtension ;
2626import io .opentelemetry .instrumentation .testing .junit .InstrumentationExtension ;
27+ import io .opentelemetry .sdk .testing .assertj .OpenTelemetryAssertions ;
2728import io .opentelemetry .sdk .trace .data .StatusData ;
2829import io .opentelemetry .testing .internal .armeria .common .HttpResponse ;
2930import io .opentelemetry .testing .internal .armeria .common .HttpStatus ;
3334import java .util .Map ;
3435import java .util .concurrent .CountDownLatch ;
3536import java .util .concurrent .atomic .AtomicReference ;
37+ import javax .annotation .Nullable ;
3638import org .junit .jupiter .api .AfterEach ;
3739import org .junit .jupiter .api .BeforeEach ;
3840import org .junit .jupiter .api .Test ;
@@ -49,6 +51,14 @@ class KubernetesClientVer20Test {
4951
5052 private CoreV1Api coreV1Api ;
5153
54+ @ Nullable
55+ private static String experimental (String value ) {
56+ if (Boolean .getBoolean ("otel.instrumentation.kubernetes-client.experimental-span-attributes" )) {
57+ return value ;
58+ }
59+ return null ;
60+ }
61+
5262 @ BeforeEach
5363 void beforeEach () {
5464 mockWebServer .start ();
@@ -96,8 +106,23 @@ void synchronousCall() throws ApiException {
96106 equalTo (SERVER_PORT , mockWebServer .httpPort ()),
97107 equalTo (PEER_SERVICE , "test-peer-service" ),
98108 equalTo (
99- AttributeKey .stringKey ("kubernetes-client.namespace" ), "namespace" ),
100- equalTo (AttributeKey .stringKey ("kubernetes-client.name" ), "name" ))));
109+ stringKey ("kubernetes-client.namespace" ),
110+ experimental ("namespace" )),
111+ equalTo (stringKey ("kubernetes-client.name" ), experimental ("name" )))));
112+
113+ testing .waitAndAssertMetrics (
114+ "io.opentelemetry.kubernetes-client-7.0" ,
115+ "http.client.request.duration" ,
116+ metrics ->
117+ metrics .anySatisfy (
118+ metric ->
119+ OpenTelemetryAssertions .assertThat (metric )
120+ .hasDescription ("Duration of HTTP client requests." )
121+ .hasUnit ("s" )
122+ .hasHistogramSatisfying (
123+ histogram ->
124+ histogram .hasPointsSatisfying (
125+ point -> point .hasSumGreaterThan (0.0 )))));
101126 }
102127
103128 @ Test
@@ -108,9 +133,10 @@ void handleErrorsInSyncCall() {
108133 try {
109134 testing .runWithSpan (
110135 "parent" ,
111- () -> {
112- coreV1Api .connectGetNamespacedPodProxyWithPath ("name" , "namespace" , "path" ).execute ();
113- });
136+ () ->
137+ coreV1Api
138+ .connectGetNamespacedPodProxyWithPath ("name" , "namespace" , "path" )
139+ .execute ());
114140 } catch (ApiException e ) {
115141 exception = e ;
116142 }
@@ -145,8 +171,9 @@ void handleErrorsInSyncCall() {
145171 equalTo (ERROR_TYPE , "451" ),
146172 equalTo (PEER_SERVICE , "test-peer-service" ),
147173 equalTo (
148- AttributeKey .stringKey ("kubernetes-client.namespace" ), "namespace" ),
149- equalTo (AttributeKey .stringKey ("kubernetes-client.name" ), "name" ))));
174+ stringKey ("kubernetes-client.namespace" ),
175+ experimental ("namespace" )),
176+ equalTo (stringKey ("kubernetes-client.name" ), experimental ("name" )))));
150177 }
151178
152179 @ Test
@@ -158,20 +185,21 @@ void asynchronousCall() throws ApiException, InterruptedException {
158185
159186 testing .runWithSpan (
160187 "parent" ,
161- () -> {
162- coreV1Api
163- .connectGetNamespacedPodProxyWithPath ("name" , "namespace" , "path" )
164- .executeAsync (
165- new ApiCallbackTemplate () {
166- @ Override
167- public void onSuccess (
168- String result , int statusCode , Map <String , List <String >> responseHeaders ) {
169- responseBodyReference .set (result );
170- countDownLatch .countDown ();
171- testing .runWithSpan ("callback" , () -> {});
172- }
173- });
174- });
188+ () ->
189+ coreV1Api
190+ .connectGetNamespacedPodProxyWithPath ("name" , "namespace" , "path" )
191+ .executeAsync (
192+ new ApiCallbackTemplate () {
193+ @ Override
194+ public void onSuccess (
195+ String result ,
196+ int statusCode ,
197+ Map <String , List <String >> responseHeaders ) {
198+ responseBodyReference .set (result );
199+ countDownLatch .countDown ();
200+ testing .runWithSpan ("callback" , () -> {});
201+ }
202+ }));
175203
176204 countDownLatch .await ();
177205
@@ -198,8 +226,9 @@ public void onSuccess(
198226 equalTo (SERVER_PORT , mockWebServer .httpPort ()),
199227 equalTo (PEER_SERVICE , "test-peer-service" ),
200228 equalTo (
201- AttributeKey .stringKey ("kubernetes-client.namespace" ), "namespace" ),
202- equalTo (AttributeKey .stringKey ("kubernetes-client.name" ), "name" )),
229+ stringKey ("kubernetes-client.namespace" ),
230+ experimental ("namespace" )),
231+ equalTo (stringKey ("kubernetes-client.name" ), experimental ("name" ))),
203232 span ->
204233 span .hasName ("callback" )
205234 .hasKind (SpanKind .INTERNAL )
@@ -217,20 +246,21 @@ void handleErrorsInAsynchronousCall() throws ApiException, InterruptedException
217246
218247 testing .runWithSpan (
219248 "parent" ,
220- () -> {
221- coreV1Api
222- .connectGetNamespacedPodProxyWithPath ("name" , "namespace" , "path" )
223- .executeAsync (
224- new ApiCallbackTemplate () {
225- @ Override
226- public void onFailure (
227- ApiException e , int statusCode , Map <String , List <String >> responseHeaders ) {
228- exceptionReference .set (e );
229- countDownLatch .countDown ();
230- testing .runWithSpan ("callback" , () -> {});
231- }
232- });
233- });
249+ () ->
250+ coreV1Api
251+ .connectGetNamespacedPodProxyWithPath ("name" , "namespace" , "path" )
252+ .executeAsync (
253+ new ApiCallbackTemplate () {
254+ @ Override
255+ public void onFailure (
256+ ApiException e ,
257+ int statusCode ,
258+ Map <String , List <String >> responseHeaders ) {
259+ exceptionReference .set (e );
260+ countDownLatch .countDown ();
261+ testing .runWithSpan ("callback" , () -> {});
262+ }
263+ }));
234264
235265 countDownLatch .await ();
236266
@@ -260,8 +290,9 @@ public void onFailure(
260290 equalTo (ERROR_TYPE , "451" ),
261291 equalTo (PEER_SERVICE , "test-peer-service" ),
262292 equalTo (
263- AttributeKey .stringKey ("kubernetes-client.namespace" ), "namespace" ),
264- equalTo (AttributeKey .stringKey ("kubernetes-client.name" ), "name" )),
293+ stringKey ("kubernetes-client.namespace" ),
294+ experimental ("namespace" )),
295+ equalTo (stringKey ("kubernetes-client.name" ), experimental ("name" ))),
265296 span ->
266297 span .hasName ("callback" )
267298 .hasKind (SpanKind .INTERNAL )
0 commit comments