blob: 6c25f5b27755b3b63b04f95c73a12f7dac15d99a [file] [log] [blame]
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -07001--
2-- Licensed to the Apache Software Foundation (ASF) under one
3-- or more contributor license agreements. See the NOTICE file
4-- distributed with this work for additional information
5-- regarding copyright ownership. The ASF licenses this file
6-- to you under the Apache License, Version 2.0 (the
7-- "License"); you may not use this file except in compliance
8-- with the License. You may obtain a copy of the License at
9--
10-- http://www.apache.org/licenses/LICENSE-2.0
11--
12-- Unless required by applicable law or agreed to in writing,
13-- software distributed under the License is distributed on an
14-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15-- KIND, either express or implied. See the License for the
16-- specific language governing permissions and limitations
17-- under the License.
18--
19
20{-# LANGUAGE OverloadedStrings, RecordWildCards, ScopedTypeVariables #-}
21module Main where
22
23import Control.Exception
24import Control.Monad
25import Data.Functor
cdwijayarathnad9217912014-08-15 22:18:30 +053026import Data.List.Split
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -070027import Data.String
28import Network
29import System.Environment
30import System.Exit
31import System.Posix.Unistd
32import qualified Data.HashMap.Strict as Map
33import qualified Data.HashSet as Set
34import qualified Data.Vector as Vector
35
36import ThriftTest_Iface
37import ThriftTest_Types
38import qualified ThriftTest_Client as Client
39
40import Thrift.Transport
41import Thrift.Transport.Handle
42import Thrift.Protocol
43import Thrift.Protocol.Binary
44import Thrift.Protocol.Compact
45import Thrift.Protocol.JSON
46
47data Options = Options
48 { host :: String
49 , port :: Int
50 , domainSocket :: String
51 , transport :: String
52 , protocol :: ProtocolType
53 , ssl :: Bool
54 , testLoops :: Int
55 }
56 deriving (Show, Eq)
57
58data ProtocolType = Binary
59 | Compact
60 | JSON
61 deriving (Show, Eq)
62
63getProtocol :: String -> ProtocolType
64getProtocol "binary" = Binary
65getProtocol "compact" = Compact
66getProtocol "json" = JSON
67getProtocol p = error $ "Unsupported Protocol: " ++ p
68
69defaultOptions :: Options
70defaultOptions = Options
71 { port = 9090
72 , domainSocket = ""
73 , host = "localhost"
74 , transport = "framed"
75 , protocol = Binary
76 , ssl = False
77 , testLoops = 1
78 }
79
80runClient :: (Protocol p, Transport t) => p t -> IO ()
81runClient p = do
82 let prot = (p,p)
83 putStrLn "Starting Tests"
cdwijayarathnad9217912014-08-15 22:18:30 +053084
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -070085 -- VOID Test
86 Client.testVoid prot
cdwijayarathnad9217912014-08-15 22:18:30 +053087
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -070088 -- String Test
89 s <- Client.testString prot "Test"
90 when (s /= "Test") exitFailure
91
92 -- Byte Test
93 byte <- Client.testByte prot 1
94 when (byte /= 1) exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +053095
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -070096 -- I32 Test
97 i32 <- Client.testI32 prot (-1)
98 when (i32 /= -1) exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +053099
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700100 -- I64 Test
101 i64 <- Client.testI64 prot (-34359738368)
102 when (i64 /= -34359738368) exitFailure
103
104 -- Double Test
105 dub <- Client.testDouble prot (-5.2098523)
106 when (abs (dub + 5.2098523) > 0.001) exitFailure
107
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100108 -- TODO: call Client.testBinary
109
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700110 -- Struct Test
111 let structIn = Xtruct{ xtruct_string_thing = "Zero"
112 , xtruct_byte_thing = 1
113 , xtruct_i32_thing = -3
114 , xtruct_i64_thing = -5
115 }
cdwijayarathnad9217912014-08-15 22:18:30 +0530116 structOut <- Client.testStruct prot structIn
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700117 when (structIn /= structOut) exitFailure
118
119 -- Nested Struct Test
120 let nestIn = Xtruct2{ xtruct2_byte_thing = 1
121 , xtruct2_struct_thing = structIn
122 , xtruct2_i32_thing = 5
123 }
124 nestOut <- Client.testNest prot nestIn
125 when (nestIn /= nestOut) exitSuccess
cdwijayarathnad9217912014-08-15 22:18:30 +0530126
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700127 -- Map Test
128 let mapIn = Map.fromList $ map (\i -> (i, i-10)) [1..5]
129 mapOut <- Client.testMap prot mapIn
130 when (mapIn /= mapOut) exitSuccess
cdwijayarathnad9217912014-08-15 22:18:30 +0530131
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700132 -- Set Test
133 let setIn = Set.fromList [-2..3]
134 setOut <- Client.testSet prot setIn
135 when (setIn /= setOut) exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +0530136
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700137 -- List Test
138 let listIn = Vector.fromList [-2..3]
139 listOut <- Client.testList prot listIn
140 when (listIn /= listOut) exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +0530141
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700142 -- Enum Test
143 numz1 <- Client.testEnum prot ONE
144 when (numz1 /= ONE) exitFailure
145
146 numz2 <- Client.testEnum prot TWO
147 when (numz2 /= TWO) exitFailure
148
149 numz5 <- Client.testEnum prot FIVE
150 when (numz5 /= FIVE) exitFailure
151
152 -- Typedef Test
153 uid <- Client.testTypedef prot 309858235082523
154 when (uid /= 309858235082523) exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +0530155
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700156 -- Nested Map Test
157 _ <- Client.testMapMap prot 1
cdwijayarathnad9217912014-08-15 22:18:30 +0530158
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700159 -- Exception Test
160 exn1 <- try $ Client.testException prot "Xception"
161 case exn1 of
162 Left (Xception _ _) -> return ()
163 _ -> putStrLn (show exn1) >> exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +0530164
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700165 exn2 <- try $ Client.testException prot "TException"
166 case exn2 of
167 Left (_ :: SomeException) -> return ()
168 Right _ -> exitFailure
cdwijayarathnad9217912014-08-15 22:18:30 +0530169
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700170 exn3 <- try $ Client.testException prot "success"
171 case exn3 of
172 Left (_ :: SomeException) -> exitFailure
173 Right _ -> return ()
cdwijayarathnad9217912014-08-15 22:18:30 +0530174
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700175 -- Multi Exception Test
176 multi1 <- try $ Client.testMultiException prot "Xception" "test 1"
177 case multi1 of
178 Left (Xception _ _) -> return ()
179 _ -> exitFailure
180
181 multi2 <- try $ Client.testMultiException prot "Xception2" "test 2"
182 case multi2 of
183 Left (Xception2 _ _) -> return ()
184 _ -> exitFailure
185
186 multi3 <- try $ Client.testMultiException prot "success" "test 3"
187 case multi3 of
188 Left (_ :: SomeException) -> exitFailure
189 Right _ -> return ()
190
191
192main :: IO ()
193main = do
194 options <- flip parseFlags defaultOptions <$> getArgs
195 case options of
196 Nothing -> showHelp
197 Just Options{..} -> do
198 handle <- hOpen (host, PortNumber $ fromIntegral port)
199 let client = case protocol of
200 Binary -> runClient $ BinaryProtocol handle
201 Compact -> runClient $ CompactProtocol handle
202 JSON -> runClient $ JSONProtocol handle
cdwijayarathnad9217912014-08-15 22:18:30 +0530203 replicateM_ testLoops client
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700204 putStrLn "COMPLETED SUCCESSFULLY"
205
206parseFlags :: [String] -> Options -> Maybe Options
cdwijayarathnad9217912014-08-15 22:18:30 +0530207parseFlags (flag : flags) opts = do
208 let pieces = splitOn "=" flag
209 case pieces of
210 "--port" : arg : _ -> parseFlags flags opts{ port = read arg }
211 "--domain-socket" : arg : _ -> parseFlags flags opts{ domainSocket = read arg }
212 "--host" : arg : _ -> parseFlags flags opts{ host = arg }
213 "--transport" : arg : _ -> parseFlags flags opts{ transport = arg }
214 "--protocol" : arg : _ -> parseFlags flags opts{ protocol = getProtocol arg }
cdwijayarathna7191bc92014-08-16 23:36:07 +0530215 "-n" : arg : _ -> parseFlags flags opts{ testLoops = read arg }
cdwijayarathnad9217912014-08-15 22:18:30 +0530216 "--h" : _ -> Nothing
217 "--help" : _ -> Nothing
218 "--ssl" : _ -> parseFlags flags opts{ ssl = True }
219 "--processor-events" : _ -> parseFlags flags opts
cdwijayarathna7191bc92014-08-16 23:36:07 +0530220 _ -> Nothing
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700221parseFlags [] opts = Just opts
222
223showHelp :: IO ()
224showHelp = putStrLn
225 "Allowed options:\n\
226 \ -h [ --help ] produce help message\n\
227 \ --host arg (=localhost) Host to connect\n\
228 \ --port arg (=9090) Port number to connect\n\
cdwijayarathnad9217912014-08-15 22:18:30 +0530229 \ --domain-socket arg Domain Socket (e.g. /tmp/ThriftTest.thrift),\n\
Noam Zilbersteinaf5d64a2014-07-31 15:44:13 -0700230 \ instead of host and port\n\
231 \ --transport arg (=buffered) Transport: buffered, framed, http, evhttp\n\
232 \ --protocol arg (=binary) Protocol: binary, compact, json\n\
233 \ --ssl Encrypted Transport using SSL\n\
234 \ -n [ --testloops ] arg (=1) Number of Tests"