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.

195 lines
5.0 KiB

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