module LoggingTests where import Control.Eff import qualified Control.Eff.LogWriter.UDP as UDP import qualified Control.Eff.LogWriter.Async as Async import Control.Eff.Concurrent import Test.Tasty import Test.Tasty.HUnit import Common import Control.Lens import Control.Monad.Trans.Control (liftBaseOp) test_Logging :: TestTree test_Logging = setTravisTestOptions $ testGroup "logging" [ cencoredLogging , strictness , testGroup "IO" [ liftedIoLogging , udpLogging , udpNestedLogging , asyncLogging , asyncNestedLogging ] ] cencoredLogging :: HasCallStack => TestTree cencoredLogging = testCase "log cencorship works" $ do res <- fmap (view lmMessage) <$> censoredLoggingTestImpl demo res @?= view lmMessage <$> [ infoMessage "1" , debugMessage "2" , infoMessage "x 1" , debugMessage "x 2" , infoMessage "x y 1" , debugMessage "x y 2" , infoMessage "x 1" , debugMessage "x 2" , infoMessage "1" , debugMessage "2" ] where demo :: ('[Logs] <:: e) => Eff e () demo = do logDebug "2" logInfo "1" censoredLoggingTestImpl :: Eff '[Logs, LogWriterReader, Lift IO] () -> IO [LogMessage] censoredLoggingTestImpl e = do logs <- newMVar [] runLift $ withLogging (MkLogWriter (\lm -> modifyMVar_ logs (\lms -> return (lm : lms)))) $ do e censorLogs (lmMessage %~ ("x " <>)) $ do e censorLogs (lmMessage %~ ("y " <>)) e e e takeMVar logs strictness :: HasCallStack => TestTree strictness = testCase "messages failing the predicate are not deeply evaluated" $ runLift $ withConsoleLogging "test-app" local0 allLogMessages $ excludeLogMessages (lmSeverityIs errorSeverity) $ do logDebug "test" logError' ("test" <> error "TEST FAILED: this log statement should not have been evaluated deeply") liftedIoLogging :: HasCallStack => TestTree liftedIoLogging = testCase "logging vs. MonadBaseControl" $ do outVar <- newEmptyMVar runLift $ withConsoleLogging "test-app" local0 allLogMessages $ (\ e -> liftBaseOp (testWriter outVar) (\doWrite -> addLogWriter (MkLogWriter doWrite) e)) $ logDebug "test" actual <- takeMVar outVar assertEqual "wrong log message" "test" actual where testWriter :: MVar String -> ((LogMessage -> IO ()) -> IO ()) -> IO () testWriter outVar withWriter = withWriter (putMVar outVar . show) test1234 :: Member Logs e => Eff e () test1234 = do logNotice "~~~~~~~~~~~~~~~~~~~~~~~~~~test 1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" logNotice "~~~~~~~~~~~~~~~~~~~~~~~~~~test 2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" logNotice "~~~~~~~~~~~~~~~~~~~~~~~~~~test 3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" logNotice "~~~~~~~~~~~~~~~~~~~~~~~~~~test 4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" udpLogging :: HasCallStack => TestTree udpLogging = testCase "udp logging" $ runLift $ UDP.withUDPLogging renderRFC5424NoLocation "localhost" "9999" "test-app" local0 allLogMessages test1234 udpNestedLogging :: HasCallStack => TestTree udpNestedLogging = testCase "udp nested filteredlogging" $ runLift $ withConsoleLogging "test-app" local0 allLogMessages $ UDP.withUDPLogWriter renderRFC5424 "localhost" "9999" test1234 asyncLogging :: HasCallStack => TestTree asyncLogging = testCase "async filteredlogging" $ do lw <- consoleLogWriter runLift $ Async.withAsyncLogging lw (1000::Int) "app-name" local0 allLogMessages test1234 asyncNestedLogging :: HasCallStack => TestTree asyncNestedLogging = testCase "async nested filteredlogging" $ do lw <- consoleLogWriter runLift $ withLogging lw $ Async.withAsyncLogWriter (1000::Int) test1234