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.

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