Skip to content

runSessionWithConfig -> runSessionWithServerInTmpDir in test/functional/Format.hs - #5154

Merged
Aster89 merged 19 commits into
haskell:masterfrom
Aster89:issue-5054
Nov 10, 2026
Merged

Aster89 merged 19 commits into
haskell:masterfrom
Aster89:issue-5054

Conversation

@Aster89

@Aster89 Aster89 commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Ready for review & merge

With this PR we do the transition written in the title.

At least we do so in the func-tests. Why are we doing this, is written in #5054, which links to #5020, so in essence this is part of the effort to update cabal-version.

Original text (so following messages makes sense)

I'm still experimenting.

For now there's two commits:

Running cabal run func-test -- -j32 results¹ in this error:

haskell-language-server
  part 1
    plugin config
      generic plugin config
        custom defaults:                                      OK (0.66s)
        custom defaults and user config on some other plugin: OK (0.45s)
        custom defaults and non overlapping user config:      OK (0.47s)
        custom defaults and overlapping user plugin config:   OK (0.25s)
        custom defaults and non plugin user config:           OK (0.23s)
    generate schema
      vscode-extension-schema:                                OK (0.43s)
      generate-default-config:                                OK (0.45s)
      plugins-custom-config-markdown-reference:               OK (0.42s)
  part 2
    format document
      lsp formatting provider
        respects none:                                        OK (0.50s)
        error message contains stderr output:                 FAIL (0.20s)
          test/functional/Format.hs:68:
          Expected exit code prefix, got: ormolu: Internal Error: ormolu: createProcess: posix_spawnp: does not exist (No such file or directory)
          Use -p '/error message contains stderr output/' to rerun this test only.
        can change on the fly:                                IGNORED
          Ormolu plugin disabled
    behaviour on malformed projects
      Missing module diagnostic:                              OK (0.86s)
      Missing module diagnostic - no matching prefix:         OK (0.47s)
    hie-bios
      loads main-is module:                                   OK (12.37s)
    window/workDoneProgress
      sends indefinite progress notifications:                OK (0.68s)
      eval plugin sends progress reports:                     OK (16.56s)
      ormolu plugin sends progress notifications:             IGNORED
        Ormolu plugin disabled
      fourmolu plugin sends progress notifications:           IGNORED
        Fourmolu plugin disabled

1 out of 18 tests failed (17.23s)

Looking at #3968 I suspect the error above might ahve to do with ormolu as an external process?


¹ Most of the times; just once I've seen more tests failing, but maybe that's related to some residual flakiness that I can't easily reproduce, having tried 5 more times.


Fixes #5054


@Aster89 Aster89 self-assigned this Oct 24, 2026
Comment thread haskell-language-server.cabal Resolved
@Aster89
Aster89 force-pushed the issue-5054 branch 3 times, most recently from 69183c6 to ae02dca Compare November 2, 2026 21:27
@Aster89

Aster89 commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator Author

I've duplicated the first part of the "can change on the fly" test and run it via runSessionWithServerInTmpDir instead of runSessionWithConfig.

However, to include the following parts of the test, where ormolu is run on the file as edited by fourmolu, I'd need runSessionWithServerInTmpDir to use 2 plugins, but the function it delegates to, runSessionWithTestConfig, only expects 1 plugin (inside TestConfig's testPluginDescriptor field). On the other hand, looking at the implementation of runSessionWithTestConfig, nothing seems to prevent us from changing TestConfig in such a way that it can hold a list of plugins.

@fendor, what do you think?

@fendor

fendor commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

@Aster89 PluginTestDescriptor b implement Monoid, so plugin1 <> plugin2 works as expected. See plugins/hls-cabal-plugin/test/Utils.hs:70 for an example.

@Aster89

Aster89 commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator Author

@Aster89 PluginTestDescriptor b implement Monoid

I had no idea!

Great, so there's also mempty should be enough for the case no plugin is present. Thanks!


Actually, @fendor, I understand that IdePlugins a implements Monoid, but PluginTestDescriptor b is instantiated with a different b for oromolu as compared to fourmolu, as they use a different LogEvent for the Recorder:

data LogEvent
= NoVersion Text
| StdErr Text
| LogCompiledInVersion String
| LogExternalVersion [Int]
| LogOrmoluCommand [String] FilePath
deriving (Show)

data LogEvent
= NoVersion Text
| ConfigPath FilePath
| NoConfigPath [FilePath]
| StdErr Text
| LogCompiledInVersion String
| LogExternalVersion [Int]
deriving (Show)

The example you give, instead,

failIfSessionTimeout . runSessionWithServerInTmpDir def (cabalPlugin <> cabalHaskellPlugin) vft

uses these two descriptors,

cabalPlugin :: PluginTestDescriptor Ide.Plugin.Cabal.Log
cabalPlugin = mkPluginTestDescriptor descriptor "cabal"
cabalHaskellPlugin :: PluginTestDescriptor Ide.Plugin.Cabal.Log
cabalHaskellPlugin = mkPluginTestDescriptor haskellInteractionDescriptor "cabal-haskell"

that share the same Log.

What do you suggest?

Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
@Aster89
Aster89 marked this pull request as ready for review November 3, 2026 16:04
Comment thread test/functional/Format.hs Resolved
@Aster89

Aster89 commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
@Aster89
Aster89 force-pushed the issue-5054 branch 3 times, most recently from 149aaf5 to 1dbd866 Compare November 7, 2026 19:41

@fendor fendor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make these tests resemble their previous behaviour, we should be launching HLS as closely to the final haskell-language-server binary as possible. Thus, I suggest to use idePlugins and avoid the CPP by using requiresOrmoluPlugin and requiresFourmoluPlugin test combinators.

Comment thread haskell-language-server.cabal Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Avoid `#if`-branching on the presence/absence of the plugins, and use
`idePlugins` to retrieve the currently available plugins (as determined
by the passed `Config`).

---

I think there's definitely some flakiness around, as I've very sparingly
observed the failure below. It's not unlikely that we just need to
serialize tests a bit more, which I only partly did via haskell#5152.
```
haskell-language-server
  part 1
    plugin config
      generic plugin config
        custom defaults:                                      FAIL
          Exception: ghc-internal:GHC.Internal.IO.Exception.IOException:

          /home/enrico/haskell-language-server/test/testdata/diagnostics/test/testdata/diagnostics: changeWorkingDirectory: does not exist (No such file or directory)

          HasCallStack backtrace:
            ioError, called at libraries/unix/System/Posix/PosixPath/FilePath.hsc:106:5 in unix-2.8.8.0-fd61:System.Posix.PosixPath.FilePath

          Use -p '$0=="haskell-language-server.part 1.plugin config.generic plugin config.custom defaults"' to rerun this test only.
        custom defaults and user config on some other plugin: OK (0.43s)
        custom defaults and non overlapping user config:      FAIL
          Exception: ghc-internal:GHC.Internal.IO.Exception.IOException:

          /home/enrico/haskell-language-server/test/testdata/diagnostics/test/testdata/diagnostics: changeWorkingDirectory: does not exist (No such file or directory)

          HasCallStack backtrace:
            ioError, called at libraries/unix/System/Posix/PosixPath/FilePath.hsc:106:5 in unix-2.8.8.0-fd61:System.Posix.PosixPath.FilePath

          Use -p '/custom defaults and non overlapping user config/' to rerun this test only.
        custom defaults and overlapping user plugin config:   FAIL
          Exception: ghc-internal:GHC.Internal.IO.Exception.IOException:

          /home/enrico/haskell-language-server/test/testdata/diagnostics/test/testdata/diagnostics: changeWorkingDirectory: does not exist (No such file or directory)

          HasCallStack backtrace:
            ioError, called at libraries/unix/System/Posix/PosixPath/FilePath.hsc:106:5 in unix-2.8.8.0-fd61:System.Posix.PosixPath.FilePath

          Use -p '/custom defaults and overlapping user plugin config/' to rerun this test only.
        custom defaults and non plugin user config:           OK (0.24s)
    generate schema
      vscode-extension-schema:                                OK (0.47s)
      generate-default-config:                                OK (0.48s)
      plugins-custom-config-markdown-reference:               OK (0.47s)
  part 2
    format document
      lsp formatting provider
        respects none:                                        OK (0.03s)
        can change on the fly:                                OK (0.44s)
    behaviour on malformed projects
      Missing module diagnostic:                              OK (0.86s)
      Missing module diagnostic - no matching prefix:         OK (0.54s)
    hie-bios
      loads main-is module:                                   OK (13.91s)
    window/workDoneProgress
      sends indefinite progress notifications:                OK (0.69s)
      eval plugin sends progress reports:                     OK (19.10s)
      ormolu plugin sends progress notifications:             OK (0.98s)
      fourmolu plugin sends progress notifications:           OK (0.75s)

3 out of 17 tests failed (19.58s)
```
Comment thread test/functional/Format.hs Resolved

@fendor fendor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good, final nitpicks and then you are good to go :)

Thanks for pushing this through, great improvement!

Comment thread haskell-language-server.cabal Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
Comment thread test/functional/Format.hs Resolved
@Aster89
Aster89 enabled auto-merge (squash) November 10, 2026 13:45
@Aster89
Aster89 disabled auto-merge November 10, 2026 13:46
@Aster89
Aster89 enabled auto-merge (squash) November 10, 2026 13:52
@Aster89
Aster89 merged commit 793c889 into haskell:master Nov 10, 2026
42 checks passed
@Aster89
Aster89 deleted the issue-5054 branch November 10, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix some tests by using runSessionWithServerInTmpDir instead of runSessionWithConfig

2 participants