diff --git a/src/lib/probe-validator.ts b/src/lib/probe-validator.ts index 40e6bd27..794f9c38 100644 --- a/src/lib/probe-validator.ts +++ b/src/lib/probe-validator.ts @@ -3,38 +3,39 @@ import TTLCache from '@isaacs/ttlcache'; import { type RedisCluster, getMeasurementRedisClient } from './redis/measurement-client.js'; export class ProbeValidator { - private readonly testIdToProbeId = new TTLCache({ + private readonly measurementIdToTests = new TTLCache>({ ttl: (config.get('measurement.timeout') + 30) * 1000, }); constructor (private readonly redis: RedisCluster) {} addValidIds (measurementId: string, testId: string, probeUuid: string): void { - const key = ProbeValidator.getKey(measurementId, testId); - this.testIdToProbeId.set(key, probeUuid); + const measurement = this.measurementIdToTests.get(measurementId); + + if (!measurement) { + this.measurementIdToTests.set(measurementId, new Map([ [ testId, probeUuid ] ])); + } else { + measurement.set(testId, probeUuid); + } } async validateProbe (measurementId: string, testId: string, probeUuid: string): Promise { - const key = ProbeValidator.getKey(measurementId, testId); - let probeId = this.testIdToProbeId.get(key); + const measurement = this.measurementIdToTests.get(measurementId); + let probeId = measurement && measurement.get(testId); if (!probeId) { - probeId = await this.getProbeIdFromRedis(key); + probeId = await this.getProbeIdFromRedis(measurementId, testId); } if (!probeId) { - throw new Error(`Probe ID not found for key ${key}`); + throw new Error(`Probe ID not found for measurement ID: ${measurementId}, test ID: ${testId}`); } else if (probeId !== probeUuid) { - throw new Error(`Probe ID is wrong for key ${key}. Expected: ${probeId}, actual: ${probeUuid}`); + throw new Error(`Probe ID is wrong for measurement ID: ${measurementId}, test ID: ${testId}. Expected: ${probeId}, actual: ${probeUuid}`); } } - async getProbeIdFromRedis (key: string) { - return this.redis.hGet('gp:test-to-probe', key); - } - - static getKey (measurementId: string, testId: string) { - return `${measurementId}_${testId}`; + async getProbeIdFromRedis (measurementId: string, testId: string) { + return this.redis.hGet('gp:test-to-probe', `${measurementId}_${testId}`); } } diff --git a/test/tests/unit/probe-validator.test.ts b/test/tests/unit/probe-validator.test.ts index dd8f5ca7..e4b1c132 100644 --- a/test/tests/unit/probe-validator.test.ts +++ b/test/tests/unit/probe-validator.test.ts @@ -13,19 +13,21 @@ describe('ProbeValidator', () => { }); it('should pass through valid probe id', async () => { - probeValidator.addValidIds('measurement-id', 'test-id', 'probe-uuid'); - await probeValidator.validateProbe('measurement-id', 'test-id', 'probe-uuid'); + probeValidator.addValidIds('measurement-id', 'test-id-0', 'probe-uuid-0'); + probeValidator.addValidIds('measurement-id', 'test-id-1', 'probe-uuid-1'); + await probeValidator.validateProbe('measurement-id', 'test-id-0', 'probe-uuid-0'); + await probeValidator.validateProbe('measurement-id', 'test-id-1', 'probe-uuid-1'); }); it('should throw for invalid probe id', async () => { probeValidator.addValidIds('measurement-id', 'test-id', 'probe-uuid'); const error = await probeValidator.validateProbe('measurement-id', 'test-id', 'invalid-probe-uuid').catch(err => err); - expect(error.message).to.equal('Probe ID is wrong for key measurement-id_test-id. Expected: probe-uuid, actual: invalid-probe-uuid'); + expect(error.message).to.equal('Probe ID is wrong for measurement ID: measurement-id, test ID: test-id. Expected: probe-uuid, actual: invalid-probe-uuid'); }); it('should throw for missing key', async () => { const error = await probeValidator.validateProbe('missing-measurement-id', 'test-id', 'probe-uuid').catch(err => err); - expect(error.message).to.equal('Probe ID not found for key missing-measurement-id_test-id'); + expect(error.message).to.equal('Probe ID not found for measurement ID: missing-measurement-id, test ID: test-id'); }); it('should search key in redis if not found locally', async () => { @@ -36,6 +38,6 @@ describe('ProbeValidator', () => { it('should throw if redis probe id is different', async () => { redis.hGet.resolves('different-probe-uuid'); const error = await probeValidator.validateProbe('only-redis-measurement-id', 'test-id', 'probe-uuid').catch(err => err); - expect(error.message).to.equal('Probe ID is wrong for key only-redis-measurement-id_test-id. Expected: different-probe-uuid, actual: probe-uuid'); + expect(error.message).to.equal('Probe ID is wrong for measurement ID: only-redis-measurement-id, test ID: test-id. Expected: different-probe-uuid, actual: probe-uuid'); }); });