packages feed

crypto-pubkey-openssh-0.1.0: tests/Tests.hs

{-# LANGUAGE CPP #-}

module Main where

import Data.Monoid ((<>))
import System.FilePath.Posix ((</>), (<.>))
import System.Process (runCommand, waitForProcess)
import System.IO.Temp (withSystemTempDirectory)
import qualified Data.ByteString as SB

import Test.Framework (Test, defaultMain, testGroup)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Test.QuickCheck (Property, Arbitrary(..), elements)
import Test.QuickCheck.Monadic (monadicIO, run, assert)

import Crypto.PubKey.OpenSsh.Types (OpenSshPublicKeyType(..),
                                    OpenSshPublicKey(..))
import Crypto.PubKey.OpenSsh.Encode (encode)
import Crypto.PubKey.OpenSsh.Decode (decode)

type StrictByteString = SB.ByteString

instance Arbitrary OpenSshPublicKeyType where
    arbitrary = elements [OpenSshPublicKeyTypeRsa, OpenSshPublicKeyTypeDsa]

openSshPubKey :: OpenSshPublicKeyType -> IO StrictByteString
openSshPubKey t = withSystemTempDirectory base $ \dir -> do
    let path = dir </> typ
    let run = "ssh-keygen -t " <> typ <> " -N \"\" -f " <> path
    waitForProcess =<< runCommand run
    fmap SB.init $ SB.readFile $ path <.> "pub"
  where
    base = "crypto-pubkey-openssh-tests"
    typ = case t of
        OpenSshPublicKeyTypeRsa -> "rsa"
        OpenSshPublicKeyTypeDsa -> "dsa"

testWithOpenSsh :: OpenSshPublicKeyType -> Property
testWithOpenSsh t = monadicIO $ do
    pub <- run $ openSshPubKey t
    assert $ check (decode pub) pub
  where
    check = case t of
        OpenSshPublicKeyTypeRsa -> \r b -> case r of
            Right k@(OpenSshPublicKeyRsa _ _) ->
                encode k == b
            _                                 -> False
        OpenSshPublicKeyTypeDsa -> \r b -> case r of
            Right k@(OpenSshPublicKeyDsa _ _) ->
                encode k == b
            _                                 -> False

main :: IO ()
main = defaultMain
    [
#ifdef OPENSSH
      testGroup "ssh-keygen" [ testProperty "decode" $ testWithOpenSsh
                             ]
#endif
    ]