Make generated Haskell code an instance of Arbitrary
----------------------------------------------------
Key: THRIFT-728
URL: https://issues.apache.org/jira/browse/THRIFT-728
Project: Thrift
Issue Type: New Feature
Components: Compiler (Haskell), Library (Haskell)
Environment: All
Reporter: Aran Donohue
Priority: Minor
Attachments: arbitrary.patch
The patch
* Generates Arbitrary instances for Thrift structs, enums and exceptions
* Provides Arbitrary instances for GHC's Int64, Data.Map.Map and Data.Set.Set
* Makes Thrift enums instances of Bounded and improves the Enum instance
declaration
Making a type an instance of Test.QuickCheck.Arbitrary specifies how to
generate random instances of the struct. This is useful for testing.
For example, consider the following simple Thrift declaration:
{code:title=distributed_log.thrift}
enum LogLevel { DEBUG, INFO, WARNING, ERROR }
typedef i32 UnixTimeStamp
struct LogEntry {
1: LogLevel level,
2: UnixTimeStamp timestamp,
3: string message
}
service Logger {
void log(1: LogEntry entry)
}
{code}
With the patch, the following program (import statements elided) is a fuzzer
for the log service.
{code:title=LogTest.hs}
-- ripped from Test.QuickCheck.Gen.sample'
infexamples ∷ Gen a → IO [a]
infexamples (MkGen m) =
do rnd ← newStdGen
let rnds rnd = rnd1 : rnds rnd2 where (rnd1, rnd2) = split rnd
return [(m r n) | (r, n) ← rnds rnd `zip` [0,2..] ]
infentries = infexamples (arbitrary ∷ Gen LogEntry)
main = do entries ← infentries
forM entries logAnEntry
logAnEntry entry = do
transport ← hOpen ("localhost", PortNumber 9090)
let binProto = BinaryProtocol transport
let client = (binProto, binProto)
(Client.log client) entry
tClose transport
`Control.Exception.catch`
(λ(TransportExn s t) → print s)
--On systems with Haskell we could just generate a fuzzer like this one.
{code}
In implementing the Arbitrary instances, it was useful to make Thrift enums
instances of Bounded and to improve the Enum instance. Specifically, whereas
before,
{code}
[DEBUG .. ]
{code}
would throw an exception, now it behaves as expected without an exception.
I consider the patch incomplete. It's more of a starting point for a discussion
at this point than a serious candidate for inclusion. If it is of interest, I'd
appreciate some direction on testing it as well as style, and I'd welcome any
other comments or thoughts.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.