Skip to content

Commit 71632ce

Browse files
committed
Improve isolation of build artefacts of test runs
Even though we copy test files into temporary directories, we used to reuse the same cache directory for build artefacts, hiedb and compilation artefacts. While there is practially no chance this causes any issues for the test runs themselves, it litters the cache directory with a lot of files. So, we create one main directory in the temporary directory, and generate all caches and in there. This makes it trivial to delete all test caches, without risking deleting the cache that is still used.
1 parent 5502b76 commit 71632ce

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

hls-test-utils/hls-test-utils.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ library
4646
, lens
4747
, lsp-test ^>=0.17
4848
, lsp-types ^>=2.1
49+
, safe-exceptions
4950
, tasty
5051
, tasty-expected-failure
5152
, tasty-golden

hls-test-utils/src/Test/Hls.hs

+40-9
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ import Control.Concurrent.Async (async, cancel, wait)
6565
import Control.Concurrent.Extra
6666
import Control.Exception.Base
6767
import Control.Lens.Extras (is)
68-
import Control.Monad (guard, unless, void)
68+
import Control.Monad (guard, unless, void, when)
6969
import Control.Monad.Extra (forM)
7070
import Control.Monad.IO.Class
7171
import Data.Aeson (Result (Success),
@@ -106,11 +106,14 @@ import Language.LSP.Protocol.Message
106106
import Language.LSP.Protocol.Types hiding (Null)
107107
import Language.LSP.Test
108108
import Prelude hiding (log)
109-
import System.Directory (getCurrentDirectory,
109+
import System.Directory (createDirectory,
110+
doesDirectoryExist,
111+
getCurrentDirectory,
112+
getTemporaryDirectory,
110113
setCurrentDirectory)
111-
import System.Environment (lookupEnv)
114+
import System.Environment (lookupEnv, setEnv)
112115
import System.FilePath
113-
import System.IO.Extra (newTempDir, withTempDir)
116+
import System.IO.Extra (newTempDirWithin)
114117
import System.IO.Unsafe (unsafePerformIO)
115118
import System.Process.Extra (createPipe)
116119
import System.Time.Extra
@@ -423,22 +426,24 @@ runSessionWithServerInTmpDir' ::
423426
Session a ->
424427
IO a
425428
runSessionWithServerInTmpDir' plugins conf sessConf caps tree act = withLock lockForTempDirs $ do
429+
testRoot <- setupTestEnvironment
426430
(recorder, _) <- initialiseTestRecorder
427431
["LSP_TEST_LOG_STDERR", "HLS_TEST_HARNESS_STDERR", "HLS_TEST_LOG_STDERR"]
428432

429433
-- Do not clean up the temporary directory if this variable is set to anything but '0'.
430434
-- Aids debugging.
431435
cleanupTempDir <- lookupEnv "HLS_TEST_HARNESS_NO_TESTDIR_CLEANUP"
432-
let runTestInDir = case cleanupTempDir of
436+
let runTestInDir action = case cleanupTempDir of
433437
Just val
434-
| val /= "0" -> \action -> do
435-
(tempDir, _) <- newTempDir
438+
| val /= "0" -> do
439+
(tempDir, _) <- newTempDirWithin testRoot
436440
a <- action tempDir
437441
logWith recorder Debug LogNoCleanup
438442
pure a
439443

440-
_ -> \action -> do
441-
a <- withTempDir action
444+
_ -> do
445+
(tempDir, cleanup) <- newTempDirWithin testRoot
446+
a <- action tempDir `finally` cleanup
442447
logWith recorder Debug LogCleanup
443448
pure a
444449

@@ -447,6 +452,32 @@ runSessionWithServerInTmpDir' plugins conf sessConf caps tree act = withLock loc
447452
_fs <- FS.materialiseVFT tmpDir tree
448453
runSessionWithServer' plugins conf sessConf caps tmpDir act
449454

455+
-- | Setup the test environment for isolated tests.
456+
--
457+
-- This creates a directory in the temporary directory that will be
458+
-- reused for running isolated tests.
459+
-- It returns the root to the testing directory that tests should use.
460+
-- This directory is not fully cleaned between reruns.
461+
-- However, it is totally safe to delete the directory between runs.
462+
--
463+
-- Additionally, this overwrites the 'XDG_CACHE_HOME' variable to isolate
464+
-- the tests from existing caches. 'hie-bios' and 'ghcide' honour the
465+
-- 'XDG_CACHE_HOME' environment variable and generate their caches there.
466+
setupTestEnvironment :: IO FilePath
467+
setupTestEnvironment = do
468+
tmpDirRoot <- getTemporaryDirectory
469+
let testRoot = tmpDirRoot </> "hls-test-root"
470+
testCacheDir = testRoot </> ".cache"
471+
createDirectoryIfMissing testRoot
472+
createDirectoryIfMissing testCacheDir
473+
setEnv "XDG_CACHE_HOME" testCacheDir
474+
pure testRoot
475+
where
476+
createDirectoryIfMissing fp = do
477+
exists <- doesDirectoryExist fp
478+
when (not exists) $ do
479+
createDirectory fp
480+
450481
goldenWithHaskellDocFormatter
451482
:: Pretty b
452483
=> Config

0 commit comments

Comments
 (0)