@@ -5,6 +5,7 @@ module Control.Distributed.Process.Tests.Tracing (tests) where
5
5
import Control.Distributed.Process.Tests.Internal.Utils
6
6
import Network.Transport.Test (TestTransport (.. ))
7
7
8
+ import Control.Applicative ((<*) )
8
9
import Control.Concurrent (threadDelay )
9
10
import Control.Concurrent.MVar
10
11
( MVar
@@ -19,16 +20,24 @@ import Control.Distributed.Process.Debug
19
20
import Control.Distributed.Process.Management
20
21
( MxEvent (.. )
21
22
)
23
+ import qualified Control.Exception as IO (bracket )
24
+ import Data.List (isPrefixOf , isSuffixOf )
22
25
23
26
#if ! MIN_VERSION_base(4,6,0)
24
27
import Prelude hiding (catch , log )
28
+ #else
29
+ import Prelude hiding ((<*) )
25
30
#endif
26
31
27
32
import Test.Framework
28
33
( Test
29
34
, testGroup
30
35
)
31
36
import Test.Framework.Providers.HUnit (testCase )
37
+ import System.Environment (getEnvironment )
38
+ -- These are available in System.Environment only since base 4.7
39
+ import System.SetEnv (setEnv , unsetEnv )
40
+
32
41
33
42
testSpawnTracing :: TestResult Bool -> Process ()
34
43
testSpawnTracing result = do
@@ -282,6 +291,82 @@ testRemoteTraceRelay TestTransport{..} result =
282
291
-- and just to be polite...
283
292
liftIO $ closeLocalNode node2
284
293
294
+ -- | Sets the value of an environment variable while executing the given IO
295
+ -- computation and restores the preceeding value upon completion.
296
+ withEnv :: String -> String -> IO a -> IO a
297
+ withEnv var val =
298
+ IO. bracket (fmap (lookup var) getEnvironment <* setEnv var val)
299
+ (maybe (unsetEnv var) (setEnv var))
300
+ . const
301
+
302
+ -- | Tests that one and only one interesting trace message is produced when a
303
+ -- given action is performed. A message is considered interesting when the given
304
+ -- function return @True@.
305
+ testSystemLoggerMsg :: TestTransport
306
+ -> Process a
307
+ -> (a -> String -> Bool )
308
+ -> IO ()
309
+ testSystemLoggerMsg t action interestingMessage =
310
+ withEnv " DISTRIBUTED_PROCESS_TRACE_CONSOLE" " yes" $
311
+ withEnv " DISTRIBUTED_PROCESS_TRACE_FLAGS" " pdnusrl" $ do
312
+ n <- newLocalNode (testTransport t) initRemoteTable
313
+
314
+ runProcess n $ do
315
+ self <- getSelfPid
316
+ reregister " trace.logger" self
317
+ a <- action
318
+ let interestingMessage' (_ :: String , msg ) = interestingMessage a msg
319
+ -- Wait for the trace message.
320
+ receiveWait [ matchIf interestingMessage' $ const $ return () ]
321
+ -- Only one interesting message should arrive.
322
+ Nothing <- receiveTimeout 100000
323
+ [ matchIf interestingMessage' $ const $ return () ]
324
+ return ()
325
+
326
+
327
+ -- | Tests that one and only one trace message is produced when a message is
328
+ -- received.
329
+ testSystemLoggerMxReceive :: TestTransport -> IO ()
330
+ testSystemLoggerMxReceive t = testSystemLoggerMsg t
331
+ (getSelfPid >>= flip send () )
332
+ (\ _ msg -> " MxReceived" `isPrefixOf` msg
333
+ -- discard traces of internal messages
334
+ && not (" :: RegisterReply" `isSuffixOf` msg)
335
+ )
336
+
337
+ -- | Tests that one and only one trace message is produced when a message is
338
+ -- sent.
339
+ testSystemLoggerMxSent :: TestTransport -> IO ()
340
+ testSystemLoggerMxSent t = testSystemLoggerMsg t
341
+ (getSelfPid >>= flip send () )
342
+ (const $ isPrefixOf " MxSent" )
343
+
344
+ -- | Tests that one and only one trace message is produced when a process dies.
345
+ testSystemLoggerMxProcessDied :: TestTransport -> IO ()
346
+ testSystemLoggerMxProcessDied t = testSystemLoggerMsg t
347
+ (spawnLocal $ return () )
348
+ (\ pid -> isPrefixOf $ " MxProcessDied " ++ show pid)
349
+
350
+ -- | Tests that one and only one trace message appears when a process spawns.
351
+ testSystemLoggerMxSpawned :: TestTransport -> IO ()
352
+ testSystemLoggerMxSpawned t = testSystemLoggerMsg t
353
+ (spawnLocal $ return () )
354
+ (\ pid -> isPrefixOf $ " MxSpawned " ++ show pid)
355
+
356
+ -- | Tests that one and only one trace message appears when a process is
357
+ -- registered.
358
+ testSystemLoggerMxRegistered :: TestTransport -> IO ()
359
+ testSystemLoggerMxRegistered t = testSystemLoggerMsg t
360
+ (getSelfPid >>= register " a" >> getSelfPid)
361
+ (\ self -> isPrefixOf $ " MxRegistered " ++ show self ++ " " ++ show " a" )
362
+
363
+ -- | Tests that one and only one trace message appears when a process is
364
+ -- unregistered.
365
+ testSystemLoggerMxUnRegistered :: TestTransport -> IO ()
366
+ testSystemLoggerMxUnRegistered t = testSystemLoggerMsg t
367
+ (getSelfPid >>= register " a" >> unregister " a" >> getSelfPid)
368
+ (\ self -> isPrefixOf $ " MxUnRegistered " ++ show self ++ " " ++ show " a" )
369
+
285
370
tests :: TestTransport -> IO [Test ]
286
371
tests testtrans@ TestTransport {.. } = do
287
372
node1 <- newLocalNode testTransport initRemoteTable
@@ -323,4 +408,12 @@ tests testtrans@TestTransport{..} = do
323
408
(synchronisedAssertion
324
409
" expected blah"
325
410
node1 True (testRemoteTraceRelay testtrans) lock)
411
+ , testGroup " SystemLoggerTracer"
412
+ [ testCase " MxReceive" $ testSystemLoggerMxReceive testtrans
413
+ , testCase " MxSent" $ testSystemLoggerMxSent testtrans
414
+ , testCase " MxProcessDied" $ testSystemLoggerMxProcessDied testtrans
415
+ , testCase " MxSpawned" $ testSystemLoggerMxSpawned testtrans
416
+ , testCase " MxRegistered" $ testSystemLoggerMxRegistered testtrans
417
+ , testCase " MxUnRegistered" $ testSystemLoggerMxUnRegistered testtrans
418
+ ]
326
419
] ]
0 commit comments