@@ -7,6 +7,7 @@ import os from 'os';
77import path from 'path' ;
88import fs from 'fs' ;
99import { DB } from '@matrixai/db' ;
10+ import { withF } from '@matrixai/resources' ;
1011import Logger , { LogLevel , StreamHandler } from '@matrixai/logger' ;
1112import { EncryptedFS } from 'encryptedfs' ;
1213import git from 'isomorphic-git' ;
@@ -491,6 +492,8 @@ describe('VaultInternal', () => {
491492 expect ( vaultInterface . writeG ) . toBeTruthy ( ) ;
492493 expect ( vaultInterface . readF ) . toBeTruthy ( ) ;
493494 expect ( vaultInterface . readG ) . toBeTruthy ( ) ;
495+ expect ( vaultInterface . acquireRead ) . toBeTruthy ( ) ;
496+ expect ( vaultInterface . acquireWrite ) . toBeTruthy ( ) ;
494497 expect ( vaultInterface . log ) . toBeTruthy ( ) ;
495498 expect ( vaultInterface . version ) . toBeTruthy ( ) ;
496499
@@ -873,6 +876,82 @@ describe('VaultInternal', () => {
873876 expect ( finished . length ) . toBe ( 4 ) ;
874877 await releaseRead ( ) ;
875878 } ) ;
879+ test ( 'can acquire a read resource' , async ( ) => {
880+ await vault . writeF ( async ( efs ) => {
881+ await efs . writeFile ( secret1 . name , secret1 . content ) ;
882+ } ) ;
883+ const acquireRead = vault . acquireRead ( ) ;
884+ await withF ( [ acquireRead ] , async ( [ efs ] ) => {
885+ const content = await efs . readFile ( secret1 . name ) ;
886+ expect ( content . toString ( ) ) . toEqual ( secret1 . content ) ;
887+ } ) ;
888+ } ) ;
889+ test ( 'acquiring read resource respects locking' , async ( ) => {
890+ const lock = vault . getLock ( ) ;
891+ const [ releaseWrite ] = await lock . write ( ) ( ) ;
892+ let finished = false ;
893+ const readP = withF ( [ vault . acquireRead ( ) ] , async ( ) => {
894+ finished = true ;
895+ } ) ;
896+ await sleep ( waitDelay ) ;
897+ expect ( finished ) . toBe ( false ) ;
898+ await releaseWrite ( ) ;
899+ await readP ;
900+ expect ( finished ) . toBe ( true ) ;
901+ } ) ;
902+ test ( 'acquiring read resource allows concurrency' , async ( ) => {
903+ const lock = vault . getLock ( ) ;
904+ const [ releaseRead ] = await lock . read ( ) ( ) ;
905+ const finished : Array < boolean > = [ ] ;
906+ const read1P = withF ( [ vault . acquireRead ( ) ] , async ( ) => {
907+ finished . push ( true ) ;
908+ } ) ;
909+ const read2P = withF ( [ vault . acquireRead ( ) ] , async ( ) => {
910+ finished . push ( true ) ;
911+ } ) ;
912+ const read3P = withF ( [ vault . acquireRead ( ) ] , async ( ) => {
913+ finished . push ( true ) ;
914+ } ) ;
915+ await Promise . all ( [ read1P , read2P , read3P ] ) ;
916+ expect ( finished . length ) . toBe ( 3 ) ;
917+ await releaseRead ( ) ;
918+ } ) ;
919+ test ( 'can acquire a write resource' , async ( ) => {
920+ const acquireWrite = vault . acquireWrite ( ) ;
921+ await withF ( [ acquireWrite ] , async ( [ efs ] ) => {
922+ await efs . writeFile ( secret1 . name , secret1 . content ) ;
923+ } ) ;
924+ await vault . readF ( async ( efs ) => {
925+ const content = await efs . readFile ( secret1 . name ) ;
926+ expect ( content . toString ( ) ) . toEqual ( secret1 . content ) ;
927+ } ) ;
928+ } ) ;
929+ test ( 'acquiring write resource respects write locking' , async ( ) => {
930+ const lock = vault . getLock ( ) ;
931+ const [ releaseWrite ] = await lock . write ( ) ( ) ;
932+ let finished = false ;
933+ const writeP = withF ( [ vault . acquireWrite ( ) ] , async ( ) => {
934+ finished = true ;
935+ } ) ;
936+ await sleep ( waitDelay ) ;
937+ expect ( finished ) . toBe ( false ) ;
938+ await releaseWrite ( ) ;
939+ await writeP ;
940+ expect ( finished ) . toBe ( true ) ;
941+ } ) ;
942+ test ( 'acquiring write resource respects read locking' , async ( ) => {
943+ const lock = vault . getLock ( ) ;
944+ const [ releaseRead ] = await lock . read ( ) ( ) ;
945+ let finished = false ;
946+ const writeP = withF ( [ vault . acquireWrite ( ) ] , async ( ) => {
947+ finished = true ;
948+ } ) ;
949+ await sleep ( waitDelay ) ;
950+ expect ( finished ) . toBe ( false ) ;
951+ await releaseRead ( ) ;
952+ await writeP ;
953+ expect ( finished ) . toBe ( true ) ;
954+ } ) ;
876955 // Life-cycle
877956 test ( 'can create with CreateVaultInternal' , async ( ) => {
878957 let vault1 : VaultInternal | undefined ;
0 commit comments