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.

363 lines
9.4 KiB

lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
7 years ago
7 years ago
7 years ago
8 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
  1. package kvstore
  2. import (
  3. "context"
  4. "fmt"
  5. "sort"
  6. "testing"
  7. "github.com/stretchr/testify/require"
  8. "github.com/tendermint/tendermint/libs/log"
  9. "github.com/tendermint/tendermint/libs/service"
  10. abciclient "github.com/tendermint/tendermint/abci/client"
  11. "github.com/tendermint/tendermint/abci/example/code"
  12. abciserver "github.com/tendermint/tendermint/abci/server"
  13. "github.com/tendermint/tendermint/abci/types"
  14. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  15. )
  16. const (
  17. testKey = "abc"
  18. testValue = "def"
  19. )
  20. func testKVStore(t *testing.T, app types.Application, tx []byte, key, value string) {
  21. req := types.RequestFinalizeBlock{Txs: [][]byte{tx}}
  22. ar := app.FinalizeBlock(req)
  23. require.Equal(t, 1, len(ar.Txs))
  24. require.False(t, ar.Txs[0].IsErr())
  25. // repeating tx doesn't raise error
  26. ar = app.FinalizeBlock(req)
  27. require.Equal(t, 1, len(ar.Txs))
  28. require.False(t, ar.Txs[0].IsErr())
  29. // commit
  30. app.Commit()
  31. info := app.Info(types.RequestInfo{})
  32. require.NotZero(t, info.LastBlockHeight)
  33. // make sure query is fine
  34. resQuery := app.Query(types.RequestQuery{
  35. Path: "/store",
  36. Data: []byte(key),
  37. })
  38. require.Equal(t, code.CodeTypeOK, resQuery.Code)
  39. require.Equal(t, key, string(resQuery.Key))
  40. require.Equal(t, value, string(resQuery.Value))
  41. require.EqualValues(t, info.LastBlockHeight, resQuery.Height)
  42. // make sure proof is fine
  43. resQuery = app.Query(types.RequestQuery{
  44. Path: "/store",
  45. Data: []byte(key),
  46. Prove: true,
  47. })
  48. require.EqualValues(t, code.CodeTypeOK, resQuery.Code)
  49. require.Equal(t, key, string(resQuery.Key))
  50. require.Equal(t, value, string(resQuery.Value))
  51. require.EqualValues(t, info.LastBlockHeight, resQuery.Height)
  52. }
  53. func TestKVStoreKV(t *testing.T) {
  54. kvstore := NewApplication()
  55. key := testKey
  56. value := key
  57. tx := []byte(key)
  58. testKVStore(t, kvstore, tx, key, value)
  59. value = testValue
  60. tx = []byte(key + "=" + value)
  61. testKVStore(t, kvstore, tx, key, value)
  62. }
  63. func TestPersistentKVStoreKV(t *testing.T) {
  64. dir := t.TempDir()
  65. logger := log.NewTestingLogger(t)
  66. kvstore := NewPersistentKVStoreApplication(logger, dir)
  67. key := testKey
  68. value := key
  69. tx := []byte(key)
  70. testKVStore(t, kvstore, tx, key, value)
  71. value = testValue
  72. tx = []byte(key + "=" + value)
  73. testKVStore(t, kvstore, tx, key, value)
  74. }
  75. func TestPersistentKVStoreInfo(t *testing.T) {
  76. dir := t.TempDir()
  77. logger := log.NewTestingLogger(t)
  78. kvstore := NewPersistentKVStoreApplication(logger, dir)
  79. InitKVStore(kvstore)
  80. height := int64(0)
  81. resInfo := kvstore.Info(types.RequestInfo{})
  82. if resInfo.LastBlockHeight != height {
  83. t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
  84. }
  85. // make and apply block
  86. height = int64(1)
  87. hash := []byte("foo")
  88. header := tmproto.Header{
  89. Height: height,
  90. }
  91. kvstore.FinalizeBlock(types.RequestFinalizeBlock{Hash: hash, Header: header, Height: height})
  92. kvstore.Commit()
  93. resInfo = kvstore.Info(types.RequestInfo{})
  94. if resInfo.LastBlockHeight != height {
  95. t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
  96. }
  97. }
  98. // add a validator, remove a validator, update a validator
  99. func TestValUpdates(t *testing.T) {
  100. dir := t.TempDir()
  101. logger := log.NewTestingLogger(t)
  102. kvstore := NewPersistentKVStoreApplication(logger, dir)
  103. // init with some validators
  104. total := 10
  105. nInit := 5
  106. vals := RandVals(total)
  107. // initialize with the first nInit
  108. kvstore.InitChain(types.RequestInitChain{
  109. Validators: vals[:nInit],
  110. })
  111. vals1, vals2 := vals[:nInit], kvstore.Validators()
  112. valsEqual(t, vals1, vals2)
  113. var v1, v2, v3 types.ValidatorUpdate
  114. // add some validators
  115. v1, v2 = vals[nInit], vals[nInit+1]
  116. diff := []types.ValidatorUpdate{v1, v2}
  117. tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
  118. tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
  119. makeApplyBlock(t, kvstore, 1, diff, tx1, tx2)
  120. vals1, vals2 = vals[:nInit+2], kvstore.Validators()
  121. valsEqual(t, vals1, vals2)
  122. // remove some validators
  123. v1, v2, v3 = vals[nInit-2], vals[nInit-1], vals[nInit]
  124. v1.Power = 0
  125. v2.Power = 0
  126. v3.Power = 0
  127. diff = []types.ValidatorUpdate{v1, v2, v3}
  128. tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
  129. tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
  130. tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
  131. makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3)
  132. vals1 = append(vals[:nInit-2], vals[nInit+1]) // nolint: gocritic
  133. vals2 = kvstore.Validators()
  134. valsEqual(t, vals1, vals2)
  135. // update some validators
  136. v1 = vals[0]
  137. if v1.Power == 5 {
  138. v1.Power = 6
  139. } else {
  140. v1.Power = 5
  141. }
  142. diff = []types.ValidatorUpdate{v1}
  143. tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
  144. makeApplyBlock(t, kvstore, 3, diff, tx1)
  145. vals1 = append([]types.ValidatorUpdate{v1}, vals1[1:]...)
  146. vals2 = kvstore.Validators()
  147. valsEqual(t, vals1, vals2)
  148. }
  149. func makeApplyBlock(
  150. t *testing.T,
  151. kvstore types.Application,
  152. heightInt int,
  153. diff []types.ValidatorUpdate,
  154. txs ...[]byte) {
  155. // make and apply block
  156. height := int64(heightInt)
  157. hash := []byte("foo")
  158. header := tmproto.Header{
  159. Height: height,
  160. }
  161. resFinalizeBlock := kvstore.FinalizeBlock(types.RequestFinalizeBlock{
  162. Hash: hash,
  163. Header: header,
  164. Height: height,
  165. Txs: txs,
  166. })
  167. kvstore.Commit()
  168. valsEqual(t, diff, resFinalizeBlock.ValidatorUpdates)
  169. }
  170. // order doesn't matter
  171. func valsEqual(t *testing.T, vals1, vals2 []types.ValidatorUpdate) {
  172. if len(vals1) != len(vals2) {
  173. t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
  174. }
  175. sort.Sort(types.ValidatorUpdates(vals1))
  176. sort.Sort(types.ValidatorUpdates(vals2))
  177. for i, v1 := range vals1 {
  178. v2 := vals2[i]
  179. if !v1.PubKey.Equal(v2.PubKey) ||
  180. v1.Power != v2.Power {
  181. t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
  182. }
  183. }
  184. }
  185. func makeSocketClientServer(
  186. ctx context.Context,
  187. t *testing.T,
  188. logger log.Logger,
  189. app types.Application,
  190. name string,
  191. ) (abciclient.Client, service.Service, error) {
  192. ctx, cancel := context.WithCancel(ctx)
  193. t.Cleanup(cancel)
  194. // Start the listener
  195. socket := fmt.Sprintf("unix://%s.sock", name)
  196. server := abciserver.NewSocketServer(logger.With("module", "abci-server"), socket, app)
  197. if err := server.Start(ctx); err != nil {
  198. cancel()
  199. return nil, nil, err
  200. }
  201. // Connect to the socket
  202. client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false)
  203. if err := client.Start(ctx); err != nil {
  204. cancel()
  205. return nil, nil, err
  206. }
  207. return client, server, nil
  208. }
  209. func makeGRPCClientServer(
  210. ctx context.Context,
  211. t *testing.T,
  212. logger log.Logger,
  213. app types.Application,
  214. name string,
  215. ) (abciclient.Client, service.Service, error) {
  216. ctx, cancel := context.WithCancel(ctx)
  217. t.Cleanup(cancel)
  218. // Start the listener
  219. socket := fmt.Sprintf("unix://%s.sock", name)
  220. gapp := types.NewGRPCApplication(app)
  221. server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, gapp)
  222. if err := server.Start(ctx); err != nil {
  223. cancel()
  224. return nil, nil, err
  225. }
  226. client := abciclient.NewGRPCClient(logger.With("module", "abci-client"), socket, true)
  227. if err := client.Start(ctx); err != nil {
  228. cancel()
  229. return nil, nil, err
  230. }
  231. return client, server, nil
  232. }
  233. func TestClientServer(t *testing.T) {
  234. ctx, cancel := context.WithCancel(context.Background())
  235. defer cancel()
  236. logger := log.NewTestingLogger(t)
  237. // set up socket app
  238. kvstore := NewApplication()
  239. client, server, err := makeSocketClientServer(ctx, t, logger, kvstore, "kvstore-socket")
  240. require.NoError(t, err)
  241. t.Cleanup(func() { cancel(); server.Wait() })
  242. t.Cleanup(func() { cancel(); client.Wait() })
  243. runClientTests(ctx, t, client)
  244. // set up grpc app
  245. kvstore = NewApplication()
  246. gclient, gserver, err := makeGRPCClientServer(ctx, t, logger, kvstore, "/tmp/kvstore-grpc")
  247. require.NoError(t, err)
  248. t.Cleanup(func() { cancel(); gserver.Wait() })
  249. t.Cleanup(func() { cancel(); gclient.Wait() })
  250. runClientTests(ctx, t, gclient)
  251. }
  252. func runClientTests(ctx context.Context, t *testing.T, client abciclient.Client) {
  253. // run some tests....
  254. key := testKey
  255. value := key
  256. tx := []byte(key)
  257. testClient(ctx, t, client, tx, key, value)
  258. value = testValue
  259. tx = []byte(key + "=" + value)
  260. testClient(ctx, t, client, tx, key, value)
  261. }
  262. func testClient(ctx context.Context, t *testing.T, app abciclient.Client, tx []byte, key, value string) {
  263. ar, err := app.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: [][]byte{tx}})
  264. require.NoError(t, err)
  265. require.Equal(t, 1, len(ar.Txs))
  266. require.False(t, ar.Txs[0].IsErr())
  267. // repeating FinalizeBlock doesn't raise error
  268. ar, err = app.FinalizeBlock(ctx, types.RequestFinalizeBlock{Txs: [][]byte{tx}})
  269. require.NoError(t, err)
  270. require.Equal(t, 1, len(ar.Txs))
  271. require.False(t, ar.Txs[0].IsErr())
  272. // commit
  273. _, err = app.Commit(ctx)
  274. require.NoError(t, err)
  275. info, err := app.Info(ctx, types.RequestInfo{})
  276. require.NoError(t, err)
  277. require.NotZero(t, info.LastBlockHeight)
  278. // make sure query is fine
  279. resQuery, err := app.Query(ctx, types.RequestQuery{
  280. Path: "/store",
  281. Data: []byte(key),
  282. })
  283. require.NoError(t, err)
  284. require.Equal(t, code.CodeTypeOK, resQuery.Code)
  285. require.Equal(t, key, string(resQuery.Key))
  286. require.Equal(t, value, string(resQuery.Value))
  287. require.EqualValues(t, info.LastBlockHeight, resQuery.Height)
  288. // make sure proof is fine
  289. resQuery, err = app.Query(ctx, types.RequestQuery{
  290. Path: "/store",
  291. Data: []byte(key),
  292. Prove: true,
  293. })
  294. require.NoError(t, err)
  295. require.Equal(t, code.CodeTypeOK, resQuery.Code)
  296. require.Equal(t, key, string(resQuery.Key))
  297. require.Equal(t, value, string(resQuery.Value))
  298. require.EqualValues(t, info.LastBlockHeight, resQuery.Height)
  299. }