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.

308 lines
7.8 KiB

8 years ago
8 years ago
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
7 years ago
7 years ago
7 years ago
8 years ago
  1. package dummy
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "sort"
  6. "testing"
  7. "github.com/stretchr/testify/require"
  8. cmn "github.com/tendermint/tmlibs/common"
  9. "github.com/tendermint/tmlibs/log"
  10. abcicli "github.com/tendermint/abci/client"
  11. "github.com/tendermint/abci/example/code"
  12. abciserver "github.com/tendermint/abci/server"
  13. "github.com/tendermint/abci/types"
  14. )
  15. func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
  16. ar := app.DeliverTx(tx)
  17. require.False(t, ar.IsErr(), ar)
  18. // repeating tx doesn't raise error
  19. ar = app.DeliverTx(tx)
  20. require.False(t, ar.IsErr(), ar)
  21. // make sure query is fine
  22. resQuery := app.Query(types.RequestQuery{
  23. Path: "/store",
  24. Data: []byte(key),
  25. })
  26. require.Equal(t, code.CodeTypeOK, resQuery.Code)
  27. require.Equal(t, value, string(resQuery.Value))
  28. // make sure proof is fine
  29. resQuery = app.Query(types.RequestQuery{
  30. Path: "/store",
  31. Data: []byte(key),
  32. Prove: true,
  33. })
  34. require.EqualValues(t, code.CodeTypeOK, resQuery.Code)
  35. require.Equal(t, value, string(resQuery.Value))
  36. }
  37. func TestDummyKV(t *testing.T) {
  38. dummy := NewDummyApplication()
  39. key := "abc"
  40. value := key
  41. tx := []byte(key)
  42. testDummy(t, dummy, tx, key, value)
  43. value = "def"
  44. tx = []byte(key + "=" + value)
  45. testDummy(t, dummy, tx, key, value)
  46. }
  47. func TestPersistentDummyKV(t *testing.T) {
  48. dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
  49. if err != nil {
  50. t.Fatal(err)
  51. }
  52. dummy := NewPersistentDummyApplication(dir)
  53. key := "abc"
  54. value := key
  55. tx := []byte(key)
  56. testDummy(t, dummy, tx, key, value)
  57. value = "def"
  58. tx = []byte(key + "=" + value)
  59. testDummy(t, dummy, tx, key, value)
  60. }
  61. func TestPersistentDummyInfo(t *testing.T) {
  62. dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. dummy := NewPersistentDummyApplication(dir)
  67. InitDummy(dummy)
  68. height := int64(0)
  69. resInfo := dummy.Info(types.RequestInfo{})
  70. if resInfo.LastBlockHeight != height {
  71. t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
  72. }
  73. // make and apply block
  74. height = int64(1)
  75. hash := []byte("foo")
  76. header := types.Header{
  77. Height: int64(height),
  78. }
  79. dummy.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil})
  80. dummy.EndBlock(types.RequestEndBlock{header.Height})
  81. dummy.Commit()
  82. resInfo = dummy.Info(types.RequestInfo{})
  83. if resInfo.LastBlockHeight != height {
  84. t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
  85. }
  86. }
  87. // add a validator, remove a validator, update a validator
  88. func TestValUpdates(t *testing.T) {
  89. dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. dummy := NewPersistentDummyApplication(dir)
  94. // init with some validators
  95. total := 10
  96. nInit := 5
  97. vals := RandVals(total)
  98. // iniitalize with the first nInit
  99. dummy.InitChain(types.RequestInitChain{vals[:nInit]})
  100. vals1, vals2 := vals[:nInit], dummy.Validators()
  101. valsEqual(t, vals1, vals2)
  102. var v1, v2, v3 types.Validator
  103. // add some validators
  104. v1, v2 = vals[nInit], vals[nInit+1]
  105. diff := []types.Validator{v1, v2}
  106. tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
  107. tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
  108. makeApplyBlock(t, dummy, 1, diff, tx1, tx2)
  109. vals1, vals2 = vals[:nInit+2], dummy.Validators()
  110. valsEqual(t, vals1, vals2)
  111. // remove some validators
  112. v1, v2, v3 = vals[nInit-2], vals[nInit-1], vals[nInit]
  113. v1.Power = 0
  114. v2.Power = 0
  115. v3.Power = 0
  116. diff = []types.Validator{v1, v2, v3}
  117. tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
  118. tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
  119. tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
  120. makeApplyBlock(t, dummy, 2, diff, tx1, tx2, tx3)
  121. vals1 = append(vals[:nInit-2], vals[nInit+1])
  122. vals2 = dummy.Validators()
  123. valsEqual(t, vals1, vals2)
  124. // update some validators
  125. v1 = vals[0]
  126. if v1.Power == 5 {
  127. v1.Power = 6
  128. } else {
  129. v1.Power = 5
  130. }
  131. diff = []types.Validator{v1}
  132. tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
  133. makeApplyBlock(t, dummy, 3, diff, tx1)
  134. vals1 = append([]types.Validator{v1}, vals1[1:]...)
  135. vals2 = dummy.Validators()
  136. valsEqual(t, vals1, vals2)
  137. }
  138. func makeApplyBlock(t *testing.T, dummy types.Application, heightInt int, diff []types.Validator, txs ...[]byte) {
  139. // make and apply block
  140. height := int64(heightInt)
  141. hash := []byte("foo")
  142. header := types.Header{
  143. Height: height,
  144. }
  145. dummy.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil})
  146. for _, tx := range txs {
  147. if r := dummy.DeliverTx(tx); r.IsErr() {
  148. t.Fatal(r)
  149. }
  150. }
  151. resEndBlock := dummy.EndBlock(types.RequestEndBlock{header.Height})
  152. dummy.Commit()
  153. valsEqual(t, diff, resEndBlock.ValidatorUpdates)
  154. }
  155. // order doesn't matter
  156. func valsEqual(t *testing.T, vals1, vals2 []types.Validator) {
  157. if len(vals1) != len(vals2) {
  158. t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
  159. }
  160. sort.Sort(types.Validators(vals1))
  161. sort.Sort(types.Validators(vals2))
  162. for i, v1 := range vals1 {
  163. v2 := vals2[i]
  164. if !bytes.Equal(v1.PubKey, v2.PubKey) ||
  165. v1.Power != v2.Power {
  166. t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
  167. }
  168. }
  169. }
  170. func makeSocketClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
  171. // Start the listener
  172. socket := cmn.Fmt("unix://%s.sock", name)
  173. logger := log.TestingLogger()
  174. server := abciserver.NewSocketServer(socket, app)
  175. server.SetLogger(logger.With("module", "abci-server"))
  176. if err := server.Start(); err != nil {
  177. return nil, nil, err
  178. }
  179. // Connect to the socket
  180. client := abcicli.NewSocketClient(socket, false)
  181. client.SetLogger(logger.With("module", "abci-client"))
  182. if err := client.Start(); err != nil {
  183. server.Stop()
  184. return nil, nil, err
  185. }
  186. return client, server, nil
  187. }
  188. func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
  189. // Start the listener
  190. socket := cmn.Fmt("unix://%s.sock", name)
  191. logger := log.TestingLogger()
  192. gapp := types.NewGRPCApplication(app)
  193. server := abciserver.NewGRPCServer(socket, gapp)
  194. server.SetLogger(logger.With("module", "abci-server"))
  195. if err := server.Start(); err != nil {
  196. return nil, nil, err
  197. }
  198. client := abcicli.NewGRPCClient(socket, true)
  199. client.SetLogger(logger.With("module", "abci-client"))
  200. if err := client.Start(); err != nil {
  201. server.Stop()
  202. return nil, nil, err
  203. }
  204. return client, server, nil
  205. }
  206. func TestClientServer(t *testing.T) {
  207. // set up socket app
  208. dummy := NewDummyApplication()
  209. client, server, err := makeSocketClientServer(dummy, "dummy-socket")
  210. require.Nil(t, err)
  211. defer server.Stop()
  212. defer client.Stop()
  213. runClientTests(t, client)
  214. // set up grpc app
  215. dummy = NewDummyApplication()
  216. gclient, gserver, err := makeGRPCClientServer(dummy, "dummy-grpc")
  217. require.Nil(t, err)
  218. defer gserver.Stop()
  219. defer gclient.Stop()
  220. runClientTests(t, gclient)
  221. }
  222. func runClientTests(t *testing.T, client abcicli.Client) {
  223. // run some tests....
  224. key := "abc"
  225. value := key
  226. tx := []byte(key)
  227. testClient(t, client, tx, key, value)
  228. value = "def"
  229. tx = []byte(key + "=" + value)
  230. testClient(t, client, tx, key, value)
  231. }
  232. func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) {
  233. ar, err := app.DeliverTxSync(tx)
  234. require.NoError(t, err)
  235. require.False(t, ar.IsErr(), ar)
  236. // repeating tx doesn't raise error
  237. ar, err = app.DeliverTxSync(tx)
  238. require.NoError(t, err)
  239. require.False(t, ar.IsErr(), ar)
  240. // make sure query is fine
  241. resQuery, err := app.QuerySync(types.RequestQuery{
  242. Path: "/store",
  243. Data: []byte(key),
  244. })
  245. require.Nil(t, err)
  246. require.Equal(t, code.CodeTypeOK, resQuery.Code)
  247. require.Equal(t, value, string(resQuery.Value))
  248. // make sure proof is fine
  249. resQuery, err = app.QuerySync(types.RequestQuery{
  250. Path: "/store",
  251. Data: []byte(key),
  252. Prove: true,
  253. })
  254. require.Nil(t, err)
  255. require.Equal(t, code.CodeTypeOK, resQuery.Code)
  256. require.Equal(t, value, string(resQuery.Value))
  257. }