From 77207e733d16ec50810a0bbd7869c8c29324a731 Mon Sep 17 00:00:00 2001 From: Baylac-Jacqué Félix Date: Wed, 9 Aug 2017 11:06:26 +0200 Subject: Refactor project structure to exec + lib. We want to add some unit tests to the project, hence, we need a proper library. --- app/Main.hs | 81 +++++++++++++++++++++++++++++++++ nara.cabal | 52 +++++++++++++++++---- src/Main.hs | 81 --------------------------------- tests/spec/Network/WireGuard/RPCSpec.hs | 11 +++++ tests/spec/Spec.hs | 1 + 5 files changed, 135 insertions(+), 91 deletions(-) create mode 100644 app/Main.hs delete mode 100644 src/Main.hs create mode 100644 tests/spec/Network/WireGuard/RPCSpec.hs create mode 100644 tests/spec/Spec.hs diff --git a/app/Main.hs b/app/Main.hs new file mode 100644 index 0000000..29d4953 --- /dev/null +++ b/app/Main.hs @@ -0,0 +1,81 @@ +{-# LANGUAGE RecordWildCards #-} + +module Main where + +import Control.Concurrent (getNumCapabilities) +import Control.Monad (void) +import Data.Monoid ((<>)) +import System.Directory (createDirectoryIfMissing, + doesDirectoryExist) +import System.Exit (die) +import System.FilePath.Posix (takeDirectory, ()) +import System.Info (os) +import System.Posix.IO (OpenMode (..), closeFd, + defaultFileFlags, dupTo, + openFd, stdError, stdInput, + stdOutput) +import System.Posix.Process (forkProcess) +import System.Posix.Types (Fd) + +import Options.Applicative + +import Network.WireGuard.Daemon (runDaemon) +import Network.WireGuard.Foreign.Tun (openTun) +import Network.WireGuard.Internal.Util (catchIOExceptionAnd) + +data Opts = Opts + { foreground :: Bool + , intfName :: String + } + +parser :: ParserInfo Opts +parser = info (helper <*> opts) fullDesc + where + opts = Opts <$> _foreground + <*> _intfName + + _foreground = switch + ( long "foreground" + <> short 'f' + <> help "run in the foreground") + + _intfName = argument str + ( metavar "interface" + <> help ("device interface name (e.g. " ++ intfNameExample ++ ")")) + + intfNameExample | os == "darwin" = "utun1" + | otherwise = "wg0" + + +main :: IO () +main = do + Opts{..} <- execParser parser + + runPath <- maybe (die "failed to find path to bind socket") return =<< findVarRun + let sockPath = runPath "wireguard" (intfName ++ ".sock") + createDirectoryIfMissing False (takeDirectory sockPath) + + fds <- openTun intfName =<< getNumCapabilities + + let runner daemon | foreground = daemon + | otherwise = void $ forkProcess $ do + mapM_ redirectToNull [stdInput, stdOutput, stdError] + daemon + + runner $ runDaemon intfName sockPath fds + +redirectToNull :: Fd -> IO () +redirectToNull fd = catchIOExceptionAnd (return ()) $ do + nullFd <- openFd "/dev/null" ReadWrite Nothing defaultFileFlags + closeFd fd + void $ dupTo nullFd fd + +findVarRun :: IO (Maybe FilePath) +findVarRun = loop ["/var/run", "/run"] + where + loop [] = return Nothing + loop (d:ds) = do + exists <- doesDirectoryExist d + if exists + then return (Just d) + else loop ds diff --git a/nara.cabal b/nara.cabal index ef76d20..323f635 100644 --- a/nara.cabal +++ b/nara.cabal @@ -19,27 +19,45 @@ flag static default: False -executable nara - main-is: - Main.hs - other-modules: +executable nara-exe + hs-source-dirs: app + main-is: Main.hs + ghc-options: + -Wall -Werror -O2 -threaded + if flag(static) + ghc-options: + -optl-static + build-depends: + base, + nara, + directory, + filepath, + unix == 2.7.*, + optparse-applicative + default-language: + Haskell2010 + +library +-- main-is: +-- Main.hs + exposed-modules: Network.WireGuard.Core, Network.WireGuard.Daemon, Network.WireGuard.Foreign.In6Addr, Network.WireGuard.Foreign.Key, Network.WireGuard.Foreign.Tun, Network.WireGuard.Foreign.UAPI, + Network.WireGuard.RPC, + Network.WireGuard.TunListener, + Network.WireGuard.UdpListener, + Network.WireGuard.Internal.Util, Network.WireGuard.Internal.Constant, Network.WireGuard.Internal.IPPacket, Network.WireGuard.Internal.Noise, Network.WireGuard.Internal.Packet, Network.WireGuard.Internal.PacketQueue, Network.WireGuard.Internal.State, - Network.WireGuard.Internal.Types, - Network.WireGuard.Internal.Util, - Network.WireGuard.RPC, - Network.WireGuard.TunListener, - Network.WireGuard.UdpListener + Network.WireGuard.Internal.Types build-depends: async, base == 4.9.*, @@ -75,7 +93,7 @@ executable nara buildable: False ghc-options: - -Wall -O2 -threaded + -Wall -Werror -O2 if flag(static) ghc-options: -optl-static @@ -86,3 +104,17 @@ executable nara include default-language: Haskell2010 + +test-suite nara-test + type: exitcode-stdio-1.0 + main-is: Spec.hs + hs-source-dirs: + tests/spec + ghc-options: -Wall + build-depends: + base == 4.9.* + , hspec + , nara + other-modules: + Network.WireGuard.RPCSpec + default-language: Haskell2010 diff --git a/src/Main.hs b/src/Main.hs deleted file mode 100644 index 29d4953..0000000 --- a/src/Main.hs +++ /dev/null @@ -1,81 +0,0 @@ -{-# LANGUAGE RecordWildCards #-} - -module Main where - -import Control.Concurrent (getNumCapabilities) -import Control.Monad (void) -import Data.Monoid ((<>)) -import System.Directory (createDirectoryIfMissing, - doesDirectoryExist) -import System.Exit (die) -import System.FilePath.Posix (takeDirectory, ()) -import System.Info (os) -import System.Posix.IO (OpenMode (..), closeFd, - defaultFileFlags, dupTo, - openFd, stdError, stdInput, - stdOutput) -import System.Posix.Process (forkProcess) -import System.Posix.Types (Fd) - -import Options.Applicative - -import Network.WireGuard.Daemon (runDaemon) -import Network.WireGuard.Foreign.Tun (openTun) -import Network.WireGuard.Internal.Util (catchIOExceptionAnd) - -data Opts = Opts - { foreground :: Bool - , intfName :: String - } - -parser :: ParserInfo Opts -parser = info (helper <*> opts) fullDesc - where - opts = Opts <$> _foreground - <*> _intfName - - _foreground = switch - ( long "foreground" - <> short 'f' - <> help "run in the foreground") - - _intfName = argument str - ( metavar "interface" - <> help ("device interface name (e.g. " ++ intfNameExample ++ ")")) - - intfNameExample | os == "darwin" = "utun1" - | otherwise = "wg0" - - -main :: IO () -main = do - Opts{..} <- execParser parser - - runPath <- maybe (die "failed to find path to bind socket") return =<< findVarRun - let sockPath = runPath "wireguard" (intfName ++ ".sock") - createDirectoryIfMissing False (takeDirectory sockPath) - - fds <- openTun intfName =<< getNumCapabilities - - let runner daemon | foreground = daemon - | otherwise = void $ forkProcess $ do - mapM_ redirectToNull [stdInput, stdOutput, stdError] - daemon - - runner $ runDaemon intfName sockPath fds - -redirectToNull :: Fd -> IO () -redirectToNull fd = catchIOExceptionAnd (return ()) $ do - nullFd <- openFd "/dev/null" ReadWrite Nothing defaultFileFlags - closeFd fd - void $ dupTo nullFd fd - -findVarRun :: IO (Maybe FilePath) -findVarRun = loop ["/var/run", "/run"] - where - loop [] = return Nothing - loop (d:ds) = do - exists <- doesDirectoryExist d - if exists - then return (Just d) - else loop ds diff --git a/tests/spec/Network/WireGuard/RPCSpec.hs b/tests/spec/Network/WireGuard/RPCSpec.hs new file mode 100644 index 0000000..b0422a3 --- /dev/null +++ b/tests/spec/Network/WireGuard/RPCSpec.hs @@ -0,0 +1,11 @@ +module Network.WireGuard.RPCSpec (spec) where + +import Test.Hspec (Spec, describe, it, shouldBe) + +import Network.WireGuard.RPC (runRPC) + + +spec :: Spec +spec = describe "test" $ + it "should fail" $ + True `shouldBe` False diff --git a/tests/spec/Spec.hs b/tests/spec/Spec.hs new file mode 100644 index 0000000..a824f8c --- /dev/null +++ b/tests/spec/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF hspec-discover #-} -- cgit v1.2.3-59-g8ed1b