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.

309 lines
7.7 KiB

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