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.

184 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. tmtypes "github.com/tendermint/tendermint/types"
  15. tmtime "github.com/tendermint/tendermint/types/time"
  16. "github.com/stretchr/testify/assert"
  17. "github.com/stretchr/testify/require"
  18. )
  19. func TestWALTruncate(t *testing.T) {
  20. walDir, err := ioutil.TempDir("", "wal")
  21. if err != nil {
  22. panic(fmt.Errorf("failed to create temp WAL file: %v", err))
  23. }
  24. defer os.RemoveAll(walDir)
  25. walFile := filepath.Join(walDir, "wal")
  26. //this magic number 4K can truncate the content when RotateFile. defaultHeadSizeLimit(10M) is hard to simulate.
  27. //this magic number 1 * time.Millisecond make RotateFile check frequently. defaultGroupCheckDuration(5s) is hard to simulate.
  28. wal, err := NewWAL(walFile, autofile.GroupHeadSizeLimit(4096), autofile.GroupCheckDuration(1*time.Millisecond))
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. wal.Start()
  33. defer wal.Stop()
  34. //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.
  35. //at this time, RotateFile is called, truncate content exist in each file.
  36. err = WALGenerateNBlocks(wal.Group(), 60)
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  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. if err != nil {
  82. t.Fatal(err)
  83. }
  84. h := int64(3)
  85. gr, found, err := wal.SearchForEndHeight(h, &WALSearchOptions{})
  86. assert.NoError(t, err, fmt.Sprintf("expected not to err on height %d", h))
  87. assert.True(t, found, fmt.Sprintf("expected to find end height for %d", h))
  88. assert.NotNil(t, gr, "expected group not to be nil")
  89. defer gr.Close()
  90. dec := NewWALDecoder(gr)
  91. msg, err := dec.Decode()
  92. assert.NoError(t, err, "expected to decode a message")
  93. rs, ok := msg.Msg.(tmtypes.EventDataRoundState)
  94. assert.True(t, ok, "expected message of type EventDataRoundState")
  95. assert.Equal(t, rs.Height, h+1, fmt.Sprintf("wrong height"))
  96. }
  97. /*
  98. var initOnce sync.Once
  99. func registerInterfacesOnce() {
  100. initOnce.Do(func() {
  101. var _ = wire.RegisterInterface(
  102. struct{ WALMessage }{},
  103. wire.ConcreteType{[]byte{}, 0x10},
  104. )
  105. })
  106. }
  107. */
  108. func nBytes(n int) []byte {
  109. buf := make([]byte, n)
  110. n, _ = rand.Read(buf)
  111. return buf[:n]
  112. }
  113. func benchmarkWalDecode(b *testing.B, n int) {
  114. // registerInterfacesOnce()
  115. buf := new(bytes.Buffer)
  116. enc := NewWALEncoder(buf)
  117. data := nBytes(n)
  118. enc.Encode(&TimedWALMessage{Msg: data, Time: time.Now().Round(time.Second).UTC()})
  119. encoded := buf.Bytes()
  120. b.ResetTimer()
  121. for i := 0; i < b.N; i++ {
  122. buf.Reset()
  123. buf.Write(encoded)
  124. dec := NewWALDecoder(buf)
  125. if _, err := dec.Decode(); err != nil {
  126. b.Fatal(err)
  127. }
  128. }
  129. b.ReportAllocs()
  130. }
  131. func BenchmarkWalDecode512B(b *testing.B) {
  132. benchmarkWalDecode(b, 512)
  133. }
  134. func BenchmarkWalDecode10KB(b *testing.B) {
  135. benchmarkWalDecode(b, 10*1024)
  136. }
  137. func BenchmarkWalDecode100KB(b *testing.B) {
  138. benchmarkWalDecode(b, 100*1024)
  139. }
  140. func BenchmarkWalDecode1MB(b *testing.B) {
  141. benchmarkWalDecode(b, 1024*1024)
  142. }
  143. func BenchmarkWalDecode10MB(b *testing.B) {
  144. benchmarkWalDecode(b, 10*1024*1024)
  145. }
  146. func BenchmarkWalDecode100MB(b *testing.B) {
  147. benchmarkWalDecode(b, 100*1024*1024)
  148. }
  149. func BenchmarkWalDecode1GB(b *testing.B) {
  150. benchmarkWalDecode(b, 1024*1024*1024)
  151. }