You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "John Chee (JIRA)" <ji...@apache.org> on 2014/08/26 06:30:57 UTC

[jira] [Commented] (THRIFT-728) Make generated Haskell code an instance of Arbitrary

    [ https://issues.apache.org/jira/browse/THRIFT-728?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14110260#comment-14110260 ] 

John Chee commented on THRIFT-728:
----------------------------------

This is also resolved my [~noamz]'s recent patch.

haskell code:
{code}
instance QC.Arbitrary Numberz where
  arbitrary = QC.elements (P.enumFromTo P.minBound P.maxBound)
{code}

thrift:
{code}
enum Numberz
{
  ONE = 1,
  TWO,
  THREE,
  FIVE = 5,
  SIX,
  EIGHT = 8
}
{code}

cc: [~roger.meier]

> 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: Haskell - Compiler, Haskell - Library
>         Environment: All
>            Reporter: Aran Donohue
>            Priority: Minor
>              Labels: test
>         Attachments: arbitrary.patch
>
>   Original Estimate: 96h
>  Remaining Estimate: 96h
>
> 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 was sent by Atlassian JIRA
(v6.2#6252)