-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add migration operation input event and tracker. (#214)
- Loading branch information
1 parent
bee4e74
commit 2a1eb6f
Showing
9 changed files
with
449 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
185 changes: 185 additions & 0 deletions
185
packages/shared/sdk-server/__tests__/MigrationOpTracker.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import { Context } from '@launchdarkly/js-sdk-common'; | ||
|
||
import { LDConsistencyCheck, LDMigrationStage } from '../src'; | ||
import MigrationOpTracker from '../src/MigrationOpTracker'; | ||
|
||
it('does not generate an event if an op is not set', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
|
||
expect(tracker.createEvent()).toBeUndefined(); | ||
}); | ||
|
||
it('does not generate an event for an invalid context', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'kind', key: '' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
|
||
// Set the op otherwise that would prevent an event as well. | ||
tracker.op('write'); | ||
|
||
expect(tracker.createEvent()).toBeUndefined(); | ||
}); | ||
|
||
it('generates an event if the minimal requirements are met.', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
|
||
tracker.op('write'); | ||
|
||
expect(tracker.createEvent()).toMatchObject({ | ||
contextKeys: { user: 'bob' }, | ||
evaluation: { default: 'off', key: 'flag', reason: { kind: 'FALLTHROUGH' }, value: 'off' }, | ||
kind: 'migration_op', | ||
measurements: [], | ||
operation: 'write', | ||
}); | ||
}); | ||
|
||
it('includes errors if at least one is set', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
tracker.op('read'); | ||
tracker.error('old'); | ||
|
||
const event = tracker.createEvent(); | ||
expect(event?.measurements).toContainEqual({ | ||
key: 'error', | ||
values: { | ||
old: 1, | ||
new: 0, | ||
}, | ||
}); | ||
|
||
const trackerB = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
trackerB.op('read'); | ||
trackerB.error('new'); | ||
|
||
const eventB = trackerB.createEvent(); | ||
expect(eventB?.measurements).toContainEqual({ | ||
key: 'error', | ||
values: { | ||
old: 0, | ||
new: 1, | ||
}, | ||
}); | ||
}); | ||
|
||
it('includes latency if at least one measurement exists', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
tracker.op('read'); | ||
tracker.latency('old', 100); | ||
|
||
const event = tracker.createEvent(); | ||
expect(event?.measurements).toContainEqual({ | ||
key: 'latency', | ||
values: { | ||
old: 100, | ||
}, | ||
}); | ||
|
||
const trackerB = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
trackerB.op('read'); | ||
trackerB.latency('new', 150); | ||
|
||
const eventB = trackerB.createEvent(); | ||
expect(eventB?.measurements).toContainEqual({ | ||
key: 'latency', | ||
values: { | ||
new: 150, | ||
}, | ||
}); | ||
}); | ||
|
||
it('includes if the result was consistent', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
tracker.op('read'); | ||
tracker.consistency(LDConsistencyCheck.Consistent); | ||
|
||
const event = tracker.createEvent(); | ||
expect(event?.measurements).toContainEqual({ | ||
key: 'consistent', | ||
value: 1, | ||
samplingOdds: 0, | ||
}); | ||
}); | ||
|
||
it('includes if the result was inconsistent', () => { | ||
const tracker = new MigrationOpTracker( | ||
'flag', | ||
Context.fromLDContext({ kind: 'user', key: 'bob' }), | ||
LDMigrationStage.Off, | ||
LDMigrationStage.Off, | ||
{ | ||
kind: 'FALLTHROUGH', | ||
}, | ||
); | ||
tracker.op('read'); | ||
tracker.consistency(LDConsistencyCheck.Inconsistent); | ||
|
||
const event = tracker.createEvent(); | ||
expect(event?.measurements).toContainEqual({ | ||
key: 'consistent', | ||
value: 0, | ||
samplingOdds: 0, | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.