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.

182 lines
4.7 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package consensus
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. // "sync"
  10. "testing"
  11. "time"
  12. "github.com/tendermint/tendermint/consensus/types"
  13. "github.com/tendermint/tendermint/libs/autofile"
  14. "github.com/tendermint/tendermint/libs/log"
  15. tmtypes "github.com/tendermint/tendermint/types"
  16. tmtime "github.com/tendermint/tendermint/types/time"
  17. "github.com/stretchr/testify/assert"
  18. "github.com/stretchr/testify/require"
  19. )
  20. func TestWALTruncate(t *testing.T) {
  21. walDir, err := ioutil.TempDir("", "wal")
  22. require.NoError(t, err)
  23. defer os.RemoveAll(walDir)
  24. walFile := filepath.Join(walDir, "wal")
  25. //this magic number 4K can truncate the content when RotateFile. defaultHeadSizeLimit(10M) is hard to simulate.
  26. //this magic number 1 * time.Millisecond make RotateFile check frequently. defaultGroupCheckDuration(5s) is hard to simulate.
  27. wal, err := NewWAL(walFile,
  28. autofile.GroupHeadSizeLimit(4096),
  29. autofile.GroupCheckDuration(1*time.Millisecond),
  30. )
  31. require.NoError(t, err)
  32. wal.SetLogger(log.TestingLogger())
  33. err = wal.Start()
  34. require.NoError(t, err)
  35. defer wal.Stop()
  36. //60 block's size nearly 70K, greater than group's headBuf size(4096 * 10), when headBuf is full, truncate content will Flush to the file.
  37. //at this time, RotateFile is called, truncate content exist in each file.
  38. err = WALGenerateNBlocks(wal.Group(), 60)
  39. require.NoError(t, err)
  40. time.Sleep(1 * time.Millisecond) //wait groupCheckDuration, make sure RotateFile run
  41. wal.Group().Flush()
  42. h := int64(50)
  43. gr, found, err := wal.SearchForEndHeight(h, &WALSearchOptions{})
  44. assert.NoError(t, err, fmt.Sprintf("expected not to err on height %d", h))
  45. assert.True(t, found, fmt.Sprintf("expected to find end height for %d", h))
  46. assert.NotNil(t, gr, "expected group not to be nil")
  47. defer gr.Close()
  48. dec := NewWALDecoder(gr)
  49. msg, err := dec.Decode()
  50. assert.NoError(t, err, "expected to decode a message")
  51. rs, ok := msg.Msg.(tmtypes.EventDataRoundState)
  52. assert.True(t, ok, "expected message of type EventDataRoundState")
  53. assert.Equal(t, rs.Height, h+1, fmt.Sprintf("wrong height"))
  54. }
  55. func TestWALEncoderDecoder(t *testing.T) {
  56. now := tmtime.Now()
  57. msgs := []TimedWALMessage{
  58. TimedWALMessage{Time: now, Msg: EndHeightMessage{0}},
  59. TimedWALMessage{Time: now, Msg: timeoutInfo{Duration: time.Second, Height: 1, Round: 1, Step: types.RoundStepPropose}},
  60. }
  61. b := new(bytes.Buffer)
  62. for _, msg := range msgs {
  63. b.Reset()
  64. enc := NewWALEncoder(b)
  65. err := enc.Encode(&msg)
  66. require.NoError(t, err)
  67. dec := NewWALDecoder(b)
  68. decoded, err := dec.Decode()
  69. require.NoError(t, err)
  70. assert.Equal(t, msg.Time.UTC(), decoded.Time)
  71. assert.Equal(t, msg.Msg, decoded.Msg)
  72. }
  73. }
  74. func TestWALSearchForEndHeight(t *testing.T) {
  75. walBody, err := WALWithNBlocks(6)
  76. if err != nil {
  77. t.Fatal(err)
  78. }
  79. walFile := tempWALWithData(walBody)
  80. wal, err := NewWAL(walFile)
  81. require.NoError(t, err)
  82. wal.SetLogger(log.TestingLogger())
  83. h := int64(3)
  84. gr, found, err := wal.SearchForEndHeight(h, &WALSearchOptions{})
  85. assert.NoError(t, err, fmt.Sprintf("expected not to err on height %d", h))
  86. assert.True(t, found, fmt.Sprintf("expected to find end height for %d", h))
  87. assert.NotNil(t, gr, "expected group not to be nil")
  88. defer gr.Close()
  89. dec := NewWALDecoder(gr)
  90. msg, err := dec.Decode()
  91. assert.NoError(t, err, "expected to decode a message")
  92. rs, ok := msg.Msg.(tmtypes.EventDataRoundState)
  93. assert.True(t, ok, "expected message of type EventDataRoundState")
  94. assert.Equal(t, rs.Height, h+1, fmt.Sprintf("wrong height"))
  95. }
  96. /*
  97. var initOnce sync.Once
  98. func registerInterfacesOnce() {
  99. initOnce.Do(func() {
  100. var _ = wire.RegisterInterface(
  101. struct{ WALMessage }{},
  102. wire.ConcreteType{[]byte{}, 0x10},
  103. )
  104. })
  105. }
  106. */
  107. func nBytes(n int) []byte {
  108. buf := make([]byte, n)
  109. n, _ = rand.Read(buf)
  110. return buf[:n]
  111. }
  112. func benchmarkWalDecode(b *testing.B, n int) {
  113. // registerInterfacesOnce()
  114. buf := new(bytes.Buffer)
  115. enc := NewWALEncoder(buf)
  116. data := nBytes(n)
  117. enc.Encode(&TimedWALMessage{Msg: data, Time: time.Now().Round(time.Second).UTC()})
  118. encoded := buf.Bytes()
  119. b.ResetTimer()
  120. for i := 0; i < b.N; i++ {
  121. buf.Reset()
  122. buf.Write(encoded)
  123. dec := NewWALDecoder(buf)
  124. if _, err := dec.Decode(); err != nil {
  125. b.Fatal(err)
  126. }
  127. }
  128. b.ReportAllocs()
  129. }
  130. func BenchmarkWalDecode512B(b *testing.B) {
  131. benchmarkWalDecode(b, 512)
  132. }
  133. func BenchmarkWalDecode10KB(b *testing.B) {
  134. benchmarkWalDecode(b, 10*1024)
  135. }
  136. func BenchmarkWalDecode100KB(b *testing.B) {
  137. benchmarkWalDecode(b, 100*1024)
  138. }
  139. func BenchmarkWalDecode1MB(b *testing.B) {
  140. benchmarkWalDecode(b, 1024*1024)
  141. }
  142. func BenchmarkWalDecode10MB(b *testing.B) {
  143. benchmarkWalDecode(b, 10*1024*1024)
  144. }
  145. func BenchmarkWalDecode100MB(b *testing.B) {
  146. benchmarkWalDecode(b, 100*1024*1024)
  147. }
  148. func BenchmarkWalDecode1GB(b *testing.B) {
  149. benchmarkWalDecode(b, 1024*1024*1024)
  150. }