iproute 1.2.7 → 1.2.8
raw patch · 9 files changed
+130/−326 lines, 9 filesdep +QuickCheckdep +doctestdep +hspecdep ~base
Dependencies added: QuickCheck, doctest, hspec
Dependency ranges changed: base
Files
- Data/IP/Addr.hs +5/−5
- Data/IP/Range.hs +2/−2
- iproute.cabal +31/−8
- test/IPv4Search.hs +0/−39
- test/Makefile +0/−7
- test/RouteTableSpec.hs +85/−0
- test/Spec.hs +1/−0
- test/Test.hs +0/−265
- test/doctests.hs +6/−0
Data/IP/Addr.hs view
@@ -169,16 +169,16 @@ (Just ip,rest) -> [(IPv4 ip,rest)] (Nothing,_) -> case runParser ip6 cs of (Just ip,rest) -> [(IPv6 ip,rest)]- (Nothing,_) -> error $ "parseIP" ++ cs+ (Nothing,_) -> [] parseIPv4 :: String -> [(IPv4,String)] parseIPv4 cs = case runParser ip4 cs of- (Nothing,_) -> error $ "parseIPv4 " ++ cs+ (Nothing,_) -> [] (Just a4,rest) -> [(a4,rest)] parseIPv6 :: String -> [(IPv6,String)] parseIPv6 cs = case runParser ip6 cs of- (Nothing,_) -> error $ "parseIPv6 " ++ cs+ (Nothing,_) -> [] (Just a6,rest) -> [(a6,rest)] ----------------------------------------------------------------@@ -236,8 +236,8 @@ where check ns = when (length ns > 4) (fail "IPv6 address -- more than 4 hex") -colon2 :: Parser String-colon2 = string "::"+colon2 :: Parser ()+colon2 = void $ string "::" format :: [Int] -> [Int] -> Parser [Int] format bs1 bs2 = do
Data/IP/Range.hs view
@@ -99,7 +99,7 @@ ip4range :: Parser (AddrRange IPv4) ip4range = do ip <- ip4- len <- option 32 $ do { char '/'; dig }+ len <- option 32 $ char '/' >> dig check len let msk = maskIPv4 len adr = ip `maskedIPv4` msk@@ -113,7 +113,7 @@ ip6range :: Parser (AddrRange IPv6) ip6range = do ip <- ip6- len <- option 128 $ do { char '/'; dig }+ len <- option 128 $ char '/' >> dig check len let msk = maskIPv6 len adr = ip `maskedIPv6` msk
iproute.cabal view
@@ -1,5 +1,5 @@ Name: iproute-Version: 1.2.7+Version: 1.2.8 Author: Kazu Yamamoto <kazu@iij.ad.jp> Maintainer: Kazu Yamamoto <kazu@iij.ad.jp> License: BSD3@@ -12,14 +12,12 @@ way branching removed. Both IPv4 and IPv6 are supported. Category: Algorithms, Network-Cabal-Version: >= 1.6+Cabal-Version: >= 1.10 Build-Type: Simple-Extra-Source-Files: test/Test.hs test/IPv4Search.hs test/Makefile-library- if impl(ghc >= 6.12)- GHC-Options: -Wall -fno-warn-unused-do-bind- else- GHC-Options: -Wall++Library+ Default-Language: Haskell2010+ GHC-Options: -Wall Exposed-Modules: Data.IP Data.IP.RouteTable Other-Modules: Data.IP.Addr@@ -32,6 +30,31 @@ , byteorder , containers , network++Test-Suite doctest+ Type: exitcode-stdio-1.0+ Default-Language: Haskell2010+ HS-Source-Dirs: test+ Ghc-Options: -threaded -Wall+ Main-Is: doctests.hs+ Build-Depends: base+ , doctest >= 0.9.3++Test-Suite spec+ Type: exitcode-stdio-1.0+ Default-Language: Haskell2010+ Hs-Source-Dirs: ., test+ Ghc-Options: -Wall+ Main-Is: Spec.hs+ Other-Modules: RouteTableSpec+ Build-Depends: base+ , hspec+ , QuickCheck+ , appar+ , byteorder+ , containers+ , network+ Source-Repository head Type: git Location: git://github.com/kazu-yamamoto/iproute.git
− test/IPv4Search.hs
@@ -1,39 +0,0 @@-module Main where--import Control.Exception-import Data.IP-import Data.IP.RouteTable-import Prelude hiding (lookup, catch)-import System.Environment--main :: IO ()-main = flip catch handler $ do- as <- getArgs- let file = as !! 0- ip = as !! 1- range = ip ++ "/32"- target = readIPv4Range range- rt <- loadRoutes file- let res = lookup target rt- print res- where- handler :: ErrorCall -> IO ()- handler _ = help--loadRoutes :: FilePath -> IO (IPRTable IPv4 (AddrRange IPv4))-loadRoutes file = do- cs <- readFile file- let ls = lines cs- rs = map readIPv4Range ls- kvs = zip rs rs -- value is AddrRange itself in this test- radish = fromList kvs- return radish--readIPv4Range :: String -> AddrRange IPv4-readIPv4Range = read--help :: IO ()-help = do- putStrLn "Usage:"- putStrLn " ipv4_search file IPv4"-
− test/Makefile
@@ -1,7 +0,0 @@-PROG = ipv4_search--all:- ghc -Wall -fno-warn-unused-do-bind -i.. --make -o $(PROG) IPv4Search.hs--clean:- rm -f *.hi *.o $(PROG)
+ test/RouteTableSpec.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE FlexibleInstances #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module RouteTableSpec where++import Control.Monad+import Data.IP+import Data.IP.RouteTable.Internal+import Data.List (sort, nub)+import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck++----------------------------------------------------------------+--+-- Arbitrary+--++instance Arbitrary (AddrRange IPv4) where+ arbitrary = arbitraryIP arbitrary 32++instance Arbitrary (AddrRange IPv6) where+ arbitrary = arbitraryIP arbitrary 128++instance Arbitrary IPv4 where+ arbitrary = arbitraryAdr toIPv4 255 4++instance Arbitrary IPv6 where+ arbitrary = arbitraryAdr toIPv6 65535 8++arbitraryAdr :: Routable a => ([Int] -> a) -> Int -> Int -> Gen a+arbitraryAdr func width adrlen = do+ a <- replicateM adrlen (choose (0, width))+ return $ func a++arbitraryIP :: Routable a => Gen a -> Int -> Gen (AddrRange a)+arbitraryIP adrGen msklen = do+ adr <- adrGen+ len <- choose (0,msklen)+ return $ makeAddrRange adr len++----------------------------------------------------------------+--+-- Spec+--++spec :: Spec+spec = do+ describe "fromList" $ do+ prop "creates the same tree for random input and ordered input"+ (sort_ip :: [AddrRange IPv4] -> Bool)+ prop "creates the same tree for random input and ordered input"+ (sort_ip :: [AddrRange IPv6] -> Bool)+ prop "stores input in the incremental order"+ (ord_ip :: [AddrRange IPv4] -> Bool)+ prop "stores input in the incremental order"+ (ord_ip :: [AddrRange IPv6] -> Bool)+ describe "toList" $ do+ prop "expands as sorted"+ (fromto_ip :: [AddrRange IPv4] -> Bool)+ prop "expands as sorted"+ (fromto_ip :: [AddrRange IPv6] -> Bool)++sort_ip :: (Routable a, Ord a) => [AddrRange a] -> Bool+sort_ip xs = fromList (zip xs xs) == fromList (zip xs' xs')+ where+ xs' = sort xs++fromto_ip :: (Routable a, Ord a) => [AddrRange a] -> Bool+fromto_ip xs = nub (sort xs) == nub (sort ys)+ where+ ys = map fst . toList . fromList $ zip xs xs++ord_ip :: Routable a => [AddrRange a] -> Bool+ord_ip xs = isOrdered . fromList $ zip xs xs++isOrdered :: Routable k => IPRTable k a -> Bool+isOrdered = foldt (\x v -> v && ordered x) True++ordered :: Routable k => IPRTable k a -> Bool+ordered Nil = True+ordered (Node k _ _ l r) = ordered' k l && ordered' k r+ where+ ordered' _ Nil = True+ ordered' k1 (Node k2 _ _ _ _) = k1 >:> k2
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
− test/Test.hs
@@ -1,265 +0,0 @@-{-# LANGUAGE FlexibleInstances, OverloadedStrings, TemplateHaskell #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--module Main where------------------------------------------------------------------------ Tests for IP.RouteTable------ runghc -i.. Test.hs-----import Control.Monad-import Data.IP-import Data.IP.RouteTable.Internal-import Data.List (sort, nub)-import Prelude hiding (lookup)-import Test.Framework.Providers.DocTest-import Test.Framework.Providers.HUnit-import Test.Framework.Providers.QuickCheck2-import Test.Framework.TH.Prime-import Test.HUnit-import Test.QuickCheck--------------------------------------------------------------------main :: IO ()-main = $(defaultMainGenerator)--------------------------------------------------------------------doc_test :: DocTests-doc_test = docTest ["../Data/IP.hs", "../Data/IP/RouteTable.hs"] ["-i..", "-XOverloadedStrings"]------------------------------------------------------------------------ Arbitrary-----instance Arbitrary (AddrRange IPv4) where- arbitrary = arbitraryIP arbitrary 32--instance Arbitrary (AddrRange IPv6) where- arbitrary = arbitraryIP arbitrary 128--instance Arbitrary IPv4 where- arbitrary = arbitraryAdr toIPv4 255 4--instance Arbitrary IPv6 where- arbitrary = arbitraryAdr toIPv6 65535 8--arbitraryAdr :: Routable a => ([Int] -> a) -> Int -> Int -> Gen a-arbitraryAdr func width adrlen = do- a <- replicateM adrlen (choose (0, width))- return $ func a--arbitraryIP :: Routable a => Gen a -> Int -> Gen (AddrRange a)-arbitraryIP adrGen msklen = do- adr <- adrGen- len <- choose (0,msklen)- return $ makeAddrRange adr len------------------------------------------------------------------------ Properties-----prop_sort_ipv4 :: [AddrRange IPv4] -> Bool-prop_sort_ipv4 = sort_ip--prop_sort_ipv6 :: [AddrRange IPv6] -> Bool-prop_sort_ipv6 = sort_ip--sort_ip :: (Routable a, Ord a) => [AddrRange a] -> Bool-sort_ip xs = fromList (zip xs xs) == fromList (zip xs' xs')- where- xs' = sort xs--------------------------------------------------------------------prop_fromto_ipv4 :: [AddrRange IPv4] -> Bool-prop_fromto_ipv4 = fromto_ip--prop_fromto_ipv6 :: [AddrRange IPv6] -> Bool-prop_fromto_ipv6 = fromto_ip--fromto_ip :: (Routable a, Ord a) => [AddrRange a] -> Bool-fromto_ip xs = nub (sort xs) == nub (sort ys)- where- ys = map fst . toList . fromList $ zip xs xs--------------------------------------------------------------------prop_ord_ipv4 :: [AddrRange IPv4] -> Bool-prop_ord_ipv4 = ord_ip--prop_ord_ipv6 :: [AddrRange IPv6] -> Bool-prop_ord_ipv6 = ord_ip--ord_ip :: Routable a => [AddrRange a] -> Bool-ord_ip xs = isOrdered . fromList $ zip xs xs--isOrdered :: Routable k => IPRTable k a -> Bool-isOrdered = foldt (\x v -> v && ordered x) True--ordered :: Routable k => IPRTable k a -> Bool-ordered Nil = True-ordered (Node k _ _ l r) = ordered' k l && ordered' k r- where- ordered' _ Nil = True- ordered' k1 (Node k2 _ _ _ _) = k1 >:> k2--------------------------------------------------------------------prop_insert_lookup_ipv4 :: AddrRange IPv4 -> [AddrRange IPv4] -> Bool-prop_insert_lookup_ipv4 = insert_lookup_ip--prop_insert_lookup_ipv6 :: AddrRange IPv6 -> [AddrRange IPv6] -> Bool-prop_insert_lookup_ipv6 = insert_lookup_ip--insert_lookup_ip :: Routable a => AddrRange a -> [AddrRange a] -> Bool-insert_lookup_ip k xs = lookup k (insert k k t) == Just k- where- rs = zip xs xs- t = fromList rs--prop_search_ipv4 :: AddrRange IPv4 -> [AddrRange IPv4] -> Bool-prop_search_ipv4 = search_ip--prop_search_ipv6 :: AddrRange IPv6 -> [AddrRange IPv6] -> Bool-prop_search_ipv6 = search_ip--search_ip :: Routable a => AddrRange a -> [AddrRange a] -> Bool-search_ip k xs = lookup k (fromList (zip xs xs)) == linear k xs--linear :: Routable a => AddrRange a -> [AddrRange a] -> Maybe (AddrRange a)-linear = linear' Nothing- where- linear' a _ [] = a- linear' Nothing k (x:xs)- | x >:> k = linear' (Just x) k xs- | otherwise = linear' Nothing k xs- linear' (Just a) k (x:xs)- | x >:> k = if mlen x > mlen a- then linear' (Just x) k xs- else linear' (Just a) k xs- | otherwise = linear' (Just a) k xs--------------------------------------------------------------------prop_delete_ipv4 :: [AddrRange IPv6] -> Property-prop_delete_ipv4 = delete_ip--prop_delete_ipv6 :: [AddrRange IPv6] -> Property-prop_delete_ipv6 = delete_ip--delete_ip :: Routable a => [AddrRange a] -> Property-delete_ip xs = xs /= [] ==> isOrdered (delete i t)- where- rs = zip xs xs- t = fromList rs- i = head xs--prop_insert_delete_ipv4 :: AddrRange IPv4 -> [AddrRange IPv4] -> Property-prop_insert_delete_ipv4 = insert_delete_ip--prop_insert_delete_ipv6 :: AddrRange IPv6 -> [AddrRange IPv6] -> Property-prop_insert_delete_ipv6 = insert_delete_ip--insert_delete_ip :: Routable a => AddrRange a -> [AddrRange a] -> Property-insert_delete_ip k xs = lookup k t == Nothing ==> delete k (insert k k t) == t- where- rs = zip xs xs- t = fromList rs--prop_delete_insert_ipv4 :: [AddrRange IPv4] -> Property-prop_delete_insert_ipv4 = delete_insert_ip--prop_delete_insert_ipv6 :: [AddrRange IPv6] -> Property-prop_delete_insert_ipv6 = delete_insert_ip--delete_insert_ip :: Routable a => [AddrRange a] -> Property-delete_insert_ip xs = xs /= [] ==> insert k k (delete k t) == t- where- rs = zip xs xs- t = fromList rs- k = head xs--prop_delete_lookup_ipv4 :: [AddrRange IPv4] -> Property-prop_delete_lookup_ipv4 = delete_lookup_ip--prop_delete_lookup_ipv6 :: [AddrRange IPv6] -> Property-prop_delete_lookup_ipv6 = delete_lookup_ip--delete_lookup_ip :: Routable a => [AddrRange a] -> Property-delete_lookup_ip xs = xs /= [] ==> case lookup k (delete k t) of- Nothing -> True- Just r -> r /= k && r >:> k- where- rs = zip xs xs- t = fromList rs- k = head xs--prop_convert_ipv4 :: IPv4 -> Property-prop_convert_ipv4 ip = True ==> (toIPv4 . fromIPv4) ip == ip--prop_convert_ipv6 :: IPv6 -> Property-prop_convert_ipv6 ip = True ==> (toIPv6 . fromIPv6) ip == ip--------------------------------------------------------------------ipv4_list :: [AddrRange IPv4]-ipv4_list = [- "0.0.0.0/0"- , "133.4.0.0/16"- , "133.5.0.0/16"- , "133.5.16.0/24"- , "133.5.23.0/24"- ]--case_fromto_ipv4 :: Assertion-case_fromto_ipv4 = (sort . toList . fromList $ pairs) @?= pairs- where- pairs = sort $ zip ipv4_list ipv4_list--case_lookup_ipv4 :: Assertion-case_lookup_ipv4 = do- let rt = fromList pairs- lookup "127.0.0.1" rt @?= Just "0.0.0.0/0"- lookup "133.3.0.1" rt @?= Just "0.0.0.0/0"- lookup "133.4.0.0" rt @?= Just "133.4.0.0/16"- lookup "133.4.0.1" rt @?= Just "133.4.0.0/16"- lookup "133.5.16.0" rt @?= Just "133.5.16.0/24"- lookup "133.5.16.1" rt @?= Just "133.5.16.0/24"- where- pairs = zip ipv4_list ipv4_list--case_findMatch_ipv4 :: Assertion-case_findMatch_ipv4 = do- let rt = fromList pairs- findMatch "127.0.0.1" rt @?= []- findMatch "133.5.23.0/23" rt @?= [("133.5.23.0/24","133.5.23.0/24")]- findMatch "133.5.0.0/16" rt @?= [- ("133.5.0.0/16","133.5.0.0/16")- , ("133.5.16.0/24","133.5.16.0/24")- , ("133.5.23.0/24","133.5.23.0/24")- ]- findMatch "133.4.0.0/16" rt @?= [("133.4.0.0/16", "133.4.0.0/16")]- findMatch "133.4.0.0/15" rt @?= [- ("133.4.0.0/16","133.4.0.0/16")- , ("133.5.0.0/16","133.5.0.0/16")- , ("133.5.16.0/24","133.5.16.0/24")- , ("133.5.23.0/24","133.5.23.0/24")- ]- findMatch "0.0.0.0/0" rt @?= [- ("0.0.0.0/0", "0.0.0.0/0")- , ("133.4.0.0/16", "133.4.0.0/16")- , ("133.5.0.0/16", "133.5.0.0/16")- , ("133.5.16.0/24", "133.5.16.0/24")- , ("133.5.23.0/24", "133.5.23.0/24")- ]- where- pairs = zip ipv4_list ipv4_list------------------------------------------------------------------
+ test/doctests.hs view
@@ -0,0 +1,6 @@+module Main where++import Test.DocTest++main :: IO ()+main = doctest ["-XOverloadedStrings", "Data/IP.hs", "Data/IP/RouteTable.hs"]