| importScripts('/resources/testharness.js'); |
| importScripts('resources/sandboxed-fs-test-helpers.js'); |
| importScripts('resources/test-helpers.js'); |
| |
| 'use strict'; |
| |
| // Adds tests to test the interaction between a lock created by the move |
| // operation and a lock created by `createLock`. |
| function generateCrossLockMoveTests(lockName, createLock) { |
| generateCrossLockTests(createMoveWithCleanup, createLock, { |
| diffFile: `A file with an ongoing move operation does not interfere with` + |
| ` ${lockName} on another file`, |
| acquireAfterRelease: `After a file has finished moving, that file can` + |
| ` have ${lockName}`, |
| // TODO(https://github.com/whatwg/fs/pull/10): Add tests for directory moves |
| // once supported. |
| }); |
| |
| directory_test(async (t, rootDir) => { |
| const [fooFileHandle, barFileHandle] = |
| await createFileHandles(rootDir, 'foo.test', 'bar.test'); |
| |
| createLock(t, fooFileHandle); |
| await promise_rejects_dom( |
| t, 'NoModificationAllowedError', |
| createMoveWithCleanup(t, barFileHandle, 'foo.test')); |
| }, `A file cannot be moved to a location with ${lockName}`); |
| } |
| |
| // Adds tests to test the interaction between a lock created by the remove |
| // operation and a lock created by `createLock`. |
| function generateCrossLockRemoveTests(lockName, createLock) { |
| generateCrossLockTests(createRemoveWithCleanup, createLock, { |
| diffFile: `A file with an ongoing remove operation does not interfere` + |
| ` with the creation of ${lockName} on another file`, |
| acquireAfterRelease: `After a file has finished being removed, that file` + |
| ` can have ${lockName}`, |
| }); |
| generateCrossLockTests(createLock, createRemoveWithCleanup, { |
| takeFileThenDir: `A directory cannot be removed if it contains a file` + |
| ` that has ${lockName}.`, |
| }); |
| } |
| |
| // Gets the name of a writable file stream opened in `wfsMode` to be used in |
| // tests. |
| function getWFSLockName(wfsMode) { |
| return `an open writable stream in ${wfsMode} mode` |
| } |
| |
| // Adds tests to test the interaction between a lock created by an open writable |
| // and a lock created by `createLock`. |
| function generateCrossLockWFSTests(lockName, createLock, wfsMode) { |
| const WFSLockName = getWFSLockName(wfsMode); |
| const tests = { |
| sameFile: `When there's ${WFSLockName} on a file, cannot have` + |
| ` ${lockName} on that same file`, |
| diffFile: `A file with ${WFSLockName} does not interfere with` + |
| ` ${lockName} on another file`, |
| }; |
| if (wfsMode === 'siloed') { |
| tests.multiAcquireAfterRelease = `After all writable streams in siloed` + |
| ` mode have been closed for a file, that file can have ${lockName}`; |
| } else { |
| tests.acquireAfterRelease = `After a writable stream in exclusive mode` + |
| ` has been closed for a file, that file can have ${lockName}`; |
| } |
| generateCrossLockTests( |
| createWFSWithCleanupFactory({mode: wfsMode}), createLock, tests); |
| } |
| |
| // Adds tests to test the interaction between a lock created by an open access |
| // handle in `sahMode and locks created by other file primitives and operations. |
| function generateCrossLockSAHTests(sahMode) { |
| const createSAHLock = createSAHWithCleanupFactory({mode: sahMode}); |
| const SAHLockName = `an open access handle in ${sahMode} mode`; |
| |
| // Test interaction between move locks and SAH locks. |
| generateCrossLockMoveTests(SAHLockName, createSAHLock); |
| generateCrossLockTests(createSAHLock, createMoveWithCleanup, { |
| sameFile: `A file with ${SAHLockName} cannot be moved`, |
| diffFile: `A file with ${SAHLockName} does not interfere with moving` + |
| ` another file`, |
| acquireAfterRelease: `After ${SAHLockName} on a file has been closed,` + |
| ` that file can be moved`, |
| }); |
| |
| // Test interaction between remove locks and SAH locks. |
| generateCrossLockRemoveTests(SAHLockName, createSAHLock); |
| generateCrossLockTests(createSAHLock, createRemoveWithCleanup, { |
| sameFile: `A file with ${SAHLockName} cannot be removed`, |
| diffFile: `A file with ${SAHLockName} does not interfere with removing` + |
| ` another file`, |
| acquireAfterRelease: `After ${SAHLockName} on a file has been closed,` + |
| ` that file can be removed`, |
| }); |
| |
| // Test interaction between WFS locks and SAH locks. |
| for (const wfsMode of WFS_MODES) { |
| const WFSLockName = getWFSLockName(wfsMode); |
| const wfsOptions = {mode: wfsMode}; |
| generateCrossLockWFSTests(SAHLockName, createSAHLock, wfsMode); |
| generateCrossLockTests( |
| createSAHLock, createWFSWithCleanupFactory(wfsOptions), { |
| sameFile: `When there's ${SAHLockName} on a file, cannot open` + |
| ` ${WFSLockName} on that same file`, |
| diffFile: `A file with ${SAHLockName} does not interfere with the` + |
| ` creation of ${WFSLockName} on another file`, |
| }); |
| } |
| } |
| |
| // Test interaction for each SAH lock mode. |
| for (const sahMode of SAH_MODES) { |
| generateCrossLockSAHTests(sahMode); |
| } |
| |
| // Test interaction for each WFS lock mode. |
| for (const wfsMode of WFS_MODES) { |
| const WFSLockName = getWFSLockName(wfsMode); |
| const wfsOptions = {mode: wfsMode}; |
| // Test interaction between move locks and WFS locks. |
| generateCrossLockMoveTests( |
| WFSLockName, createWFSWithCleanupFactory(wfsOptions)); |
| generateCrossLockWFSTests( |
| 'an ongoing move operation', createMoveWithCleanup, wfsMode); |
| |
| // Test interaction between remove locks and WFS locks. |
| generateCrossLockRemoveTests( |
| WFSLockName, createWFSWithCleanupFactory(wfsOptions)); |
| generateCrossLockWFSTests( |
| 'an ongoing remove operation', createRemoveWithCleanup, wfsMode); |
| } |
| |
| done(); |