lazy cache hit/miss tests

This commit is contained in:
Michael Peters 2022-10-05 21:38:51 -07:00
parent f2ec9cfd14
commit 4d41dd0087
2 changed files with 104 additions and 2 deletions

View File

@ -445,6 +445,106 @@ describe('fetchAndVerifyIfNeeded tests', () => {
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(1);
expect(verifyFunc).toHaveBeenCalledTimes(1);
});
// Make sure to do try/catch errors, verification failures, unverifies in the middle
// Lazy verify - primary null and primary with value
test('primary with null, lazy - lazy cache miss, need to ping server', async () => {
const {
nextPrimary, nextTrusted, nextEnsureTrustedFuncReady, nextVerify,
primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc
} = getManualsAndMocks();
const primary = nextPrimary();
const trusted = nextTrusted();
const ensureTrustedFuncReady = nextEnsureTrustedFuncReady();
const verify = nextVerify();
const av = new AutoVerifier(primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc);
const resultPromise = av.fetchAndVerifyIfNeeded(true);
let result: BasicWE | null | undefined = undefined;
resultPromise.then(value => { result = value; });
expect(av.primaryPromise).toBe(primary.promise);
expect(av.trustedPromise).toBe(null); // trustedFunc will never be called
expect(av.trustedStatus).toBe('none');
expect(primaryFunc).toHaveBeenCalled();
expect(trustedFunc).toHaveBeenCalledTimes(0);
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(0);
primary.resolve(null);
await disjoint();
expect(trustedFunc).toHaveBeenCalled();
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalled();
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('verifying'); // notably, we will never publicly see it in 'fetching'
ensureTrustedFuncReady.resolve();
await disjoint();
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('verifying');
expect(verifyFunc).toHaveBeenCalledTimes(0);
trusted.resolve(new BasicWE(2));
await disjoint();
expect(verifyFunc).toHaveBeenCalledWith(null, new BasicWE(2));
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('verifying');
expect(primaryFunc).toHaveBeenCalledTimes(1);
expect(trustedFunc).toHaveBeenCalledTimes(1);
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(1);
expect(verifyFunc).toHaveBeenCalledTimes(1);
expect(result).toBeUndefined();
verify.resolve(true);
await disjoint();
expect(result).toEqual(new BasicWE(2));
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('verified');
expect(primaryFunc).toHaveBeenCalledTimes(1);
expect(trustedFunc).toHaveBeenCalledTimes(1);
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(1);
expect(verifyFunc).toHaveBeenCalledTimes(1);
});
test('primary with value, lazy - lazy cache hit, no need to ping server', async () => {
const {
nextPrimary,
primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc
} = getManualsAndMocks();
const primary = nextPrimary();
const av = new AutoVerifier(primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc);
const resultPromise = av.fetchAndVerifyIfNeeded(true);
let result: BasicWE | null | undefined = undefined;
resultPromise.then(value => { result = value; });
expect(av.primaryPromise).toBe(primary.promise);
expect(av.trustedPromise).toBe(null); // trustedFunc will never be called
expect(av.trustedStatus).toBe('none');
expect(primaryFunc).toHaveBeenCalled();
expect(result).toBeUndefined();
primary.resolve(new BasicWE(2));
await disjoint();
expect(result).toEqual(new BasicWE(2));
expect(av.trustedStatus).toBe('none');
expect(primaryFunc).toHaveBeenCalledTimes(1);
expect(trustedFunc).toHaveBeenCalledTimes(0);
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(0);
expect(verifyFunc).toHaveBeenCalledTimes(0);
});
// Make sure to do try/catch errors/rejections, verification failures, unverifies in the middle
// Multiple tryResolveTrustedPromises
});

View File

@ -229,6 +229,7 @@ export class AutoVerifier<T> {
return;
}
} else {
/* istanbul ignore next */
if (debug) LOG.debug(fetchId + ': waiting for trusted to resolve');
}
@ -269,6 +270,7 @@ export class AutoVerifier<T> {
new Error(),
);
if (this.trustedPromise === null) {
/* istanbul ignore next */
if (debug) LOG.debug(fetchId + ': re-fetching since trustedPromise was null');
this.trustedStatus = 'fetching';
this.trustedPromise = this.trustedFunc();