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.

203 lines
4.7 KiB

8 years ago
8 years ago
8 years ago
8 years ago
  1. package dummy
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "sort"
  6. "testing"
  7. . "github.com/tendermint/go-common"
  8. "github.com/tendermint/go-crypto"
  9. "github.com/tendermint/go-wire"
  10. "github.com/tendermint/abci/types"
  11. )
  12. func testDummy(t *testing.T, dummy types.Application, tx []byte, key, value string) {
  13. if r := dummy.DeliverTx(tx); r.IsErr() {
  14. t.Fatal(r)
  15. }
  16. if r := dummy.DeliverTx(tx); r.IsErr() {
  17. t.Fatal(r)
  18. }
  19. r := dummy.Query([]byte(key))
  20. if r.IsErr() {
  21. t.Fatal(r)
  22. }
  23. q := new(QueryResult)
  24. if err := wire.ReadJSONBytes(r.Data, q); err != nil {
  25. t.Fatal(err)
  26. }
  27. if q.Value != value {
  28. t.Fatalf("Got %s, expected %s", q.Value, value)
  29. }
  30. }
  31. func TestDummyKV(t *testing.T) {
  32. dummy := NewDummyApplication()
  33. key := "abc"
  34. value := key
  35. tx := []byte(key)
  36. testDummy(t, dummy, tx, key, value)
  37. value = "def"
  38. tx = []byte(key + "=" + value)
  39. testDummy(t, dummy, tx, key, value)
  40. }
  41. func TestPersistentDummyKV(t *testing.T) {
  42. dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
  43. if err != nil {
  44. t.Fatal(err)
  45. }
  46. dummy := NewPersistentDummyApplication(dir)
  47. key := "abc"
  48. value := key
  49. tx := []byte(key)
  50. testDummy(t, dummy, tx, key, value)
  51. value = "def"
  52. tx = []byte(key + "=" + value)
  53. testDummy(t, dummy, tx, key, value)
  54. }
  55. func TestPersistentDummyInfo(t *testing.T) {
  56. dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. dummy := NewPersistentDummyApplication(dir)
  61. height := uint64(0)
  62. resInfo := dummy.Info()
  63. if resInfo.LastBlockHeight != height {
  64. t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
  65. }
  66. // make and apply block
  67. height = uint64(1)
  68. hash := []byte("foo")
  69. header := &types.Header{
  70. Height: uint64(height),
  71. }
  72. dummy.BeginBlock(hash, header)
  73. dummy.EndBlock(height)
  74. dummy.Commit()
  75. resInfo = dummy.Info()
  76. if resInfo.LastBlockHeight != height {
  77. t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
  78. }
  79. }
  80. // add a validator, remove a validator, update a validator
  81. func TestValSetChanges(t *testing.T) {
  82. dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. dummy := NewPersistentDummyApplication(dir)
  87. // init with some validators
  88. total := 10
  89. nInit := 5
  90. vals := make([]*types.Validator, total)
  91. for i := 0; i < total; i++ {
  92. pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(Fmt("test%d", i))).PubKey().Bytes()
  93. power := RandInt()
  94. vals[i] = &types.Validator{pubkey, uint64(power)}
  95. }
  96. // iniitalize with the first nInit
  97. dummy.InitChain(vals[:nInit])
  98. vals1, vals2 := vals[:nInit], dummy.Validators()
  99. valsEqual(t, vals1, vals2)
  100. var v1, v2, v3 *types.Validator
  101. // add some validators
  102. v1, v2 = vals[nInit], vals[nInit+1]
  103. diff := []*types.Validator{v1, v2}
  104. tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
  105. tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
  106. makeApplyBlock(t, dummy, 1, diff, tx1, tx2)
  107. vals1, vals2 = vals[:nInit+2], dummy.Validators()
  108. valsEqual(t, vals1, vals2)
  109. // remove some validators
  110. v1, v2, v3 = vals[nInit-2], vals[nInit-1], vals[nInit]
  111. v1.Power = 0
  112. v2.Power = 0
  113. v3.Power = 0
  114. diff = []*types.Validator{v1, v2, v3}
  115. tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
  116. tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
  117. tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
  118. makeApplyBlock(t, dummy, 2, diff, tx1, tx2, tx3)
  119. vals1 = append(vals[:nInit-2], vals[nInit+1])
  120. vals2 = dummy.Validators()
  121. valsEqual(t, vals1, vals2)
  122. // update some validators
  123. v1 = vals[0]
  124. if v1.Power == 5 {
  125. v1.Power = 6
  126. } else {
  127. v1.Power = 5
  128. }
  129. diff = []*types.Validator{v1}
  130. tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
  131. makeApplyBlock(t, dummy, 3, diff, tx1)
  132. vals1 = append([]*types.Validator{v1}, vals1[1:len(vals1)]...)
  133. vals2 = dummy.Validators()
  134. valsEqual(t, vals1, vals2)
  135. }
  136. func makeApplyBlock(t *testing.T, dummy types.Application, heightInt int, diff []*types.Validator, txs ...[]byte) {
  137. // make and apply block
  138. height := uint64(heightInt)
  139. hash := []byte("foo")
  140. header := &types.Header{
  141. Height: height,
  142. }
  143. dummyChain := dummy.(types.BlockchainAware) // hmm...
  144. dummyChain.BeginBlock(hash, header)
  145. for _, tx := range txs {
  146. if r := dummy.DeliverTx(tx); r.IsErr() {
  147. t.Fatal(r)
  148. }
  149. }
  150. resEndBlock := dummyChain.EndBlock(height)
  151. dummy.Commit()
  152. valsEqual(t, diff, resEndBlock.Diffs)
  153. }
  154. // order doesn't matter
  155. func valsEqual(t *testing.T, vals1, vals2 []*types.Validator) {
  156. if len(vals1) != len(vals2) {
  157. t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
  158. }
  159. sort.Sort(types.Validators(vals1))
  160. sort.Sort(types.Validators(vals2))
  161. for i, v1 := range vals1 {
  162. v2 := vals2[i]
  163. if !bytes.Equal(v1.PubKey, v2.PubKey) ||
  164. v1.Power != v2.Power {
  165. t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
  166. }
  167. }
  168. }