mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Add metrics validation to avoid NaN #253
This commit is contained in:
		
							parent
							
								
									a2f80c6ee5
								
							
						
					
					
						commit
						f91a24eabe
					
				| @ -335,3 +335,45 @@ test('should have correct values for lastHour', t => { | ||||
|     metrics.destroy(); | ||||
|     clock.restore(); | ||||
| }); | ||||
| 
 | ||||
| test('should not fail when toggle metrics is missing yes/no field', t => { | ||||
|     const store = new EventEmitter(); | ||||
|     const metrics = new UnleashClientMetrics(store); | ||||
|     store.emit('metrics', { | ||||
|         appName, | ||||
|         instanceId, | ||||
|         bucket: { | ||||
|             start: new Date(), | ||||
|             stop: new Date(), | ||||
|             toggles: { | ||||
|                 toggleX: { | ||||
|                     yes: 123, | ||||
|                     no: 0, | ||||
|                 }, | ||||
|             }, | ||||
|         }, | ||||
|     }); | ||||
| 
 | ||||
|     metrics.addPayload({ | ||||
|         appName, | ||||
|         instanceId, | ||||
|         bucket: { | ||||
|             start: new Date(), | ||||
|             stop: new Date(), | ||||
|             toggles: { | ||||
|                 toggleX: { | ||||
|                     blue: 10, | ||||
|                     green: 10, | ||||
|                 }, | ||||
|             }, | ||||
|         }, | ||||
|     }); | ||||
| 
 | ||||
|     t.truthy(metrics.globalCount === 123); | ||||
|     t.deepEqual(metrics.getTogglesMetrics().lastMinute.toggleX, { | ||||
|         yes: 123, | ||||
|         no: 0, | ||||
|     }); | ||||
| 
 | ||||
|     metrics.destroy(); | ||||
| }); | ||||
|  | ||||
| @ -25,7 +25,7 @@ module.exports = class UnleashClientMetrics { | ||||
|             Object.keys(toggles).forEach(toggleName => { | ||||
|                 this.lastHourProjection.substract( | ||||
|                     toggleName, | ||||
|                     toggles[toggleName] | ||||
|                     this.createCountObject(toggles[toggleName]) | ||||
|                 ); | ||||
|             }); | ||||
|         }); | ||||
| @ -33,7 +33,7 @@ module.exports = class UnleashClientMetrics { | ||||
|             Object.keys(toggles).forEach(toggleName => { | ||||
|                 this.lastMinuteProjection.substract( | ||||
|                     toggleName, | ||||
|                     toggles[toggleName] | ||||
|                     this.createCountObject(toggles[toggleName]) | ||||
|                 ); | ||||
|             }); | ||||
|         }); | ||||
| @ -91,6 +91,12 @@ module.exports = class UnleashClientMetrics { | ||||
|         return this.apps[appName]; | ||||
|     } | ||||
| 
 | ||||
|     createCountObject(entry) { | ||||
|         const yes = typeof entry.yes == 'number' ? entry.yes : 0; | ||||
|         const no = typeof entry.no == 'number' ? entry.no : 0; | ||||
|         return { yes, no }; | ||||
|     } | ||||
| 
 | ||||
|     addBucket(app, bucket) { | ||||
|         let count = 0; | ||||
|         // TODO stop should be createdAt
 | ||||
| @ -99,10 +105,10 @@ module.exports = class UnleashClientMetrics { | ||||
|         const toggleNames = Object.keys(toggles); | ||||
| 
 | ||||
|         toggleNames.forEach(n => { | ||||
|             const entry = toggles[n]; | ||||
|             this.lastHourProjection.add(n, entry); | ||||
|             this.lastMinuteProjection.add(n, entry); | ||||
|             count += entry.yes + entry.no; | ||||
|             const countObj = this.createCountObject(toggles[n]); | ||||
|             this.lastHourProjection.add(n, countObj); | ||||
|             this.lastMinuteProjection.add(n, countObj); | ||||
|             count += countObj.yes + countObj.no; | ||||
|         }); | ||||
| 
 | ||||
|         this.lastHourList.add(toggles, stop); | ||||
|  | ||||
| @ -2,13 +2,18 @@ | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| const countSchema = joi.object().options({ stripUnknown: true }).keys({ | ||||
|     yes: joi.number().required().min(0).default(0), | ||||
|     no: joi.number().required().min(0).default(0), | ||||
| }); | ||||
| 
 | ||||
| const clientMetricsSchema = joi.object().options({ stripUnknown: true }).keys({ | ||||
|     appName: joi.string().required(), | ||||
|     instanceId: joi.string().required(), | ||||
|     bucket: joi.object().required().keys({ | ||||
|         start: joi.date().required(), | ||||
|         stop: joi.date().required(), | ||||
|         toggles: joi.object(), | ||||
|         toggles: joi.object().pattern(/.*/, countSchema), | ||||
|     }), | ||||
| }); | ||||
| 
 | ||||
|  | ||||
| @ -36,7 +36,7 @@ test('should validate client metrics', t => { | ||||
|         .expect(400); | ||||
| }); | ||||
| 
 | ||||
| test('should accept client metrics', t => { | ||||
| test('should accept empty client metrics', t => { | ||||
|     t.plan(0); | ||||
|     const { request } = getSetup(); | ||||
|     return request | ||||
| @ -52,3 +52,47 @@ test('should accept client metrics', t => { | ||||
|         }) | ||||
|         .expect(202); | ||||
| }); | ||||
| 
 | ||||
| test('should accept client metrics with yes/no', t => { | ||||
|     t.plan(0); | ||||
|     const { request } = getSetup(); | ||||
|     return request | ||||
|         .post('/api/client/metrics') | ||||
|         .send({ | ||||
|             appName: 'demo', | ||||
|             instanceId: '1', | ||||
|             bucket: { | ||||
|                 start: Date.now(), | ||||
|                 stop: Date.now(), | ||||
|                 toggles: { | ||||
|                     toggleA: { | ||||
|                         yes: 200, | ||||
|                         no: 0, | ||||
|                     }, | ||||
|                 }, | ||||
|             }, | ||||
|         }) | ||||
|         .expect(202); | ||||
| }); | ||||
| 
 | ||||
| test('should not accept client metrics without yes/no', t => { | ||||
|     t.plan(0); | ||||
|     const { request } = getSetup(); | ||||
|     return request | ||||
|         .post('/api/client/metrics') | ||||
|         .send({ | ||||
|             appName: 'demo', | ||||
|             instanceId: '1', | ||||
|             bucket: { | ||||
|                 start: Date.now(), | ||||
|                 stop: Date.now(), | ||||
|                 toggles: { | ||||
|                     toggleA: { | ||||
|                         blue: 200, | ||||
|                         green: 0, | ||||
|                     }, | ||||
|                 }, | ||||
|             }, | ||||
|         }) | ||||
|         .expect(400); | ||||
| }); | ||||
|  | ||||
							
								
								
									
										8
									
								
								test/examples/client-register.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								test/examples/client-register.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| { | ||||
|     "appName": "appName", | ||||
|     "instanceId": "instanceId", | ||||
|     "sdkVersion": "test:123", | ||||
|     "strategies": ["default", "some-strategy-1"], | ||||
|     "started": "2016-11-03T07:16:43.572Z", | ||||
|     "interval": 10000 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user