Compare commits
No commits in common. "4d41dd00877dc7d162b965e7d5b8e1234dd39f3a" and "90ab1a0c6ef368cbf3afb946fa0e532772067635" have entirely different histories.
4d41dd0087
...
90ab1a0c6e
@ -193,7 +193,31 @@ describe('fetchAndVerifyIfNeeded tests', () => {
|
|||||||
verifyFunc: jest.fn((_primaryResult: BasicWE | null, _trustedResult: BasicWE | null) => manuals.verify[calls.verify++]!.promise),
|
verifyFunc: jest.fn((_primaryResult: BasicWE | null, _trustedResult: BasicWE | null) => manuals.verify[calls.verify++]!.promise),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function getGeneralMocks(): {
|
||||||
|
primary: ManualPromise<BasicWE>,
|
||||||
|
trusted: ManualPromise<BasicWE>,
|
||||||
|
ensureTrustedFuncReady: ManualPromise<void>,
|
||||||
|
verify: ManualPromise<boolean>
|
||||||
|
primaryFunc: () => Promise<BasicWE>,
|
||||||
|
trustedFunc: () => Promise<BasicWE>,
|
||||||
|
ensureTrustedFuncReadyFunc: () => Promise<void>,
|
||||||
|
verifyFunc: () => Promise<boolean>,
|
||||||
|
} {
|
||||||
|
const primary = new ManualPromise<BasicWE>();
|
||||||
|
const trusted = new ManualPromise<BasicWE>();
|
||||||
|
const ensureTrustedFuncReady = new ManualPromise<void>();
|
||||||
|
const verify = new ManualPromise<boolean>();
|
||||||
|
return {
|
||||||
|
primary,
|
||||||
|
trusted,
|
||||||
|
ensureTrustedFuncReady,
|
||||||
|
verify,
|
||||||
|
primaryFunc: () => primary.promise,
|
||||||
|
trustedFunc: () => trusted.promise,
|
||||||
|
ensureTrustedFuncReadyFunc: () => ensureTrustedFuncReady.promise,
|
||||||
|
verifyFunc: () => verify.promise,
|
||||||
|
};
|
||||||
|
}
|
||||||
async function disjoint() {
|
async function disjoint() {
|
||||||
await Util.sleep(0);
|
await Util.sleep(0);
|
||||||
}
|
}
|
||||||
@ -384,167 +408,8 @@ describe('fetchAndVerifyIfNeeded tests', () => {
|
|||||||
expect(verifyFunc).toHaveBeenCalledTimes(1);
|
expect(verifyFunc).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('primary with value, then trusted with null - cache hit, server deleted', async () => {
|
/* test('primary with value, then trusted with null - cache hit, server deleted', async () => { */
|
||||||
const {
|
/* expect(false).toBe(true); */
|
||||||
nextPrimary, nextTrusted, nextEnsureTrustedFuncReady, nextVerify,
|
/* }); */
|
||||||
primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc
|
// Make sure to do try/catch errors, verification failures, unverifies in the middle
|
||||||
} = 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();
|
|
||||||
let result: BasicWE | null | undefined = undefined;
|
|
||||||
resultPromise.then(value => { result = value; });
|
|
||||||
|
|
||||||
expect(av.primaryPromise).toBe(primary.promise);
|
|
||||||
expect(av.trustedPromise).toBe(trusted.promise);
|
|
||||||
expect(av.trustedStatus).toBe('fetching');
|
|
||||||
expect(primaryFunc).toHaveBeenCalled();
|
|
||||||
expect(trustedFunc).toHaveBeenCalled();
|
|
||||||
|
|
||||||
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(0);
|
|
||||||
expect(result).toBeUndefined();
|
|
||||||
primary.resolve(new BasicWE(2));
|
|
||||||
await disjoint();
|
|
||||||
|
|
||||||
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalled();
|
|
||||||
expect(result).toEqual(new BasicWE(2));
|
|
||||||
expect(av.primaryPromise).toBe(null);
|
|
||||||
expect(av.trustedPromise).toBe(trusted.promise);
|
|
||||||
expect(av.trustedStatus).toBe('verifying');
|
|
||||||
|
|
||||||
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(null);
|
|
||||||
await disjoint();
|
|
||||||
|
|
||||||
expect(verifyFunc).toHaveBeenCalledWith(new BasicWE(2), null);
|
|
||||||
expect(av.primaryPromise).toBe(null);
|
|
||||||
expect(av.trustedPromise).toBe(trusted.promise);
|
|
||||||
expect(av.trustedStatus).toBe('verifying');
|
|
||||||
|
|
||||||
verify.resolve(true);
|
|
||||||
await disjoint();
|
|
||||||
|
|
||||||
expect(av.primaryPromise).toBe(null);
|
|
||||||
expect(av.trustedPromise).toBe(trusted.promise);
|
|
||||||
expect(av.trustedStatus).toBe('none');
|
|
||||||
|
|
||||||
expect(primaryFunc).toHaveBeenCalledTimes(1);
|
|
||||||
expect(trustedFunc).toHaveBeenCalledTimes(1);
|
|
||||||
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(1);
|
|
||||||
expect(verifyFunc).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
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
|
|
||||||
});
|
});
|
||||||
|
@ -202,7 +202,6 @@ export class AutoVerifier<T> {
|
|||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (debug) LOG.debug(fetchId + ": created trusted promise, set to 'fetching'");
|
if (debug) LOG.debug(fetchId + ": created trusted promise, set to 'fetching'");
|
||||||
this.trustedStatus = 'fetching';
|
this.trustedStatus = 'fetching';
|
||||||
// TODO: The solution may be to merge the ensureTrustedFuncReady into the trustedPromise
|
|
||||||
this.trustedPromise = this.trustedFunc();
|
this.trustedPromise = this.trustedFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +228,6 @@ export class AutoVerifier<T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* istanbul ignore next */
|
|
||||||
if (debug) LOG.debug(fetchId + ': waiting for trusted to resolve');
|
if (debug) LOG.debug(fetchId + ': waiting for trusted to resolve');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +268,6 @@ export class AutoVerifier<T> {
|
|||||||
new Error(),
|
new Error(),
|
||||||
);
|
);
|
||||||
if (this.trustedPromise === null) {
|
if (this.trustedPromise === null) {
|
||||||
/* istanbul ignore next */
|
|
||||||
if (debug) LOG.debug(fetchId + ': re-fetching since trustedPromise was null');
|
if (debug) LOG.debug(fetchId + ': re-fetching since trustedPromise was null');
|
||||||
this.trustedStatus = 'fetching';
|
this.trustedStatus = 'fetching';
|
||||||
this.trustedPromise = this.trustedFunc();
|
this.trustedPromise = this.trustedFunc();
|
||||||
|
Loading…
Reference in New Issue
Block a user