@@ -22,13 +22,14 @@ import { createOtlpExportDelegate } from '../../src/otlp-export-delegate';
2222import { ExportResponse } from '../../src' ;
2323import { ISerializer } from '@opentelemetry/otlp-transformer' ;
2424import { IExportPromiseHandler } from '../../src/bounded-queue-export-promise-handler' ;
25+ import { registerMockDiagLogger } from './test-utils' ;
2526
2627interface FakeInternalRepresentation {
2728 foo : string ;
2829}
2930
3031interface FakeSignalResponse {
31- baz : string ;
32+ partialSuccess ?: { foo : string } ;
3233}
3334
3435type FakeSerializer = ISerializer <
@@ -491,9 +492,7 @@ describe('OTLPExportDelegate', function () {
491492 } ;
492493 const mockTransport = < IExporterTransport > transportStubs ;
493494
494- const response : FakeSignalResponse = {
495- baz : 'partial success' ,
496- } ;
495+ const response : FakeSignalResponse = { } ;
497496
498497 const serializerStubs = {
499498 // simulate that the serializer returns something to send
@@ -541,6 +540,144 @@ describe('OTLPExportDelegate', function () {
541540 } ) ;
542541 } ) ;
543542
543+ it ( 'returns success even if response cannot be deserialized' , function ( done ) {
544+ const { warn } = registerMockDiagLogger ( ) ;
545+ // returns mock success response (empty body)
546+ const exportResponse : ExportResponse = {
547+ data : Uint8Array . from ( [ ] ) ,
548+ status : 'success' ,
549+ } ;
550+
551+ // transport does not need to do anything in this case.
552+ const transportStubs = {
553+ send : sinon . stub ( ) . returns ( Promise . resolve ( exportResponse ) ) ,
554+ shutdown : sinon . stub ( ) ,
555+ } ;
556+ const mockTransport = < IExporterTransport > transportStubs ;
557+
558+ const serializerStubs = {
559+ // simulate that the serializer returns something to send
560+ serializeRequest : sinon . stub ( ) . returns ( Uint8Array . from ( [ 1 ] ) ) ,
561+ // simulate that it returns a partial success (response with contents)
562+ deserializeResponse : sinon . stub ( ) . throws ( new Error ( ) ) ,
563+ } ;
564+ const mockSerializer = < FakeSerializer > serializerStubs ;
565+
566+ // mock a queue that has not yet reached capacity
567+ const promiseHandlerStubs = {
568+ pushPromise : sinon . stub ( ) ,
569+ hasReachedLimit : sinon . stub ( ) . returns ( false ) ,
570+ awaitAll : sinon . stub ( ) ,
571+ } ;
572+ const promiseHandler = < IExportPromiseHandler > promiseHandlerStubs ;
573+
574+ const exporter = createOtlpExportDelegate (
575+ {
576+ promiseHandler : promiseHandler ,
577+ serializer : mockSerializer ,
578+ transport : mockTransport ,
579+ } ,
580+ {
581+ timeout : 1000 ,
582+ }
583+ ) ;
584+
585+ exporter . export ( internalRepresentation , result => {
586+ try {
587+ assert . strictEqual ( result . code , ExportResultCode . SUCCESS ) ;
588+ assert . strictEqual ( result . error , undefined ) ;
589+
590+ // assert here as otherwise the promise will not have executed yet
591+ sinon . assert . calledOnceWithMatch (
592+ warn ,
593+ 'OTLPExportDelegate' ,
594+ 'Export succeeded but could not deserialize response - is the response specification compliant?' ,
595+ sinon . match . instanceOf ( Error ) ,
596+ exportResponse . data
597+ ) ;
598+ sinon . assert . calledOnce ( serializerStubs . serializeRequest ) ;
599+ sinon . assert . calledOnce ( transportStubs . send ) ;
600+ sinon . assert . calledOnce ( promiseHandlerStubs . pushPromise ) ;
601+ sinon . assert . calledOnce ( promiseHandlerStubs . hasReachedLimit ) ;
602+ sinon . assert . notCalled ( promiseHandlerStubs . awaitAll ) ;
603+ done ( ) ;
604+ } catch ( err ) {
605+ // ensures we throw if there are more calls to result;
606+ done ( err ) ;
607+ }
608+ } ) ;
609+ } ) ;
610+
611+ it ( 'returns success and warns on partial success response' , function ( done ) {
612+ const { warn } = registerMockDiagLogger ( ) ;
613+ // returns mock success response (empty body)
614+ const exportResponse : ExportResponse = {
615+ data : Uint8Array . from ( [ ] ) ,
616+ status : 'success' ,
617+ } ;
618+
619+ // transport does not need to do anything in this case.
620+ const transportStubs = {
621+ send : sinon . stub ( ) . returns ( Promise . resolve ( exportResponse ) ) ,
622+ shutdown : sinon . stub ( ) ,
623+ } ;
624+ const mockTransport = < IExporterTransport > transportStubs ;
625+
626+ const partialSuccessResponse : FakeSignalResponse = {
627+ partialSuccess : { foo : 'bar' } ,
628+ } ;
629+
630+ const serializerStubs = {
631+ // simulate that the serializer returns something to send
632+ serializeRequest : sinon . stub ( ) . returns ( Uint8Array . from ( [ 1 ] ) ) ,
633+ // simulate that it returns a partial success (response with contents)
634+ deserializeResponse : sinon . stub ( ) . returns ( partialSuccessResponse ) ,
635+ } ;
636+ const mockSerializer = < FakeSerializer > serializerStubs ;
637+
638+ // mock a queue that has not yet reached capacity
639+ const promiseHandlerStubs = {
640+ pushPromise : sinon . stub ( ) ,
641+ hasReachedLimit : sinon . stub ( ) . returns ( false ) ,
642+ awaitAll : sinon . stub ( ) ,
643+ } ;
644+ const promiseHandler = < IExportPromiseHandler > promiseHandlerStubs ;
645+
646+ const exporter = createOtlpExportDelegate (
647+ {
648+ promiseHandler : promiseHandler ,
649+ serializer : mockSerializer ,
650+ transport : mockTransport ,
651+ } ,
652+ {
653+ timeout : 1000 ,
654+ }
655+ ) ;
656+
657+ exporter . export ( internalRepresentation , result => {
658+ try {
659+ assert . strictEqual ( result . code , ExportResultCode . SUCCESS ) ;
660+ assert . strictEqual ( result . error , undefined ) ;
661+
662+ // assert here as otherwise the promise will not have executed yet
663+ sinon . assert . calledOnceWithMatch (
664+ warn ,
665+ 'Received Partial Success response:' ,
666+ JSON . stringify ( partialSuccessResponse . partialSuccess )
667+ ) ;
668+ sinon . assert . calledOnce ( serializerStubs . serializeRequest ) ;
669+ sinon . assert . calledOnce ( transportStubs . send ) ;
670+ sinon . assert . calledOnce ( promiseHandlerStubs . pushPromise ) ;
671+ sinon . assert . calledOnce ( promiseHandlerStubs . hasReachedLimit ) ;
672+ sinon . assert . notCalled ( promiseHandlerStubs . awaitAll ) ;
673+ done ( ) ;
674+ } catch ( err ) {
675+ // ensures we throw if there are more calls to result;
676+ done ( err ) ;
677+ }
678+ } ) ;
679+ } ) ;
680+
544681 it ( 'returns failure when send rejects' , function ( done ) {
545682 const transportStubs = {
546683 // make transport reject
0 commit comments