blob: 2b9254b03167163f3212274a97e81abd03768dbe [file] [log] [blame]
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
{-# LANGUAGE OverloadedStrings, RecordWildCards, ScopedTypeVariables #-}
module Main where
import Control.Exception
import Control.Monad
import Data.Functor
import Data.List.Split
import Data.String
import Network
import System.Environment
import System.Exit
import System.Posix.Unistd
import qualified Data.HashMap.Strict as Map
import qualified Data.HashSet as Set
import qualified Data.Vector as Vector
import ThriftTest_Iface
import ThriftTest_Types
import qualified ThriftTest_Client as Client
import Thrift.Transport
import Thrift.Transport.Handle
import Thrift.Protocol
import Thrift.Protocol.Binary
import Thrift.Protocol.Compact
import Thrift.Protocol.JSON
data Options = Options
{ host :: String
, port :: Int
, domainSocket :: String
, transport :: String
, protocol :: ProtocolType
, ssl :: Bool
, testLoops :: Int
}
deriving (Show, Eq)
data ProtocolType = Binary
| Compact
| JSON
deriving (Show, Eq)
getProtocol :: String -> ProtocolType
getProtocol "binary" = Binary
getProtocol "compact" = Compact
getProtocol "json" = JSON
getProtocol p = error $ "Unsupported Protocol: " ++ p
defaultOptions :: Options
defaultOptions = Options
{ port = 9090
, domainSocket = ""
, host = "localhost"
, transport = "framed"
, protocol = Binary
, ssl = False
, testLoops = 1
}
runClient :: (Protocol p, Transport t) => p t -> IO ()
runClient p = do
let prot = (p,p)
putStrLn "Starting Tests"
-- VOID Test
Client.testVoid prot
-- String Test
s <- Client.testString prot "Test"
when (s /= "Test") exitFailure
-- Byte Test
byte <- Client.testByte prot 1
when (byte /= 1) exitFailure
-- I32 Test
i32 <- Client.testI32 prot (-1)
when (i32 /= -1) exitFailure
-- I64 Test
i64 <- Client.testI64 prot (-34359738368)
when (i64 /= -34359738368) exitFailure
-- Double Test
dub <- Client.testDouble prot (-5.2098523)
when (abs (dub + 5.2098523) > 0.001) exitFailure
-- Struct Test
let structIn = Xtruct{ xtruct_string_thing = "Zero"
, xtruct_byte_thing = 1
, xtruct_i32_thing = -3
, xtruct_i64_thing = -5
}
structOut <- Client.testStruct prot structIn
when (structIn /= structOut) exitFailure
-- Nested Struct Test
let nestIn = Xtruct2{ xtruct2_byte_thing = 1
, xtruct2_struct_thing = structIn
, xtruct2_i32_thing = 5
}
nestOut <- Client.testNest prot nestIn
when (nestIn /= nestOut) exitSuccess
-- Map Test
let mapIn = Map.fromList $ map (\i -> (i, i-10)) [1..5]
mapOut <- Client.testMap prot mapIn
when (mapIn /= mapOut) exitSuccess
-- Set Test
let setIn = Set.fromList [-2..3]
setOut <- Client.testSet prot setIn
when (setIn /= setOut) exitFailure
-- List Test
let listIn = Vector.fromList [-2..3]
listOut <- Client.testList prot listIn
when (listIn /= listOut) exitFailure
-- Enum Test
numz1 <- Client.testEnum prot ONE
when (numz1 /= ONE) exitFailure
numz2 <- Client.testEnum prot TWO
when (numz2 /= TWO) exitFailure
numz5 <- Client.testEnum prot FIVE
when (numz5 /= FIVE) exitFailure
-- Typedef Test
uid <- Client.testTypedef prot 309858235082523
when (uid /= 309858235082523) exitFailure
-- Nested Map Test
_ <- Client.testMapMap prot 1
-- Exception Test
exn1 <- try $ Client.testException prot "Xception"
case exn1 of
Left (Xception _ _) -> return ()
_ -> putStrLn (show exn1) >> exitFailure
exn2 <- try $ Client.testException prot "TException"
case exn2 of
Left (_ :: SomeException) -> return ()
Right _ -> exitFailure
exn3 <- try $ Client.testException prot "success"
case exn3 of
Left (_ :: SomeException) -> exitFailure
Right _ -> return ()
-- Multi Exception Test
multi1 <- try $ Client.testMultiException prot "Xception" "test 1"
case multi1 of
Left (Xception _ _) -> return ()
_ -> exitFailure
multi2 <- try $ Client.testMultiException prot "Xception2" "test 2"
case multi2 of
Left (Xception2 _ _) -> return ()
_ -> exitFailure
multi3 <- try $ Client.testMultiException prot "success" "test 3"
case multi3 of
Left (_ :: SomeException) -> exitFailure
Right _ -> return ()
main :: IO ()
main = do
options <- flip parseFlags defaultOptions <$> getArgs
case options of
Nothing -> showHelp
Just Options{..} -> do
handle <- hOpen (host, PortNumber $ fromIntegral port)
let client = case protocol of
Binary -> runClient $ BinaryProtocol handle
Compact -> runClient $ CompactProtocol handle
JSON -> runClient $ JSONProtocol handle
replicateM_ testLoops client
putStrLn "COMPLETED SUCCESSFULLY"
parseFlags :: [String] -> Options -> Maybe Options
parseFlags (flag : flags) opts = do
let pieces = splitOn "=" flag
case pieces of
"--port" : arg : _ -> parseFlags flags opts{ port = read arg }
"--domain-socket" : arg : _ -> parseFlags flags opts{ domainSocket = read arg }
"--host" : arg : _ -> parseFlags flags opts{ host = arg }
"--transport" : arg : _ -> parseFlags flags opts{ transport = arg }
"--protocol" : arg : _ -> parseFlags flags opts{ protocol = getProtocol arg }
"--h" : _ -> Nothing
"--help" : _ -> Nothing
"--ssl" : _ -> parseFlags flags opts{ ssl = True }
"--processor-events" : _ -> parseFlags flags opts
parseFlags (flag : arg : flags) opts
| flag == "-n" = parseFlags flags opts{ testLoops = read arg }
parseFlags [] opts = Just opts
showHelp :: IO ()
showHelp = putStrLn
"Allowed options:\n\
\ -h [ --help ] produce help message\n\
\ --host arg (=localhost) Host to connect\n\
\ --port arg (=9090) Port number to connect\n\
\ --domain-socket arg Domain Socket (e.g. /tmp/ThriftTest.thrift),\n\
\ instead of host and port\n\
\ --transport arg (=buffered) Transport: buffered, framed, http, evhttp\n\
\ --protocol arg (=binary) Protocol: binary, compact, json\n\
\ --ssl Encrypted Transport using SSL\n\
\ -n [ --testloops ] arg (=1) Number of Tests"