function sahModesAreContentious(mode1, mode2) { return primitiveModesAreContentious('readwrite', mode1, mode2);
}
function wfsModesAreContentious(mode1, mode2) { return primitiveModesAreContentious('exclusive', mode1, mode2);
}
// Array of separators used to separate components in hierarchical paths. // Consider both '/' and '\' as path separators to ensure file names are // platform-agnostic.
let kPathSeparators = ['/', '\\'];
async function cleanup(test, value, cleanup_func) { if (fs_cleanups.length === 0) { // register to get called back once from cleanup
test.add_cleanup(async () => { // Cleanup in LIFO order to ensure locks are released correctly relative // to thinks like removeEntry(). Do so in a serialized form, not in parallel!
fs_cleanups.reverse(); for (let cleanup of fs_cleanups) { try {
await cleanup();
} catch (e) { // Ignore any errors when removing files, as tests might already remove // the file.
}
}
fs_cleanups.length = 0;
});
}
fs_cleanups.push(cleanup_func); return value;
}
async function cleanup_writable(test, value) { return cleanup(test, value, async () => { try { return (await value).close();
} catch (e) { // Ignore any errors when closing writables, since attempting to close // aborted or closed writables will error.
}
});
}
function getUniqueName(name) { return `unique${Date.now()}${Math.random().toString().slice(2)}`;
}
// Releases a lock created by one of the create*WithCleanup functions below.
async function releaseLock(lockPromise) { const result = await lockPromise; if (result?.close) {
await result.close();
}
}
function createRemoveWithCleanup(t, fileHandle) { return cleanupLockPromise(t, fileHandle.remove({recursive: true}));
}
// For each key in `testFuncs` if there is a matching key in `testDescs`, // creates a directory_test passing the respective key's value for the func and // description arguments. If there is not a matching key in `testDescs`, the // test is not created. This will throw if `testDescs` contains a key that is // not in `testFuncs`. function selectDirectoryTests(testDescs, testFuncs) { for (const testDesc in testDescs) { if (!testFuncs.hasOwnProperty(testDesc)) { thrownew Error( 'Passed a test description in testDescs that wasn\'t in testFuncs.');
}
directory_test(testFuncs[testDesc], testDescs[testDesc]);
}
}
// Adds tests to test the interaction between a lock created by `createLock1` // and a lock created by `createLock2`. // // The description of each test is passed in through `testDescs`. If a test // description is omitted, it is not run. // // For all tests, `createLock1` is called first. function generateCrossLockTests(createLock1, createLock2, testDescs) { if (testDescs === undefined) { thrownew Error('Must pass testDescs.');
}
selectDirectoryTests(testDescs, {
// This tests that a lock can't be acquired on a file that already has a // lock of another type.
sameFile: async (t, rootDir) => { const [fileHandle] = await createFileHandles(rootDir, 'BFS.test');
// This tests that a lock on one file does not interfere with the creation // of a lock on another file.
diffFile: async (t, rootDir) => { const [fooFileHandle, barFileHandle] =
await createFileHandles(rootDir, 'foo.test', 'bar.test');
// This tests that after a lock has been acquired on a file and then // released, another lock of another type can be acquired. This will fail if // `createLock1` and `createLock2` create the same shared lock.
acquireAfterRelease: async (t, rootDir) => {
let [fileHandle] = await createFileHandles(rootDir, 'BFS.test');
await releaseLock(lockPromise); // Recreate the file in case releasing the lock moves/removes it.
[fileHandle] = await createFileHandles(rootDir, 'BFS.test');
await createLock2(t, fileHandle);
},
// This tests that after multiple locks of some shared lock type have been // acquired on a file and then all released, another lock of another lock // type can be acquired.
multiAcquireAfterRelease: async (t, rootDir) => { const [fileHandle] = await createFileHandles(rootDir, 'BFS.test');
// This tests that a lock taken on a directory prevents a lock being // acquired on a file contained within that directory.
takeDirThenFile: async (t, rootDir) => { const dirHandle = await rootDir.getDirectoryHandle('foo', {create: true}); const [fileHandle] = await createFileHandles(dirHandle, 'BFS.test');
// This tests that a lock acquired on a file prevents a lock being acquired // on an ancestor of that file.
takeFileThenDir: async (t, rootDir) => { const grandparentHandle =
await rootDir.getDirectoryHandle('foo', {create: true}); const parentHandle =
await grandparentHandle.getDirectoryHandle('bar', {create: true});
let [fileHandle] = await createFileHandles(parentHandle, 'BFS.test');
// Release the lock so we can recreate it.
await releaseLock(lock1); // Recreate the file in case releasing the lock moves/removes it.
[fileHandle] = await createFileHandles(parentHandle, 'BFS.test');
// Tests whether the multiple locks can be created by createLock on a file // handle or if only one can. Returns LOCK_ACCESS.SHARED for the former and // LOCK_ACCESS.EXCLUSIVE for the latter.
async function testLockAccess(t, fileHandle, createLock) {
createLock(t, fileHandle);
// Creates a test with description `testDesc` to test behavior of the BFCache // with `testFunc`. function createBFCacheTest(testFunc, testDesc) { // In the remote context `rc`, calls the `funcName` export of // `bfcache-test-page.js` with `args`. // // Will import `bfcache-test-page.js` if it hasn't been imported already. function executeFunc(rc, funcName, args) { return rc.executeScript(async (funcName, args) => { if (self.testPageFuncs === undefined) {
self.testPageFuncs =
(await import('/fs/resources/bfcache-test-page.js'));
} return await self.testPageFuncs[funcName](...args);
}, [funcName, args]);
}
promise_test(async t => { const rcHelper = new RemoteContextHelper();
// Open a window with noopener so that BFCache will work. const backRc = await rcHelper.addWindow(null, {features: 'noopener'});
let curRc = backRc;
// Functions given to the test to control the BFCache test. const testControls = { // Returns an array of functions that bind `executeFunc` with curRc and // their respective function name from `funcName`.
getRemoteFuncs: (...funcNames) => { return funcNames.map(
funcName => (...args) => executeFunc(curRc, funcName, args));
},
forward: async () => { if (curRc !== backRc) { thrownew Error('Can only navigate forward once.');
}
prepareForBFCache(curRc);
curRc = await curRc.navigateToNew();
},
back: async (shouldRestoreFromBFCache) => { if (curRc === backRc) { thrownew Error( 'Can\'t navigate back if you haven\'t navigated forward.');
}
await curRc.historyBack();
curRc = backRc; if (shouldRestoreFromBFCache) {
await assertImplementsBFCacheOptional(curRc);
} else {
await assertNotRestoredFromBFCache(curRc);
}
},
assertBFCacheEligibility(shouldRestoreFromBFCache) { return assertBFCacheEligibility(curRc, shouldRestoreFromBFCache);
}
};
await testFunc(t, testControls);
}, testDesc);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.