WIP: config.json caching/verification; some tests fixed, v1:verified cache implemented (ref. #48)

merge-requests/23/merge
Michał 'rysiek' Woźniak 2024-02-01 23:46:10 +00:00
rodzic 5bca087442
commit 0fe53bcc20
2 zmienionych plików z 92 dodań i 19 usunięć

Wyświetl plik

@ -289,16 +289,16 @@ beforeEach(async ()=>{
// clear the caches
await caches
.has('v1')
.then(async (hasv1) => {
if (hasv1) {
.then(async (hasit) => {
if (hasit) {
await caches.delete('v1')
}
})
await caches
.has('v1:temp')
.then(async (hasv1) => {
if (hasv1) {
await caches.delete('v1:temp')
.has('v1:verified')
.then(async (hasit) => {
if (hasit) {
await caches.delete('v1:verified')
}
})
// make sure we're starting with a clean slate in LibResilientPluginConstructors
@ -370,6 +370,44 @@ describe('service-worker', async () => {
assertSpyCalls(self.fetch, 1)
})
it("should use default LibResilientConfig values when fetching config.json throws an exception", async () => {
window.fetch = spy(() => {
throw new Error('Testing exception')
})
await import("../../service-worker.js?" + window.test_id);
await self.dispatchEvent(new Event('install'))
await self.waitForSWInstall()
assertEquals(typeof self.LibResilientConfig, "object")
assertEquals(self.LibResilientConfig.defaultPluginTimeout, 10000)
assertEquals(self.LibResilientConfig.plugins, [{name: "fetch"},{name: "cache"}])
assertEquals(self.LibResilientConfig.loggedComponents, ['service-worker', 'fetch', 'cache'])
assertEquals(self.LibResilientConfig.normalizeQueryParams, true)
assertEquals(self.LibResilientConfig.useMimeSniffingLibrary, false)
assertSpyCalls(self.fetch, 1)
})
it("should use default LibResilientConfig values when fetching config.json returns undefined", async () => {
window.fetch = spy(() => {
return undefined;
})
await import("../../service-worker.js?" + window.test_id);
await self.dispatchEvent(new Event('install'))
await self.waitForSWInstall()
assertEquals(typeof self.LibResilientConfig, "object")
assertEquals(self.LibResilientConfig.defaultPluginTimeout, 10000)
assertEquals(self.LibResilientConfig.plugins, [{name: "fetch"},{name: "cache"}])
assertEquals(self.LibResilientConfig.loggedComponents, ['service-worker', 'fetch', 'cache'])
assertEquals(self.LibResilientConfig.normalizeQueryParams, true)
assertEquals(self.LibResilientConfig.useMimeSniffingLibrary, false)
assertSpyCalls(self.fetch, 1)
})
it("should use default LibResilientConfig values when config.json not valid JSON", async () => {
let mock_response_data = {
@ -490,7 +528,7 @@ describe('service-worker', async () => {
assertSpyCalls(self.fetch, 1)
})
it("should use config values from a valid fetched config.json file, caching it", async () => {
it("should use config values from a valid fetched config.json file, caching it in both caches (v1, v1:verified)", async () => {
let mock_response_data = {
data: JSON.stringify({loggedComponents: ['service-worker', 'cache'], plugins: [{name: "cache"}], defaultPluginTimeout: 5000, normalizeQueryParams: false, useMimeSniffingLibrary: true})
}
@ -515,6 +553,10 @@ describe('service-worker', async () => {
await window.waitForCacheAction(window.location.origin + 'config.json', 'v1'),
mock_response_data.data
);
assertEquals(
await window.waitForCacheAction(window.location.origin + 'config.json', 'v1:verified'),
mock_response_data.data
);
})
it("should instantiate a complex tree of configured plugins", async () => {
@ -775,9 +817,17 @@ describe('service-worker', async () => {
assertEquals(self.LibResilientConfig.defaultPluginTimeout, 5000)
assertEquals(self.LibResilientConfig.plugins, [{name: "cache"}])
assertEquals(self.LibResilientConfig.loggedComponents, ['service-worker', 'cache'])
// cacheConfigJSON() is called asynchronously in the Service Worker,
// if we don't make sure that the caching has completed, we will get an error.
// so we wait until config.json is cached, and use that to verify it is in fact cached
assertEquals(
await window.waitForCacheAction(window.location.origin + 'config.json', 'v1:verified'),
mock_response_data.data
);
})
it("should use a stale cached valid config.json file without a fetch, then retrieve and cache a fresh config.json using the configured plugins", async () => {
it("should use a stale cached valid config.json file without a fetch, caching it in v1:verified cache, then retrieve and cache a fresh config.json using the configured plugins", async () => {
// this does not change
var config_url = window.location.origin + 'config.json'
@ -839,6 +889,14 @@ describe('service-worker', async () => {
assertSpyCalls(self.fetch, 0)
assertSpyCalls(resolveConfigFetch, 1)
// cacheConfigJSON() is called asynchronously in the Service Worker,
// if we don't make sure that the caching has completed, we will get an error.
// so we wait until config.json is cached, and use that to verify it is in fact cached
assertEquals(
await window.waitForCacheAction(window.location.origin + 'config.json', 'v1:verified'),
mock_response_data.data
);
// wait until verify the *new* config got cached
// running waitForCacheAdd only once might not be enough, as the cache
// already contained config.json!
@ -847,7 +905,7 @@ describe('service-worker', async () => {
// so as not to end up in a forever loop
for (let i=0; i<100; i++) {
// did we get the new config?
if (await window.waitForCacheAction(config_url, 'v1:temp') === mock_response_data2.data) {
if (await window.waitForCacheAction(config_url, 'v1') === mock_response_data2.data) {
// we did! we're done
return true;
}
@ -855,7 +913,7 @@ describe('service-worker', async () => {
throw new Error('New config failed to cache, apparently!')
})
it("should use a stale cached valid config.json file without a fetch; invalid config.json retrieved using the configured plugins should not be cached", async () => {
it("should use a stale cached valid config.json file without a fetch, caching it in v1:verified cache; invalid config.json retrieved using the configured plugins should not be cached", async () => {
// this does not change
var config_url = window.location.origin + 'config.json'
@ -917,6 +975,14 @@ describe('service-worker', async () => {
assertSpyCalls(self.fetch, 0)
assertSpyCalls(resolveConfigFetch, 1)
// cacheConfigJSON() is called asynchronously in the Service Worker,
// if we don't make sure that the caching has completed, we will get an error.
// so we wait until config.json is cached, and use that to verify it is in fact cached
assertEquals(
await window.waitForCacheAction(window.location.origin + 'config.json', 'v1:verified'),
mock_response_data.data
);
// waiting for potential caching of the "new" config
for (let i=0; i<100; i++) {
// did we get the new config?
@ -927,7 +993,7 @@ describe('service-worker', async () => {
}
})
it("should use a stale cached valid config.json file without a fetch; valid config.json retrieved using the configured plugins other than fetch should not be cached", async () => {
it("should use a stale cached valid config.json file without a fetch; invalid config.json retrieved using the configured plugins other than fetch should not be cached", async () => {
// this does not change
var config_url = window.location.origin + 'config.json'
@ -956,7 +1022,7 @@ describe('service-worker', async () => {
console.log(await resp.text())
})
// prepare the fresh invalid config request/response
// prepare the fresh valid config request/response
let mock_response_data2 = {
data: JSON.stringify({loggedComponents: ['service-worker', 'resolve-config', 'cache'], plugins: [{name: "resolve-config"}, {name: "cache"}], defaultPluginTimeout: 2000}),
headers: {

Wyświetl plik

@ -459,7 +459,7 @@ let initServiceWorker = async () => {
let lrpcBackup = new Map(self.LibResilientPluginConstructors)
// caches to try: temp cache, main cache
let available_caches = ['v1:temp', 'v1']
let available_caches = ['v1', 'v1:verified']
// keep track
let config_executed = false
@ -548,12 +548,19 @@ let initServiceWorker = async () => {
self.LibResilientConfig = config
self.log('service-worker', 'config loaded.')
// we're good, let's cache the config if we need to
// that is, if it comes from the "v1:temp" cache
// we're good, let's cache the config as verified if we need to
// that is, if it comes from the "v1" cache...
if (use_cache === "v1") {
self.log('service-worker', `successfully loaded config.json; caching in cache: v1:verified`)
cacheConfigJSON(configURL, cresponse, 'v1:verified')
// or, was fetch()ed and valid (no caching if we're going with defaults, obviously)
if ( (use_cache === "v1:temp") || ( (use_cache === undefined) && (cresponse !== false) ) ) {
self.log('service-worker', `successfully loaded config.json; caching in cache: v1`)
cacheConfigJSON(configURL, cresponse, 'v1')
} else if ( (use_cache === undefined) && (cresponse !== false) ) {
self.log('service-worker', `successfully loaded config.json; caching in cache: v1, v1:verified`)
// we want to cache to both, so that:
// 1. we get the extra bit of performance from using the v1 cache that is checked first
// 2. but we get the verified config already in the v1:verified cache for later
cacheConfigJSON(configURL, await cresponse.clone(), 'v1')
cacheConfigJSON(configURL, cresponse, 'v1:verified')
}
// inform
@ -622,7 +629,7 @@ let initServiceWorker = async () => {
self.log('service-worker', `valid config.json successfully retrieved through plugins; caching.`)
// cache it, asynchronously, in the temporary cache
// as the config has not been "execute-tested" yet
cacheConfigJSON(configURL, cresponse, "v1:temp")
cacheConfigJSON(configURL, cresponse, "v1")
}
})
}