FileSystemFileHandle-cross-primitive-locking.https.tentative.worker.js (5618B)
1 importScripts('/resources/testharness.js'); 2 importScripts('resources/sandboxed-fs-test-helpers.js'); 3 importScripts('resources/test-helpers.js'); 4 5 'use strict'; 6 7 // Adds tests to test the interaction between a lock created by the move 8 // operation and a lock created by `createLock`. 9 function generateCrossLockMoveTests(lockName, createLock) { 10 generateCrossLockTests(createMoveWithCleanup, createLock, { 11 diffFile: `A file with an ongoing move operation does not interfere with` + 12 ` ${lockName} on another file`, 13 acquireAfterRelease: `After a file has finished moving, that file can` + 14 ` have ${lockName}`, 15 // TODO(https://github.com/whatwg/fs/pull/10): Add tests for directory moves 16 // once supported. 17 }); 18 19 directory_test(async (t, rootDir) => { 20 const [fooFileHandle, barFileHandle] = 21 await createFileHandles(rootDir, 'foo.test', 'bar.test'); 22 23 createLock(t, fooFileHandle); 24 await promise_rejects_dom( 25 t, 'NoModificationAllowedError', 26 createMoveWithCleanup(t, barFileHandle, 'foo.test')); 27 }, `A file cannot be moved to a location with ${lockName}`); 28 } 29 30 // Adds tests to test the interaction between a lock created by the remove 31 // operation and a lock created by `createLock`. 32 function generateCrossLockRemoveTests(lockName, createLock) { 33 generateCrossLockTests(createRemoveWithCleanup, createLock, { 34 diffFile: `A file with an ongoing remove operation does not interfere` + 35 ` with the creation of ${lockName} on another file`, 36 acquireAfterRelease: `After a file has finished being removed, that file` + 37 ` can have ${lockName}`, 38 }); 39 generateCrossLockTests(createLock, createRemoveWithCleanup, { 40 takeFileThenDir: `A directory cannot be removed if it contains a file` + 41 ` that has ${lockName}.`, 42 }); 43 } 44 45 // Gets the name of a writable file stream opened in `wfsMode` to be used in 46 // tests. 47 function getWFSLockName(wfsMode) { 48 return `an open writable stream in ${wfsMode} mode` 49 } 50 51 // Adds tests to test the interaction between a lock created by an open writable 52 // and a lock created by `createLock`. 53 function generateCrossLockWFSTests(lockName, createLock, wfsMode) { 54 const WFSLockName = getWFSLockName(wfsMode); 55 const tests = { 56 sameFile: `When there's ${WFSLockName} on a file, cannot have` + 57 ` ${lockName} on that same file`, 58 diffFile: `A file with ${WFSLockName} does not interfere with` + 59 ` ${lockName} on another file`, 60 }; 61 if (wfsMode === 'siloed') { 62 tests.multiAcquireAfterRelease = `After all writable streams in siloed` + 63 ` mode have been closed for a file, that file can have ${lockName}`; 64 } else { 65 tests.acquireAfterRelease = `After a writable stream in exclusive mode` + 66 ` has been closed for a file, that file can have ${lockName}`; 67 } 68 generateCrossLockTests( 69 createWFSWithCleanupFactory({mode: wfsMode}), createLock, tests); 70 } 71 72 // Adds tests to test the interaction between a lock created by an open access 73 // handle in `sahMode and locks created by other file primitives and operations. 74 function generateCrossLockSAHTests(sahMode) { 75 const createSAHLock = createSAHWithCleanupFactory({mode: sahMode}); 76 const SAHLockName = `an open access handle in ${sahMode} mode`; 77 78 // Test interaction between move locks and SAH locks. 79 generateCrossLockMoveTests(SAHLockName, createSAHLock); 80 generateCrossLockTests(createSAHLock, createMoveWithCleanup, { 81 sameFile: `A file with ${SAHLockName} cannot be moved`, 82 diffFile: `A file with ${SAHLockName} does not interfere with moving` + 83 ` another file`, 84 acquireAfterRelease: `After ${SAHLockName} on a file has been closed,` + 85 ` that file can be moved`, 86 }); 87 88 // Test interaction between remove locks and SAH locks. 89 generateCrossLockRemoveTests(SAHLockName, createSAHLock); 90 generateCrossLockTests(createSAHLock, createRemoveWithCleanup, { 91 sameFile: `A file with ${SAHLockName} cannot be removed`, 92 diffFile: `A file with ${SAHLockName} does not interfere with removing` + 93 ` another file`, 94 acquireAfterRelease: `After ${SAHLockName} on a file has been closed,` + 95 ` that file can be removed`, 96 }); 97 98 // Test interaction between WFS locks and SAH locks. 99 for (const wfsMode of WFS_MODES) { 100 const WFSLockName = getWFSLockName(wfsMode); 101 const wfsOptions = {mode: wfsMode}; 102 generateCrossLockWFSTests(SAHLockName, createSAHLock, wfsMode); 103 generateCrossLockTests( 104 createSAHLock, createWFSWithCleanupFactory(wfsOptions), { 105 sameFile: `When there's ${SAHLockName} on a file, cannot open` + 106 ` ${WFSLockName} on that same file`, 107 diffFile: `A file with ${SAHLockName} does not interfere with the` + 108 ` creation of ${WFSLockName} on another file`, 109 }); 110 } 111 } 112 113 // Test interaction for each SAH lock mode. 114 for (const sahMode of SAH_MODES) { 115 generateCrossLockSAHTests(sahMode); 116 } 117 118 // Test interaction for each WFS lock mode. 119 for (const wfsMode of WFS_MODES) { 120 const WFSLockName = getWFSLockName(wfsMode); 121 const wfsOptions = {mode: wfsMode}; 122 // Test interaction between move locks and WFS locks. 123 generateCrossLockMoveTests( 124 WFSLockName, createWFSWithCleanupFactory(wfsOptions)); 125 generateCrossLockWFSTests( 126 'an ongoing move operation', createMoveWithCleanup, wfsMode); 127 128 // Test interaction between remove locks and WFS locks. 129 generateCrossLockRemoveTests( 130 WFSLockName, createWFSWithCleanupFactory(wfsOptions)); 131 generateCrossLockWFSTests( 132 'an ongoing remove operation', createRemoveWithCleanup, wfsMode); 133 } 134 135 done();