0 | module Evince.Async.Posix
 1 |
 2 | import public Evince.Async.Spec
 3 | import public Evince.Async.Synchronized
 4 | import public Evince.Async.Hoist
 5 | import public Evince.Async.Shared
 6 |
 7 | import Data.Maybe
 8 | import System
 9 | import System.Info
10 | import IO.Async
11 | import IO.Async.Loop.Posix
12 | import Evince.Core
13 |
14 | -- The posix event-loop runner. idris2-async's `simpleApp` takes its worker-thread
15 | -- count only from IDRIS2_ASYNC_THREADS (default 2). We give a better default for a
16 | -- test runner - the processor count - by setting the variable when it's unset, so
17 | -- users get full parallelism out of the box while keeping the env var as an
18 | -- override (an explicit value is always respected).
19 | posixRun : Async Poll [] () -> IO ()
20 | posixRun prog = do
21 |   Nothing <- getEnv "IDRIS2_ASYNC_THREADS"
22 |     | Just _ => simpleApp prog
23 |   cores <- getNProcessors
24 |   ignore $ setEnv "IDRIS2_ASYNC_THREADS" (show (fromMaybe 2 cores)) True
25 |   simpleApp prog
26 |
27 | -- Multi-threaded entry points: idris2-async's poll-based `ThreadPool` distributes
28 | -- top-level groups across OS worker threads, so they execute with genuine
29 | -- multi-core parallelism. In practice this builds and runs only on Chez; Racket
30 | -- and RefC hit upstream threading/FFI gaps that keep the posix loop from running
31 | -- there. The `caswrite1` lock keeps group hooks correct under that true concurrency.
32 |
33 | ||| Run a spec under the multi-threaded posix driver with custom configuration,
34 | ||| printing results and exiting non-zero if any test failed.
35 | export
36 | runSpecAsyncWith : RunConfig -> Spec (Async Poll []) () () -> IO ()
37 | runSpecAsyncWith = runSpecVia posixRun
38 |
39 | ||| Run a spec under the multi-threaded posix driver with default configuration.
40 | export
41 | runSpecAsync : Spec (Async Poll []) () () -> IO ()
42 | runSpecAsync = runSpecAsyncWith defaultConfig
43 |
44 | ||| Run under the posix driver with custom configuration and return the summary
45 | ||| without exiting. Useful for meta-testing.
46 | export
47 | runSpecAsyncWithSummaryAndConfig : RunConfig -> Spec (Async Poll []) () () -> IO Summary
48 | runSpecAsyncWithSummaryAndConfig = summaryVia posixRun
49 |
50 | ||| Run under the posix driver and return the summary without exiting.
51 | export
52 | runSpecAsyncWithSummary : Spec (Async Poll []) () () -> IO Summary
53 | runSpecAsyncWithSummary = runSpecAsyncWithSummaryAndConfig defaultConfig
54 |
55 | ||| Run a spec under the posix driver, reading CLI args (e.g. `--jobs=N`).
56 | export
57 | runSpecAsyncWithArgs : Spec (Async Poll []) () () -> IO ()
58 | runSpecAsyncWithArgs = runSpecArgsVia posixRun
59 |
60 | ||| Run under the posix driver with fail-fast - stop after the first failure.
61 | export
62 | runSpecAsyncFailFast : Spec (Async Poll []) () () -> IO ()
63 | runSpecAsyncFailFast = runSpecFailFastVia posixRun
64 |
65 | ||| Run under the posix driver with per-test timing displayed.
66 | export
67 | runSpecAsyncTimed : Spec (Async Poll []) () () -> IO ()
68 | runSpecAsyncTimed = runSpecTimedVia posixRun
69 |
70 | ||| Run a concrete `Spec IO` under the posix driver, hoisting its actions into
71 | ||| `Async` via `liftIO`.
72 | export
73 | runSpecAsyncIO : Spec IO () () -> IO ()
74 | runSpecAsyncIO = runSpecAsync . hoistSpec liftIO
75 |
76 | ||| Like `runSpecAsyncIO`, with custom configuration.
77 | export
78 | runSpecAsyncIOWith : RunConfig -> Spec IO () () -> IO ()
79 | runSpecAsyncIOWith cfg = runSpecAsyncWith cfg . hoistSpec liftIO
80 |