// ĠCopyright Ġ 2 0 0 0 - 2 0 2 0 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ package Ġcom . intellij . openapi . vfs . impl . local Ċ Ċ import Ġcom . intellij . openapi . application . run Write Action Ċ import Ġcom . intellij . openapi . diagnostic . Logger Ċ import Ġcom . intellij . openapi . util . Pair Ċ import Ġcom . intellij . openapi . util . io . Io TestUtil . assume Nio Sym Link Creation Is Supported Ċ import Ġcom . intellij . openapi . vfs . Local FileSystem Ċ import Ġcom . intellij . openapi . vfs . V fs Util Core Ċ import Ġcom . intellij . openapi . vfs . Virtual File Ċ import Ġcom . intellij . openapi . vfs . Virtual File Visitor Ċ import Ġcom . intellij . openapi . vfs . local . File Watcher TestUtil Ċ import Ġcom . intellij . test Framework . Platform TestUtil Ċ import Ġcom . intellij . test Framework . Skip Slow Test Loc ally Ċ import Ġcom . intellij . test Framework . fixtures . B are TestFixture TestCase Ċ import Ġcom . intellij . test Framework . rules . Temp Directory Ċ import Ġcom . intellij . test Framework . run In Ed t And Wait Ċ import Ġcom . intellij . util . Timeout Util Ċ import Ġorg . junit . After Ċ import Ġorg . junit . Before Ċ import Ġorg . junit . Rule Ċ import Ġorg . junit . Test Ċ import Ġjava . io . File Ċ import Ġjava . nio . file . Files Ċ import Ġjava . util .* Ċ import Ġkotlin . collections . ArrayList Ċ import Ġkotlin . test . assertFalse Ċ import Ġkotlin . test . assertTrue Ċ Ċ @ Skip Slow Test Loc ally Ċ class ĠWatch Roots Manager Performance Test Ġ: ĠB are TestFixture TestCase () Ġ{ ĊĠ Ġ// < editor - fold Ġdesc =" Set Ġup Ġ/ Ġtear Ġdown "> ĊĠ Ġprivate Ġval ĠLOG : ĠLogger Ġby Ġlazy Ġ{ ĠLogger . getInstance ( Native File Watcher Impl :: class . java ) Ġ} ĊĊĠ Ġ@ Rule ĊĠ Ġ@ Jvm Field ĊĠ Ġval Ġtemp Dir Ġ= ĠTemp Directory () ĊĊĠ Ġprivate Ġlateinit Ġvar Ġfs : ĠLocal FileSystem ĊĠ Ġprivate Ġlateinit Ġvar Ġroot : ĠVirtual File ĊĠ Ġprivate Ġlateinit Ġvar Ġwatcher : ĠFile Watcher ĊĊĠ Ġ@ Before ĊĠ Ġfun ĠsetUp () Ġ{ ĊĠĠĠ ĠLOG . debug (" ================== Ġsetting Ġup Ġ" Ġ+ Ġget Test Name ( false ) Ġ+ Ġ" Ġ================= =") ĊĊĠĠĠ Ġfs Ġ= ĠLocal FileSystem . getInstance () ĊĠĠĠ Ġroot Ġ= Ġrefresh ( temp Dir . root ) ĊĊĠĠĠ Ġrun In Ed t And Wait Ġ{ Ġfs . refresh ( false ) Ġ} ĊĠĠĠ Ġrun In Ed t And Wait Ġ{ Ġfs . refresh ( false ) Ġ} ĊĊĠĠĠ Ġwatcher Ġ= Ġ( fs Ġas ĠLocal FileSystem Impl ). file Watcher ĊĠĠĠ ĠassertFalse ( watcher . is Operation al ) ĊĠĠĠ ĠFile Watcher TestUtil . startup ( watcher ) Ġ{} ĊĊĠĠĠ ĠLOG . debug (" ================== Ġsetting Ġup Ġ" Ġ+ Ġget Test Name ( false ) Ġ+ Ġ" Ġ================= =") ĊĠ Ġ} ĊĊĠ Ġ@ After ĊĠ Ġfun ĠtearDown () Ġ{ ĊĠĠĠ ĠLOG . debug (" ================== Ġtear ing Ġdown Ġ" Ġ+ Ġget Test Name ( false ) Ġ+ Ġ" Ġ================= =") ĊĊĠĠĠ Ġif Ġ( this :: watcher . isInitialized ) Ġ{ ĊĠĠĠĠĠ ĠFile Watcher TestUtil . shutdown ( watcher ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrun In Ed t And Wait Ġ{ ĊĠĠĠĠĠ Ġrun Write Action Ġ{ Ġroot . delete ( this ) Ġ} ĊĠĠĠĠĠ Ġ( fs Ġas ĠLocal FileSystem Impl ). cleanup For Next Test () ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠLOG . debug (" ================== Ġtear ing Ġdown Ġ" Ġ+ Ġget Test Name ( false ) Ġ+ Ġ" Ġ================= =") ĊĠ Ġ} ĊĠ Ġ// </ editor - fold > ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġtest Watch Roots Add Only Timing () Ġ{ ĊĠĠĠ Ġval Ġroot Ġ= Ġtemp Dir . new Directory (" root ") ĊĠĠĠ Ġval Ġfile Count Ġ= Ġ 5 0 _ 0 0 0 ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ ĠPlatform TestUtil . start Performance Test (" Adding Ġroots ", Ġ 9 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrequests Ġ= ĠArrayList < Local FileSystem . Watch Request >( file Count ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. file Count ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġrequests . add ( fs . add Root To Watch ( File ( root , Ġ" f $ i "). path , Ġtrue ) !! ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfs . remove W atched Roots ( requests ) ĊĠĠĠĠĠ Ġ}. assert Timing () ĊĠĠĠ Ġ} ĊĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠ Ġwait Ġ{ Ġwatcher . is Setting Roots Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġtest Watch Roots Bulk Add Only Timing () Ġ{ ĊĠĠĠ Ġval Ġroot Ġ= Ġtemp Dir . new Directory (" root ") ĊĠĠĠ Ġval Ġfile Count Ġ= Ġ 1 0 0 _ 0 0 0 ĊĠĠĠ Ġrefresh ( root ) ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ ĠPlatform TestUtil . start Performance Test (" Adding Ġroots ", Ġ 1 3 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfs . remove W atched Roots ( fs . add Root sTo Watch (( 1 .. file Count ). map Ġ{ ĠFile ( root , Ġ" f $ it "). path Ġ}, Ġtrue )) ĊĠĠĠĠĠ Ġ}. assert Timing () ĊĠĠĠ Ġ} ĊĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠ Ġwait Ġ{ Ġwatcher . is Setting Roots Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġtest Add Watch Root With Many Symbolic Links () Ġ{ ĊĠĠĠ Ġassume Nio Sym Link Creation Is Supported () ĊĠĠĠ Ġval Ġroot Ġ= Ġtemp Dir . new Directory (" root ") ĊĊĠĠĠ Ġval Ġlink Count Ġ= Ġ 2 0 _ 0 0 0 ĊĊĠĠĠ Ġ( 1 .. link Count ). forEach Ġ{ ĊĠĠĠĠĠ ĠFiles . create Symbolic Link ( File ( root , Ġ" l $ it "). to Path (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemp Dir . new Directory (" targets / d $ it "). to Path ()) ĊĠĠĠ Ġ} ĊĠĠĠ Ġrefresh ( root ) ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ ĠPlatform TestUtil . start Performance Test (" Adding Ġroots ", Ġ 2 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfs . remove W atched Root ( fs . add Root To Watch ( root . path , Ġtrue ) !! ) ĊĠĠĠĠĠ Ġ}. assert Timing () ĊĠĠĠ Ġ} ĊĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠ Ġwait Ġ{ Ġwatcher . is Setting Roots Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġtest Create Canonical Path Map () Ġ{ ĊĠĠĠ Ġval Ġroot Ġ= Ġtemp Dir . new Directory (" root "). path . replace ('\\ ', Ġ'/') ĊĠĠĠ Ġval Ġflat Watch Roots Ġ= ĠTree Set < String >() ĊĠĠĠ Ġval Ġoptimized Recursive Watch Roots Ġ= ĠTree Set < String >() ĊĠĠĠ Ġval Ġpath Mappings Ġ= ĠWatch Roots Util . create Mappings Navig able Set () ĊĊĠĠĠ Ġval Ġfiles Count Ġ= Ġ 1 0 _ 0 0 0 ĊĠĠĠ Ġ( 1 .. files Count ). forEach Ġ{ i Ġ-> ĊĠĠĠĠĠ Ġoptimized Recursive Watch Roots . add ("$ root / rec $ i ") ĊĠĠĠĠĠ Ġ( 1 .. 5 ). forEach Ġ{ Ġflat Watch Roots . add ("$ root / rec $ i / flat $ it ") Ġ} ĊĠĠĠĠĠ Ġflat Watch Roots . add ("$ root / flat $ i ") ĊĠĠĠĠĠ Ġ( 1 .. 5 ). forEach Ġ{ Ġpath Mappings . add ( Pair ("$ root / rec $ i / ln $ it ", Ġ"$ root / targets / rec $ i / ln $ it ")) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠPlatform TestUtil . start Performance Test (" Create Ġcanonical Ġpath Ġmap ", Ġ 7 0 0 0 ) Ġ{ ĊĠĠĠĠĠ Ġrepeat ( 1 8 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠWatch Roots Manager . create Canonical Path Map ( flat Watch Roots , Ġoptimized Recursive Watch Roots , Ġpath Mappings , Ġfalse ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}. assert Timing () ĊĊĠĠĠ ĠPlatform TestUtil . start Performance Test (" Create Ġcanonical Ġpath Ġmap Ġ- Ġconvert Ġpaths ", Ġ 1 0 0 0 0 ) Ġ{ ĊĠĠĠĠĠ Ġrepeat ( 1 8 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠWatch Roots Manager . create Canonical Path Map ( flat Watch Roots , Ġoptimized Recursive Watch Roots , Ġpath Mappings , Ġtrue ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}. assert Timing () ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġtest Canonical Path Map With Many S ymlink s () Ġ{ ĊĠĠĠ Ġval Ġroot Ġ= Ġ"/ users / foo / workspace " ĊĠĠĠ Ġval Ġflat Watch Roots Ġ= ĠTree Set < String >() ĊĠĠĠ Ġval Ġoptimized Recursive Watch Roots Ġ= ĠTree Set < String >() ĊĠĠĠ Ġval Ġpath Mappings Ġ= ĠWatch Roots Util . create Mappings Navig able Set () ĊĊĠĠĠ Ġval Ġfiles Count Ġ= Ġ 1 0 0 _ 0 0 0 ĊĠĠĠ Ġoptimized Recursive Watch Roots . add ("$ root / targets ") ĊĠĠĠ Ġoptimized Recursive Watch Roots . add ("$ root / src ") ĊĠĠĠ Ġ( 1 .. files Count ). forEach Ġ{ i Ġ-> ĊĠĠĠĠĠ Ġpath Mappings . add ( Pair ("$ root / src / ln $ i ", Ġ"$ root / targets / ln $ i - 1 ")) ĊĠĠĠĠĠ Ġpath Mappings . add ( Pair ("$ root / src / ln $ i ", Ġ"$ root / targets / ln $ i - 2 ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġmap Ġ= ĠWatch Roots Manager . create Canonical Path Map ( flat Watch Roots , Ġoptimized Recursive Watch Roots , Ġpath Mappings , Ġfalse ) ĊĠĠĠ Ġmap . add Mapping (( 1 .. files Count ). map Ġ{ ĠPair ("$ root / src / ln $ it - 3 ", Ġ"$ root / src / ln $ it - 3 ") Ġ}) ĊĠĠĠ ĠPlatform TestUtil . start Performance Test (" Test Ġapply Ġmapping Ġfrom Ġcanonical Ġpath Ġmap ", Ġ 3 0 0 0 ) Ġ{ ĊĠĠĠĠĠ Ġrepeat ( 1 _ 0 0 0 _ 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmap . map To Original Watch Roots ("$ root / src / ln ${ ( Math . random () Ġ* Ġ 2 0 0 _ 0 0 0 ). toInt () }", Ġtrue ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}. assert Timing () ĊĊĠĠĠ ĠPlatform TestUtil . start Performance Test (" Create Ġcanonical Ġpath Ġmap ", Ġ 3 0 0 0 ) Ġ{ ĊĠĠĠĠĠ Ġrepeat ( 1 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠWatch Roots Manager . create Canonical Path Map ( flat Watch Roots , Ġoptimized Recursive Watch Roots , Ġpath Mappings , Ġfalse ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}. assert Timing () ĊĊĠĠĠ ĠPlatform TestUtil . start Performance Test (" Create Ġcanonical Ġpath Ġmap Ġ- Ġconvert Ġpaths ", Ġ 3 0 0 0 ) Ġ{ ĊĠĠĠĠĠ Ġrepeat ( 4 0 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠWatch Roots Manager . create Canonical Path Map ( flat Watch Roots , Ġoptimized Recursive Watch Roots , Ġpath Mappings , Ġtrue ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}. assert Timing () ĊĠ Ġ} ĊĊĠ Ġinternal Ġfun Ġwait ( timeout : ĠLong Ġ= ĠFile Watcher TestUtil . START _ STOP _ DELAY , Ġcondition : Ġ() Ġ-> ĠBoolean ) Ġ{ ĊĠĠĠ Ġval Ġstop At Ġ= ĠSystem . currentTimeMillis () Ġ+ Ġtimeout ĊĠĠĠ Ġwhile Ġ( condition ()) Ġ{ ĊĠĠĠĠĠ ĠassertTrue ( System . currentTimeMillis () Ġ< Ġstop At , Ġ" operation Ġtimed Ġout ") ĊĠĠĠĠĠ ĠTimeout Util . sleep ( 0 ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġrefresh ( file : ĠFile ): ĠVirtual File Ġ{ ĊĠĠĠ Ġval Ġv File Ġ= Ġfs . refresh And Find File By Io File ( file ) Ġ?: Ġthrow ĠIllegalStateException (" can 't Ġget Ġ'${ file . path }' Ġinto ĠV FS ") ĊĠĠĠ ĠV fs Util Core . visit Children Re cursively ( v File , Ġobject Ġ: ĠVirtual File Visitor < Any >() Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġvisit File ( file : ĠVirtual File ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġfile . children ; Ġreturn Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠĠĠ Ġv File . refresh ( false , Ġtrue ) ĊĠĠĠ Ġreturn Ġv File ĊĠ Ġ} Ċ } Ċ