You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
4.9 KiB

8 years ago
8 years ago
  1. package mock
  2. import (
  3. abci "github.com/tendermint/abci/types"
  4. "github.com/tendermint/tendermint/rpc/client"
  5. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  6. "github.com/tendermint/tendermint/types"
  7. )
  8. // ABCIApp will send all abci related request to the named app,
  9. // so you can test app behavior from a client without needing
  10. // an entire tendermint node
  11. type ABCIApp struct {
  12. App abci.Application
  13. }
  14. func (a ABCIApp) _assertABCIClient() client.ABCIClient {
  15. return a
  16. }
  17. func (a ABCIApp) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
  18. return &ctypes.ResultABCIInfo{a.App.Info()}, nil
  19. }
  20. func (a ABCIApp) ABCIQuery(path string, data []byte, prove bool) (*ctypes.ResultABCIQuery, error) {
  21. q := a.App.Query(abci.RequestQuery{data, path, 0, prove})
  22. return &ctypes.ResultABCIQuery{q}, nil
  23. }
  24. func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
  25. res := ctypes.ResultBroadcastTxCommit{}
  26. c := a.App.CheckTx(tx)
  27. res.CheckTx = &abci.ResponseCheckTx{c.Code, c.Data, c.Log}
  28. if !c.IsOK() {
  29. return &res, nil
  30. }
  31. d := a.App.DeliverTx(tx)
  32. res.DeliverTx = &abci.ResponseDeliverTx{d.Code, d.Data, d.Log}
  33. return &res, nil
  34. }
  35. func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
  36. c := a.App.CheckTx(tx)
  37. // and this gets writen in a background thread...
  38. if c.IsOK() {
  39. go func() { a.App.DeliverTx(tx) }()
  40. }
  41. return &ctypes.ResultBroadcastTx{c.Code, c.Data, c.Log, tx.Hash()}, nil
  42. }
  43. func (a ABCIApp) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
  44. c := a.App.CheckTx(tx)
  45. // and this gets writen in a background thread...
  46. if c.IsOK() {
  47. go func() { a.App.DeliverTx(tx) }()
  48. }
  49. return &ctypes.ResultBroadcastTx{c.Code, c.Data, c.Log, tx.Hash()}, nil
  50. }
  51. // ABCIMock will send all abci related request to the named app,
  52. // so you can test app behavior from a client without needing
  53. // an entire tendermint node
  54. type ABCIMock struct {
  55. Info Call
  56. Query Call
  57. BroadcastCommit Call
  58. Broadcast Call
  59. }
  60. func (m ABCIMock) _assertABCIClient() client.ABCIClient {
  61. return m
  62. }
  63. func (m ABCIMock) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
  64. res, err := m.Info.GetResponse(nil)
  65. if err != nil {
  66. return nil, err
  67. }
  68. return &ctypes.ResultABCIInfo{res.(abci.ResponseInfo)}, nil
  69. }
  70. func (m ABCIMock) ABCIQuery(path string, data []byte, prove bool) (*ctypes.ResultABCIQuery, error) {
  71. res, err := m.Query.GetResponse(QueryArgs{path, data, prove})
  72. if err != nil {
  73. return nil, err
  74. }
  75. return &ctypes.ResultABCIQuery{res.(abci.ResponseQuery)}, nil
  76. }
  77. func (m ABCIMock) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
  78. res, err := m.BroadcastCommit.GetResponse(tx)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return res.(*ctypes.ResultBroadcastTxCommit), nil
  83. }
  84. func (m ABCIMock) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
  85. res, err := m.Broadcast.GetResponse(tx)
  86. if err != nil {
  87. return nil, err
  88. }
  89. return res.(*ctypes.ResultBroadcastTx), nil
  90. }
  91. func (m ABCIMock) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
  92. res, err := m.Broadcast.GetResponse(tx)
  93. if err != nil {
  94. return nil, err
  95. }
  96. return res.(*ctypes.ResultBroadcastTx), nil
  97. }
  98. // ABCIRecorder can wrap another type (ABCIApp, ABCIMock, or Client)
  99. // and record all ABCI related calls.
  100. type ABCIRecorder struct {
  101. Client client.ABCIClient
  102. Calls []Call
  103. }
  104. func NewABCIRecorder(client client.ABCIClient) *ABCIRecorder {
  105. return &ABCIRecorder{
  106. Client: client,
  107. Calls: []Call{},
  108. }
  109. }
  110. func (r *ABCIRecorder) _assertABCIClient() client.ABCIClient {
  111. return r
  112. }
  113. type QueryArgs struct {
  114. Path string
  115. Data []byte
  116. Prove bool
  117. }
  118. func (r *ABCIRecorder) addCall(call Call) {
  119. r.Calls = append(r.Calls, call)
  120. }
  121. func (r *ABCIRecorder) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
  122. res, err := r.Client.ABCIInfo()
  123. r.addCall(Call{
  124. Name: "abci_info",
  125. Response: res,
  126. Error: err,
  127. })
  128. return res, err
  129. }
  130. func (r *ABCIRecorder) ABCIQuery(path string, data []byte, prove bool) (*ctypes.ResultABCIQuery, error) {
  131. res, err := r.Client.ABCIQuery(path, data, prove)
  132. r.addCall(Call{
  133. Name: "abci_query",
  134. Args: QueryArgs{path, data, prove},
  135. Response: res,
  136. Error: err,
  137. })
  138. return res, err
  139. }
  140. func (r *ABCIRecorder) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
  141. res, err := r.Client.BroadcastTxCommit(tx)
  142. r.addCall(Call{
  143. Name: "broadcast_tx_commit",
  144. Args: tx,
  145. Response: res,
  146. Error: err,
  147. })
  148. return res, err
  149. }
  150. func (r *ABCIRecorder) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
  151. res, err := r.Client.BroadcastTxAsync(tx)
  152. r.addCall(Call{
  153. Name: "broadcast_tx_async",
  154. Args: tx,
  155. Response: res,
  156. Error: err,
  157. })
  158. return res, err
  159. }
  160. func (r *ABCIRecorder) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
  161. res, err := r.Client.BroadcastTxSync(tx)
  162. r.addCall(Call{
  163. Name: "broadcast_tx_sync",
  164. Args: tx,
  165. Response: res,
  166. Error: err,
  167. })
  168. return res, err
  169. }