@@ -41,7 +41,7 @@ describe('Hub', () => {
41
41
} ) ;
42
42
43
43
describe ( 'transaction sampling' , ( ) => {
44
- describe ( 'options' , ( ) => {
44
+ describe ( 'tracesSampleRate and tracesSampler options' , ( ) => {
45
45
it ( "should call tracesSampler if it's defined" , ( ) => {
46
46
const tracesSampler = jest . fn ( ) ;
47
47
const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
@@ -52,11 +52,20 @@ describe('Hub', () => {
52
52
53
53
it ( 'should prefer tracesSampler to tracesSampleRate' , ( ) => {
54
54
const tracesSampler = jest . fn ( ) ;
55
- const hub = new Hub ( new BrowserClient ( { tracesSampleRate : 1 , tracesSampler : tracesSampler } ) ) ;
55
+ const hub = new Hub ( new BrowserClient ( { tracesSampleRate : 1 , tracesSampler } ) ) ;
56
56
hub . startTransaction ( { name : 'dogpark' } ) ;
57
57
58
58
expect ( tracesSampler ) . toHaveBeenCalled ( ) ;
59
59
} ) ;
60
+
61
+ it ( 'tolerates tracesSampler returning a boolean' , ( ) => {
62
+ const tracesSampler = jest . fn ( ) . mockReturnValue ( true ) ;
63
+ const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
64
+ const transaction = hub . startTransaction ( { name : 'dogpark' } ) ;
65
+
66
+ expect ( tracesSampler ) . toHaveBeenCalled ( ) ;
67
+ expect ( transaction . sampled ) . toBe ( true ) ;
68
+ } ) ;
60
69
} ) ;
61
70
62
71
describe ( 'default sample context' , ( ) => {
@@ -133,9 +142,25 @@ describe('Hub', () => {
133
142
134
143
expect ( tracesSampler ) . toHaveBeenCalledWith ( expect . objectContaining ( { location : dogParkLocation } ) ) ;
135
144
} ) ;
145
+
146
+ it ( "should add parent's sampling decision to default sample context" , ( ) => {
147
+ const tracesSampler = jest . fn ( ) ;
148
+ const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
149
+ const parentSamplingDecsion = false ;
150
+
151
+ hub . startTransaction ( {
152
+ name : 'dogpark' ,
153
+ parentSpanId : '12312012' ,
154
+ sampled : parentSamplingDecsion ,
155
+ } ) ;
156
+
157
+ expect ( tracesSampler ) . toHaveBeenLastCalledWith (
158
+ expect . objectContaining ( { parentSampled : parentSamplingDecsion } ) ,
159
+ ) ;
160
+ } ) ;
136
161
} ) ;
137
162
138
- describe ( 'while sampling ' , ( ) => {
163
+ describe ( 'sample() ' , ( ) => {
139
164
it ( 'should not sample transactions when tracing is disabled' , ( ) => {
140
165
// neither tracesSampleRate nor tracesSampler is defined -> tracing disabled
141
166
const hub = new Hub ( new BrowserClient ( { } ) ) ;
@@ -157,36 +182,41 @@ describe('Hub', () => {
157
182
158
183
expect ( transaction . sampled ) . toBe ( true ) ;
159
184
} ) ;
185
+ } ) ;
160
186
161
- it ( "should reject tracesSampleRates which aren't numbers" , ( ) => {
187
+ describe ( 'isValidSampleRate()' , ( ) => {
188
+ it ( "should reject tracesSampleRates which aren't numbers or booleans" , ( ) => {
162
189
const hub = new Hub ( new BrowserClient ( { tracesSampleRate : 'dogs!' as any } ) ) ;
163
190
hub . startTransaction ( { name : 'dogpark' } ) ;
164
191
165
- expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be a number' ) ) ;
192
+ expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be a boolean or a number' ) ) ;
166
193
} ) ;
167
194
195
+ // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1
168
196
it ( 'should reject tracesSampleRates less than 0' , ( ) => {
169
197
const hub = new Hub ( new BrowserClient ( { tracesSampleRate : - 26 } ) ) ;
170
198
hub . startTransaction ( { name : 'dogpark' } ) ;
171
199
172
200
expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be between 0 and 1' ) ) ;
173
201
} ) ;
174
202
203
+ // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1
175
204
it ( 'should reject tracesSampleRates greater than 1' , ( ) => {
176
205
const hub = new Hub ( new BrowserClient ( { tracesSampleRate : 26 } ) ) ;
177
206
hub . startTransaction ( { name : 'dogpark' } ) ;
178
207
179
208
expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be between 0 and 1' ) ) ;
180
209
} ) ;
181
210
182
- it ( "should reject tracesSampler return values which aren't numbers" , ( ) => {
211
+ it ( "should reject tracesSampler return values which aren't numbers or booleans " , ( ) => {
183
212
const tracesSampler = jest . fn ( ) . mockReturnValue ( 'dogs!' ) ;
184
213
const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
185
214
hub . startTransaction ( { name : 'dogpark' } ) ;
186
215
187
- expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be a number' ) ) ;
216
+ expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be a boolean or a number' ) ) ;
188
217
} ) ;
189
218
219
+ // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1
190
220
it ( 'should reject tracesSampler return values less than 0' , ( ) => {
191
221
const tracesSampler = jest . fn ( ) . mockReturnValue ( - 12 ) ;
192
222
const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
@@ -195,6 +225,7 @@ describe('Hub', () => {
195
225
expect ( logger . warn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Sample rate must be between 0 and 1' ) ) ;
196
226
} ) ;
197
227
228
+ // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1
198
229
it ( 'should reject tracesSampler return values greater than 1' , ( ) => {
199
230
const tracesSampler = jest . fn ( ) . mockReturnValue ( 31 ) ;
200
231
const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
@@ -204,14 +235,6 @@ describe('Hub', () => {
204
235
} ) ;
205
236
} ) ;
206
237
207
- it ( 'should propagate sampling decision to child spans' , ( ) => {
208
- const hub = new Hub ( new BrowserClient ( { tracesSampleRate : 0 } ) ) ;
209
- const transaction = hub . startTransaction ( { name : 'dogpark' } ) ;
210
- const child = transaction . startChild ( { op : 'test' } ) ;
211
-
212
- expect ( child . sampled ) . toBe ( false ) ;
213
- } ) ;
214
-
215
238
it ( 'should drop transactions with sampled = false' , ( ) => {
216
239
const client = new BrowserClient ( { tracesSampleRate : 0 } ) ;
217
240
jest . spyOn ( client , 'captureEvent' ) ;
@@ -226,5 +249,55 @@ describe('Hub', () => {
226
249
expect ( transaction . finish ) . toReturnWith ( undefined ) ;
227
250
expect ( client . captureEvent ) . not . toBeCalled ( ) ;
228
251
} ) ;
252
+
253
+ describe ( 'sampling inheritance' , ( ) => {
254
+ it ( 'should propagate sampling decision to child spans' , ( ) => {
255
+ const hub = new Hub ( new BrowserClient ( { tracesSampleRate : Math . random ( ) } ) ) ;
256
+ const transaction = hub . startTransaction ( { name : 'dogpark' } ) ;
257
+ const child = transaction . startChild ( { op : 'test' } ) ;
258
+
259
+ expect ( child . sampled ) . toBe ( transaction . sampled ) ;
260
+ } ) ;
261
+
262
+ it ( 'should propagate sampling decision to child transactions in XHR header' , ( ) => {
263
+ // TODO this doesn't currently happen, but it should
264
+ } ) ;
265
+
266
+ it ( 'should propagate sampling decision to child transactions in fetch header' , ( ) => {
267
+ // TODO this doesn't currently happen, but it should
268
+ } ) ;
269
+
270
+ it ( "should inherit parent's sampling decision when creating a new transaction if tracesSampler is undefined" , ( ) => {
271
+ // tracesSampleRate = 1 means every transaction should end up with sampled = true, so make parent's decision the
272
+ // opposite to prove that inheritance takes precedence over tracesSampleRate
273
+ const hub = new Hub ( new BrowserClient ( { tracesSampleRate : 1 } ) ) ;
274
+ const parentSamplingDecsion = false ;
275
+
276
+ const transaction = hub . startTransaction ( {
277
+ name : 'dogpark' ,
278
+ parentSpanId : '12312012' ,
279
+ sampled : parentSamplingDecsion ,
280
+ } ) ;
281
+
282
+ expect ( transaction . sampled ) . toBe ( parentSamplingDecsion ) ;
283
+ } ) ;
284
+
285
+ it ( "should ignore parent's sampling decision when tracesSampler is defined" , ( ) => {
286
+ // this tracesSampler causes every transaction to end up with sampled = true, so make parent's decision the
287
+ // opposite to prove that tracesSampler takes precedence over inheritance
288
+ const tracesSampler = ( ) => true ;
289
+ const parentSamplingDecsion = false ;
290
+
291
+ const hub = new Hub ( new BrowserClient ( { tracesSampler } ) ) ;
292
+
293
+ const transaction = hub . startTransaction ( {
294
+ name : 'dogpark' ,
295
+ parentSpanId : '12312012' ,
296
+ sampled : parentSamplingDecsion ,
297
+ } ) ;
298
+
299
+ expect ( transaction . sampled ) . not . toBe ( parentSamplingDecsion ) ;
300
+ } ) ;
301
+ } ) ;
229
302
} ) ;
230
303
} ) ;
0 commit comments