1+ import type { SerializedStreamedSpanContainer } from '@sentry/core' ;
12import { MongoMemoryServer } from 'mongodb-memory-server-global' ;
23import { afterAll , beforeAll , describe , expect } from 'vitest' ;
34import { cleanupChildProcesses , createEsmAndCjsTests } from '../../../utils/runner' ;
@@ -39,6 +40,23 @@ describe('Mongoose tracing channel Test', () => {
3940 origin : 'auto.db.mongoose.diagnostic_channel' ,
4041 } ) ;
4142
43+ const expectedStreamedSpan = ( operation : string , extraAttributes : Record < string , unknown > = { } ) =>
44+ expect . objectContaining ( {
45+ name : `${ operation } blogposts` ,
46+ is_segment : false ,
47+ parent_span_id : expect . stringMatching ( / ^ [ \d a - f ] { 16 } $ / ) ,
48+ attributes : expect . objectContaining ( {
49+ 'db.collection.name' : { type : 'string' , value : 'blogposts' } ,
50+ 'db.namespace' : { type : 'string' , value : 'test' } ,
51+ 'db.operation.name' : { type : 'string' , value : operation } ,
52+ 'db.system.name' : { type : 'string' , value : 'mongodb' } ,
53+ 'sentry.op' : { type : 'string' , value : 'db' } ,
54+ 'sentry.origin' : { type : 'string' , value : 'auto.db.mongoose.diagnostic_channel' } ,
55+ 'sentry.trace_lifecycle' : { type : 'string' , value : 'stream' } ,
56+ ...extraAttributes ,
57+ } ) ,
58+ } ) ;
59+
4260 const EXPECTED_TRANSACTION = {
4361 transaction : 'Test Transaction' ,
4462 spans : expect . arrayContaining ( [
@@ -62,6 +80,35 @@ describe('Mongoose tracing channel Test', () => {
6280 await createTestRunner ( ) . expect ( { transaction : EXPECTED_TRANSACTION } ) . start ( ) . completed ( ) ;
6381 } ) ;
6482
83+ test ( 'names channel spans after the operation and collection with span streaming enabled' , async ( ) => {
84+ await createTestRunner ( )
85+ . withEnv ( { STREAMED : 'true' } )
86+ . expect ( {
87+ span : ( container : SerializedStreamedSpanContainer ) => {
88+ expect ( container . items . find ( item => item . is_segment ) ?. name ) . toBe ( 'Test Transaction' ) ;
89+
90+ expect ( container . items ) . toContainEqual ( expectedStreamedSpan ( 'save' ) ) ;
91+ expect ( container . items ) . toContainEqual (
92+ expectedStreamedSpan ( 'findOne' , { 'db.query.text' : { type : 'string' , value : '{"title":"?"}' } } ) ,
93+ ) ;
94+ expect ( container . items ) . toContainEqual (
95+ expectedStreamedSpan ( 'aggregate' , {
96+ 'db.query.text' : { type : 'string' , value : '[{"$match":{"title":"?"}}]' } ,
97+ } ) ,
98+ ) ;
99+ expect ( container . items ) . toContainEqual (
100+ expectedStreamedSpan ( 'insertMany' , { 'db.operation.batch.size' : { type : 'integer' , value : 2 } } ) ,
101+ ) ;
102+ expect ( container . items ) . toContainEqual (
103+ expectedStreamedSpan ( 'bulkWrite' , { 'db.operation.batch.size' : { type : 'integer' , value : 2 } } ) ,
104+ ) ;
105+ expect ( container . items ) . toContainEqual ( expectedStreamedSpan ( 'find' ) ) ;
106+ } ,
107+ } )
108+ . start ( )
109+ . completed ( ) ;
110+ } ) ;
111+
65112 test ( 'does not double-instrument: the legacy IITM mongoose patcher does not fire on 9.7' , async ( ) => {
66113 await createTestRunner ( )
67114 . expect ( {
@@ -153,6 +200,20 @@ describe('Mongoose tracing channel Test', () => {
153200 . start ( )
154201 . completed ( ) ;
155202 } ) ;
203+
204+ test ( 'flags the streamed mongoose channel span as errored when the operation fails' , async ( ) => {
205+ await createTestRunner ( )
206+ . withEnv ( { STREAMED : 'true' } )
207+ . expect ( {
208+ span : ( container : SerializedStreamedSpanContainer ) => {
209+ const aggregateSpan = container . items . find ( item => item . name === 'aggregate blogposts' ) ;
210+ expect ( aggregateSpan ) . toBeDefined ( ) ;
211+ expect ( aggregateSpan ?. status ) . toBe ( 'error' ) ;
212+ } ,
213+ } )
214+ . start ( )
215+ . completed ( ) ;
216+ } ) ;
156217 } ,
157218 { additionalDependencies : { mongoose : '^9.7' } } ,
158219 ) ;
0 commit comments