Skip to content

Commit 53f61b4

Browse files
committed
Fix flaky call-hierarchy tests
Wait for index instead of compliation before making requests as indexing happens in the background in parallel with everything else, so we have to synchronize on the database being ready before making any call hierarchy requests.
1 parent aba2644 commit 53f61b4

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

plugins/hls-call-hierarchy-plugin/hls-call-hierarchy-plugin.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ test-suite tests
6060
, filepath
6161
, hls-call-hierarchy-plugin
6262
, hls-test-utils ^>=1.4
63+
, ghcide-test-utils
6364
, lens
6465
, lsp
6566
, lsp-test

plugins/hls-call-hierarchy-plugin/test/Main.hs

+22-8
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import Control.Lens (set, (^.))
99
import Control.Monad.Extra
1010
import Data.Aeson
1111
import Data.Functor ((<&>))
12-
import Data.List (sort)
12+
import Data.List (sort, tails)
1313
import qualified Data.Map as M
1414
import qualified Data.Text as T
1515
import Ide.Plugin.CallHierarchy
1616
import qualified Language.LSP.Test as Test
1717
import qualified Language.LSP.Types.Lens as L
18+
import Development.IDE.Test
1819
import System.Directory.Extra
1920
import System.FilePath
2021
import qualified System.IO.Extra
@@ -198,7 +199,7 @@ incomingCallsTests =
198199
testCase "xdata unavailable" $
199200
runSessionWithServer plugin testDataDir $ do
200201
doc <- createDoc "A.hs" "haskell" $ T.unlines ["a=3", "b=a"]
201-
waitForKickDone
202+
waitForIndex (testDataDir </> "A.hs")
202203
[item] <- Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc 1 0)
203204
let expected = [CallHierarchyIncomingCall item (List [mkRange 1 2 1 3])]
204205
Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc 0 0) >>=
@@ -323,7 +324,7 @@ outgoingCallsTests =
323324
testCase "xdata unavailable" $ withCanonicalTempDir $ \dir ->
324325
runSessionWithServer plugin dir $ do
325326
doc <- createDoc "A.hs" "haskell" $ T.unlines ["a=3", "b=a"]
326-
waitForKickDone
327+
waitForIndex (dir </> "A.hs")
327328
[item] <- Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc 0 1)
328329
let expected = [CallHierarchyOutgoingCall item (List [mkRange 1 2 1 3])]
329330
Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc 1 0) >>=
@@ -427,7 +428,7 @@ incomingCallTestCase :: T.Text -> Int -> Int -> [(Int, Int)] -> [Range] -> Asser
427428
incomingCallTestCase contents queryX queryY positions ranges = withCanonicalTempDir $ \dir ->
428429
runSessionWithServer plugin dir $ do
429430
doc <- createDoc "A.hs" "haskell" contents
430-
waitForKickDone
431+
waitForIndex (dir </> "A.hs")
431432
items <- concatMapM (\((x, y), range) ->
432433
Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc x y)
433434
<&> map (, range)
@@ -447,7 +448,7 @@ incomingCallMultiFileTestCase :: FilePath -> Int -> Int -> M.Map FilePath [((Int
447448
incomingCallMultiFileTestCase filepath queryX queryY mp =
448449
runSessionWithServer plugin testDataDir $ do
449450
doc <- openDoc filepath "haskell"
450-
waitForKickDone
451+
waitForIndex (testDataDir </> filepath)
451452
items <- fmap concat $ sequence $ M.elems $ M.mapWithKey (\fp pr -> do
452453
p <- openDoc fp "haskell"
453454
waitForKickDone
@@ -469,7 +470,7 @@ outgoingCallTestCase :: T.Text -> Int -> Int -> [(Int, Int)] -> [Range] -> Asser
469470
outgoingCallTestCase contents queryX queryY positions ranges = withCanonicalTempDir $ \dir ->
470471
runSessionWithServer plugin dir $ do
471472
doc <- createDoc "A.hs" "haskell" contents
472-
waitForKickDone
473+
waitForIndex (dir </> "A.hs")
473474
items <- concatMapM (\((x, y), range) ->
474475
Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc x y)
475476
<&> map (, range)
@@ -488,7 +489,7 @@ outgoingCallMultiFileTestCase :: FilePath -> Int -> Int -> M.Map FilePath [((Int
488489
outgoingCallMultiFileTestCase filepath queryX queryY mp =
489490
runSessionWithServer plugin testDataDir $ do
490491
doc <- openDoc filepath "haskell"
491-
waitForKickDone
492+
waitForIndex (testDataDir </> filepath)
492493
items <- fmap concat $ sequence $ M.elems $ M.mapWithKey (\fp pr -> do
493494
p <- openDoc fp "haskell"
494495
waitForKickDone
@@ -509,7 +510,7 @@ oneCaseWithCreate :: T.Text -> Int -> Int -> (Uri -> CallHierarchyItem) -> Asser
509510
oneCaseWithCreate contents queryX queryY expected = withCanonicalTempDir $ \dir ->
510511
runSessionWithServer plugin dir $ do
511512
doc <- createDoc "A.hs" "haskell" contents
512-
waitForKickDone
513+
waitForIndex (dir </> "A.hs")
513514
Test.prepareCallHierarchy (mkPrepareCallHierarchyParam doc queryX queryY) >>=
514515
\case
515516
[item] -> liftIO $ item @?= expected (doc ^. L.uri)
@@ -545,3 +546,16 @@ mkIncomingCallsParam = CallHierarchyIncomingCallsParams Nothing Nothing
545546

546547
mkOutgoingCallsParam :: CallHierarchyItem -> CallHierarchyOutgoingCallsParams
547548
mkOutgoingCallsParam = CallHierarchyOutgoingCallsParams Nothing Nothing
549+
550+
-- Wait for a special test message emitted by ghcide when a file is indexed,
551+
-- so that call hierarchy can safely query the database.
552+
waitForIndex :: FilePath -> Session ()
553+
waitForIndex fp1 = skipManyTill anyMessage $ void $ referenceReady lenientEquals
554+
where
555+
-- fp1 may be relative, in that case we check that it is a suffix of the
556+
-- filepath from the message
557+
lenientEquals :: FilePath -> Bool
558+
lenientEquals fp2
559+
| isRelative fp1 = any (equalFilePath fp1) (map (foldr (</>) "") $ tails $ splitDirectories fp2)
560+
| otherwise = equalFilePath fp1 fp2
561+

0 commit comments

Comments
 (0)