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.

208 lines
5.7 KiB

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