diff --git a/htest/Test/Ganeti/Utils.hs b/htest/Test/Ganeti/Utils.hs index baa5e099d95c05c01e9237693f3f30192643d941..461d1b27eb959852aea3af82d60d6440e92a0937 100644 --- a/htest/Test/Ganeti/Utils.hs +++ b/htest/Test/Ganeti/Utils.hs @@ -31,6 +31,7 @@ module Test.Ganeti.Utils (testUtils) where import Test.QuickCheck hiding (Result) import Test.HUnit +import Data.Char (isSpace) import Data.List import qualified Text.JSON as J @@ -202,6 +203,22 @@ prop_niceSortKey_equiv = zip numbers names) ] +-- | Tests 'rstripSpace'. +prop_rStripSpace :: NonEmptyList Char -> Property +prop_rStripSpace (NonEmpty str) = + forAll (resize 50 $ listOf1 (arbitrary `suchThat` isSpace)) $ \whitespace -> + conjoin [ printTestCase "arb. string last char is not space" $ + case rStripSpace str of + [] -> True + xs -> not . isSpace $ last xs + , printTestCase "whitespace suffix is stripped" $ + rStripSpace str ==? rStripSpace (str ++ whitespace) + , printTestCase "whitespace reduced to null" $ + rStripSpace whitespace ==? "" + , printTestCase "idempotent on empty strings" $ + rStripSpace "" ==? "" + ] + -- | Test list for the Utils module. testSuite "Utils" [ 'prop_commaJoinSplit @@ -217,4 +234,5 @@ testSuite "Utils" , 'prop_niceSort_generic , 'prop_niceSort_numbers , 'prop_niceSortKey_equiv + , 'prop_rStripSpace ] diff --git a/htools/Ganeti/Ssconf.hs b/htools/Ganeti/Ssconf.hs index 6853bb15a7c3da79d614c53bd88090e63d5564d0..20cfeb39632172d4b808172ffeac7aebf82b141a 100644 --- a/htools/Ganeti/Ssconf.hs +++ b/htools/Ganeti/Ssconf.hs @@ -38,7 +38,6 @@ import Ganeti.THH import Control.Exception import Control.Monad (liftM) -import Data.Char (isSpace) import Data.Maybe (fromMaybe) import qualified Network.Socket as Socket import System.FilePath ((</>)) @@ -116,11 +115,6 @@ readSSConfFile optpath def key = do keyToFilename (fromMaybe dpath optpath) $ key return (liftM (take maxFileSize) result) --- | Strip space characthers (including newline). As this is --- expensive, should only be run on small strings. -rstripSpace :: String -> String -rstripSpace = reverse . dropWhile isSpace . reverse - -- | Parses a string containing an IP family parseIPFamily :: Int -> Result Socket.Family parseIPFamily fam | fam == C.ip4Family = Ok Socket.AF_INET @@ -131,5 +125,5 @@ parseIPFamily fam | fam == C.ip4Family = Ok Socket.AF_INET getPrimaryIPFamily :: Maybe FilePath -> IO (Result Socket.Family) getPrimaryIPFamily optpath = do result <- readSSConfFile optpath (Just (show C.ip4Family)) SSPrimaryIpFamily - return (liftM rstripSpace result >>= + return (liftM rStripSpace result >>= tryRead "Parsing af_family" >>= parseIPFamily) diff --git a/htools/Ganeti/Utils.hs b/htools/Ganeti/Utils.hs index 9636a34d2266124efa37a40bd74b6de8ce373dd8..9f7e9c579cce17d98f25fbe5ac26464ab005b5d9 100644 --- a/htools/Ganeti/Utils.hs +++ b/htools/Ganeti/Utils.hs @@ -43,9 +43,10 @@ module Ganeti.Utils , exitErr , exitWhen , exitUnless + , rStripSpace ) where -import Data.Char (toUpper, isAlphaNum, isDigit) +import Data.Char (toUpper, isAlphaNum, isDigit, isSpace) import Data.Function (on) import Data.List @@ -271,3 +272,8 @@ niceSortKey :: (a -> String) -> [a] -> [a] niceSortKey keyfn = map snd . sortBy (compare `on` fst) . map (\s -> (fst . extractKey [] $ keyfn s, s)) + +-- | Strip space characthers (including newline). As this is +-- expensive, should only be run on small strings. +rStripSpace :: String -> String +rStripSpace = reverse . dropWhile isSpace . reverse