@@ -212,4 +212,169 @@ describe("agent/AKSLoader", () => {
212212 // The protobuf exporter should have different internal structure than the HTTP exporter
213213 assert . ok ( exporter , "Protobuf exporter should exist" ) ;
214214 } ) ;
215+
216+ it ( "constructor creates OTLP metric reader when OTEL_METRICS_EXPORTER contains otlp with other exporters (comma-separated)" , ( ) => {
217+ const env = {
218+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
219+ [ "OTEL_METRICS_EXPORTER" ] : "console,otlp,prometheus" ,
220+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
221+ } ;
222+ process . env = env ;
223+
224+ const agent = new AKSLoader ( ) ;
225+
226+ // Verify that metricReaders were added to the options
227+ const options = ( agent as any ) . _options ;
228+ assert . ok ( options . metricReaders , "metricReaders should be present in options when otlp is included with other exporters" ) ;
229+ assert . equal ( options . metricReaders . length , 1 , "Should have exactly one metric reader" ) ;
230+
231+ // Verify the metric reader is a PeriodicExportingMetricReader
232+ const metricReader = options . metricReaders [ 0 ] ;
233+ assert . equal ( metricReader . constructor . name , "PeriodicExportingMetricReader" , "Should be a PeriodicExportingMetricReader" ) ;
234+
235+ // Verify the exporter is an OTLP exporter
236+ const exporter = ( metricReader as any ) . _exporter ;
237+ assert . equal ( exporter . constructor . name , "OTLPMetricExporter" , "Should be an OTLPMetricExporter" ) ;
238+ } ) ;
239+
240+ it ( "constructor creates OTLP metric reader when OTEL_METRICS_EXPORTER contains otlp with spaces" , ( ) => {
241+ const env = {
242+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
243+ [ "OTEL_METRICS_EXPORTER" ] : "console, otlp, prometheus" ,
244+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
245+ } ;
246+ process . env = env ;
247+
248+ const agent = new AKSLoader ( ) ;
249+
250+ // Verify that metricReaders were added to the options
251+ const options = ( agent as any ) . _options ;
252+ assert . ok ( options . metricReaders , "metricReaders should be present in options when otlp is included with spaces" ) ;
253+ assert . equal ( options . metricReaders . length , 1 , "Should have exactly one metric reader" ) ;
254+
255+ // Verify the exporter is an OTLP exporter
256+ const metricReader = options . metricReaders [ 0 ] ;
257+ const exporter = ( metricReader as any ) . _exporter ;
258+ assert . equal ( exporter . constructor . name , "OTLPMetricExporter" , "Should be an OTLPMetricExporter" ) ;
259+ } ) ;
260+
261+ it ( "constructor creates OTLP metric reader when OTEL_METRICS_EXPORTER has otlp at the beginning" , ( ) => {
262+ const env = {
263+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
264+ [ "OTEL_METRICS_EXPORTER" ] : "otlp,console,prometheus" ,
265+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
266+ } ;
267+ process . env = env ;
268+
269+ const agent = new AKSLoader ( ) ;
270+
271+ // Verify that metricReaders were added to the options
272+ const options = ( agent as any ) . _options ;
273+ assert . ok ( options . metricReaders , "metricReaders should be present in options when otlp is at the beginning" ) ;
274+ assert . equal ( options . metricReaders . length , 1 , "Should have exactly one metric reader" ) ;
275+
276+ // Verify the exporter is an OTLP exporter
277+ const metricReader = options . metricReaders [ 0 ] ;
278+ const exporter = ( metricReader as any ) . _exporter ;
279+ assert . equal ( exporter . constructor . name , "OTLPMetricExporter" , "Should be an OTLPMetricExporter" ) ;
280+ } ) ;
281+
282+ it ( "constructor creates OTLP metric reader when OTEL_METRICS_EXPORTER has otlp at the end" , ( ) => {
283+ const env = {
284+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
285+ [ "OTEL_METRICS_EXPORTER" ] : "console,prometheus,otlp" ,
286+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
287+ } ;
288+ process . env = env ;
289+
290+ const agent = new AKSLoader ( ) ;
291+
292+ // Verify that metricReaders were added to the options
293+ const options = ( agent as any ) . _options ;
294+ assert . ok ( options . metricReaders , "metricReaders should be present in options when otlp is at the end" ) ;
295+ assert . equal ( options . metricReaders . length , 1 , "Should have exactly one metric reader" ) ;
296+
297+ // Verify the exporter is an OTLP exporter
298+ const metricReader = options . metricReaders [ 0 ] ;
299+ const exporter = ( metricReader as any ) . _exporter ;
300+ assert . equal ( exporter . constructor . name , "OTLPMetricExporter" , "Should be an OTLPMetricExporter" ) ;
301+ } ) ;
302+
303+ it ( "constructor does not create OTLP metric reader when OTEL_METRICS_EXPORTER contains similar strings but not otlp" , ( ) => {
304+ const env = {
305+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
306+ [ "OTEL_METRICS_EXPORTER" ] : "console,otlp-custom,prometheus" ,
307+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
308+ } ;
309+ process . env = env ;
310+
311+ const agent = new AKSLoader ( ) ;
312+
313+ // Verify that no metricReaders were added to the options
314+ const options = ( agent as any ) . _options ;
315+ assert . ok ( ! options . metricReaders || options . metricReaders . length === 0 , "Should not have any metric readers when 'otlp' is not exactly present (only similar strings like 'otlp-custom')" ) ;
316+ } ) ;
317+
318+ it ( "constructor does not create OTLP metric reader when OTEL_METRICS_EXPORTER is empty with multiple exporters" , ( ) => {
319+ const env = {
320+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
321+ [ "OTEL_METRICS_EXPORTER" ] : "console,prometheus" ,
322+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
323+ } ;
324+ process . env = env ;
325+
326+ const agent = new AKSLoader ( ) ;
327+
328+ // Verify that no metricReaders were added to the options
329+ const options = ( agent as any ) . _options ;
330+ assert . ok ( ! options . metricReaders || options . metricReaders . length === 0 , "Should not have any metric readers when otlp is not included in the list" ) ;
331+ } ) ;
332+
333+ it ( "constructor creates OTLP metric reader when OTEL_METRICS_EXPORTER contains uppercase OTLP" , ( ) => {
334+ const env = {
335+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
336+ [ "OTEL_METRICS_EXPORTER" ] : "OTLP" ,
337+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
338+ } ;
339+ process . env = env ;
340+
341+ const agent = new AKSLoader ( ) ;
342+
343+ // Verify that metricReaders were added to the options
344+ const options = ( agent as any ) . _options ;
345+ assert . ok ( options . metricReaders , "metricReaders should be present in options when OTLP is uppercase" ) ;
346+ assert . equal ( options . metricReaders . length , 1 , "Should have exactly one metric reader" ) ;
347+
348+ // Verify the metric reader is a PeriodicExportingMetricReader
349+ const metricReader = options . metricReaders [ 0 ] ;
350+ assert . equal ( metricReader . constructor . name , "PeriodicExportingMetricReader" , "Should be a PeriodicExportingMetricReader" ) ;
351+
352+ // Verify the exporter is an OTLP exporter
353+ const exporter = ( metricReader as any ) . _exporter ;
354+ assert . equal ( exporter . constructor . name , "OTLPMetricExporter" , "Should be an OTLPMetricExporter" ) ;
355+ } ) ;
356+
357+ it ( "constructor creates OTLP metric reader when OTEL_METRICS_EXPORTER contains mixed case otlp with other exporters" , ( ) => {
358+ const env = {
359+ [ "APPLICATIONINSIGHTS_CONNECTION_STRING" ] : "InstrumentationKey=1aa11111-bbbb-1ccc-8ddd-eeeeffff3333" ,
360+ [ "OTEL_METRICS_EXPORTER" ] : "CONSOLE,OtLp,PROMETHEUS" ,
361+ [ "OTEL_EXPORTER_OTLP_ENDPOINT" ] : "http://localhost:4317"
362+ } ;
363+ process . env = env ;
364+
365+ const agent = new AKSLoader ( ) ;
366+
367+ // Verify that metricReaders were added to the options
368+ const options = ( agent as any ) . _options ;
369+ assert . ok ( options . metricReaders , "metricReaders should be present in options when OtLp is mixed case with other exporters" ) ;
370+ assert . equal ( options . metricReaders . length , 1 , "Should have exactly one metric reader" ) ;
371+
372+ // Verify the metric reader is a PeriodicExportingMetricReader
373+ const metricReader = options . metricReaders [ 0 ] ;
374+ assert . equal ( metricReader . constructor . name , "PeriodicExportingMetricReader" , "Should be a PeriodicExportingMetricReader" ) ;
375+
376+ // Verify the exporter is an OTLP exporter
377+ const exporter = ( metricReader as any ) . _exporter ;
378+ assert . equal ( exporter . constructor . name , "OTLPMetricExporter" , "Should be an OTLPMetricExporter" ) ;
379+ } ) ;
215380} ) ;
0 commit comments