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.

238 lines
6.4 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package autofile
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "os"
  6. "testing"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. cmn "github.com/tendermint/tendermint/libs/common"
  10. )
  11. func createTestGroupWithHeadSizeLimit(t *testing.T, headSizeLimit int64) *Group {
  12. testID := cmn.RandStr(12)
  13. testDir := "_test_" + testID
  14. err := cmn.EnsureDir(testDir, 0700)
  15. require.NoError(t, err, "Error creating dir")
  16. headPath := testDir + "/myfile"
  17. g, err := OpenGroup(headPath, GroupHeadSizeLimit(headSizeLimit))
  18. require.NoError(t, err, "Error opening Group")
  19. require.NotEqual(t, nil, g, "Failed to create Group")
  20. return g
  21. }
  22. func destroyTestGroup(t *testing.T, g *Group) {
  23. g.Close()
  24. err := os.RemoveAll(g.Dir)
  25. require.NoError(t, err, "Error removing test Group directory")
  26. }
  27. func assertGroupInfo(t *testing.T, gInfo GroupInfo, minIndex, maxIndex int, totalSize, headSize int64) {
  28. assert.Equal(t, minIndex, gInfo.MinIndex)
  29. assert.Equal(t, maxIndex, gInfo.MaxIndex)
  30. assert.Equal(t, totalSize, gInfo.TotalSize)
  31. assert.Equal(t, headSize, gInfo.HeadSize)
  32. }
  33. func TestCheckHeadSizeLimit(t *testing.T) {
  34. g := createTestGroupWithHeadSizeLimit(t, 1000*1000)
  35. // At first, there are no files.
  36. assertGroupInfo(t, g.ReadGroupInfo(), 0, 0, 0, 0)
  37. // Write 1000 bytes 999 times.
  38. for i := 0; i < 999; i++ {
  39. err := g.WriteLine(cmn.RandStr(999))
  40. require.NoError(t, err, "Error appending to head")
  41. }
  42. g.FlushAndSync()
  43. assertGroupInfo(t, g.ReadGroupInfo(), 0, 0, 999000, 999000)
  44. // Even calling checkHeadSizeLimit manually won't rotate it.
  45. g.checkHeadSizeLimit()
  46. assertGroupInfo(t, g.ReadGroupInfo(), 0, 0, 999000, 999000)
  47. // Write 1000 more bytes.
  48. err := g.WriteLine(cmn.RandStr(999))
  49. require.NoError(t, err, "Error appending to head")
  50. g.FlushAndSync()
  51. // Calling checkHeadSizeLimit this time rolls it.
  52. g.checkHeadSizeLimit()
  53. assertGroupInfo(t, g.ReadGroupInfo(), 0, 1, 1000000, 0)
  54. // Write 1000 more bytes.
  55. err = g.WriteLine(cmn.RandStr(999))
  56. require.NoError(t, err, "Error appending to head")
  57. g.FlushAndSync()
  58. // Calling checkHeadSizeLimit does nothing.
  59. g.checkHeadSizeLimit()
  60. assertGroupInfo(t, g.ReadGroupInfo(), 0, 1, 1001000, 1000)
  61. // Write 1000 bytes 999 times.
  62. for i := 0; i < 999; i++ {
  63. err = g.WriteLine(cmn.RandStr(999))
  64. require.NoError(t, err, "Error appending to head")
  65. }
  66. g.FlushAndSync()
  67. assertGroupInfo(t, g.ReadGroupInfo(), 0, 1, 2000000, 1000000)
  68. // Calling checkHeadSizeLimit rolls it again.
  69. g.checkHeadSizeLimit()
  70. assertGroupInfo(t, g.ReadGroupInfo(), 0, 2, 2000000, 0)
  71. // Write 1000 more bytes.
  72. _, err = g.Head.Write([]byte(cmn.RandStr(999) + "\n"))
  73. require.NoError(t, err, "Error appending to head")
  74. g.FlushAndSync()
  75. assertGroupInfo(t, g.ReadGroupInfo(), 0, 2, 2001000, 1000)
  76. // Calling checkHeadSizeLimit does nothing.
  77. g.checkHeadSizeLimit()
  78. assertGroupInfo(t, g.ReadGroupInfo(), 0, 2, 2001000, 1000)
  79. // Cleanup
  80. destroyTestGroup(t, g)
  81. }
  82. func TestRotateFile(t *testing.T) {
  83. g := createTestGroupWithHeadSizeLimit(t, 0)
  84. g.WriteLine("Line 1")
  85. g.WriteLine("Line 2")
  86. g.WriteLine("Line 3")
  87. g.FlushAndSync()
  88. g.RotateFile()
  89. g.WriteLine("Line 4")
  90. g.WriteLine("Line 5")
  91. g.WriteLine("Line 6")
  92. g.FlushAndSync()
  93. // Read g.Head.Path+"000"
  94. body1, err := ioutil.ReadFile(g.Head.Path + ".000")
  95. assert.NoError(t, err, "Failed to read first rolled file")
  96. if string(body1) != "Line 1\nLine 2\nLine 3\n" {
  97. t.Errorf("Got unexpected contents: [%v]", string(body1))
  98. }
  99. // Read g.Head.Path
  100. body2, err := ioutil.ReadFile(g.Head.Path)
  101. assert.NoError(t, err, "Failed to read first rolled file")
  102. if string(body2) != "Line 4\nLine 5\nLine 6\n" {
  103. t.Errorf("Got unexpected contents: [%v]", string(body2))
  104. }
  105. // Cleanup
  106. destroyTestGroup(t, g)
  107. }
  108. func TestWrite(t *testing.T) {
  109. g := createTestGroupWithHeadSizeLimit(t, 0)
  110. written := []byte("Medusa")
  111. g.Write(written)
  112. g.FlushAndSync()
  113. read := make([]byte, len(written))
  114. gr, err := g.NewReader(0)
  115. require.NoError(t, err, "failed to create reader")
  116. _, err = gr.Read(read)
  117. assert.NoError(t, err, "failed to read data")
  118. assert.Equal(t, written, read)
  119. // Cleanup
  120. destroyTestGroup(t, g)
  121. }
  122. // test that Read reads the required amount of bytes from all the files in the
  123. // group and returns no error if n == size of the given slice.
  124. func TestGroupReaderRead(t *testing.T) {
  125. g := createTestGroupWithHeadSizeLimit(t, 0)
  126. professor := []byte("Professor Monster")
  127. g.Write(professor)
  128. g.FlushAndSync()
  129. g.RotateFile()
  130. frankenstein := []byte("Frankenstein's Monster")
  131. g.Write(frankenstein)
  132. g.FlushAndSync()
  133. totalWrittenLength := len(professor) + len(frankenstein)
  134. read := make([]byte, totalWrittenLength)
  135. gr, err := g.NewReader(0)
  136. require.NoError(t, err, "failed to create reader")
  137. n, err := gr.Read(read)
  138. assert.NoError(t, err, "failed to read data")
  139. assert.Equal(t, totalWrittenLength, n, "not enough bytes read")
  140. professorPlusFrankenstein := professor
  141. professorPlusFrankenstein = append(professorPlusFrankenstein, frankenstein...)
  142. assert.Equal(t, professorPlusFrankenstein, read)
  143. // Cleanup
  144. destroyTestGroup(t, g)
  145. }
  146. // test that Read returns an error if number of bytes read < size of
  147. // the given slice. Subsequent call should return 0, io.EOF.
  148. func TestGroupReaderRead2(t *testing.T) {
  149. g := createTestGroupWithHeadSizeLimit(t, 0)
  150. professor := []byte("Professor Monster")
  151. g.Write(professor)
  152. g.FlushAndSync()
  153. g.RotateFile()
  154. frankenstein := []byte("Frankenstein's Monster")
  155. frankensteinPart := []byte("Frankenstein")
  156. g.Write(frankensteinPart) // note writing only a part
  157. g.FlushAndSync()
  158. totalLength := len(professor) + len(frankenstein)
  159. read := make([]byte, totalLength)
  160. gr, err := g.NewReader(0)
  161. require.NoError(t, err, "failed to create reader")
  162. // 1) n < (size of the given slice), io.EOF
  163. n, err := gr.Read(read)
  164. assert.Equal(t, io.EOF, err)
  165. assert.Equal(t, len(professor)+len(frankensteinPart), n, "Read more/less bytes than it is in the group")
  166. // 2) 0, io.EOF
  167. n, err = gr.Read([]byte("0"))
  168. assert.Equal(t, io.EOF, err)
  169. assert.Equal(t, 0, n)
  170. // Cleanup
  171. destroyTestGroup(t, g)
  172. }
  173. func TestMinIndex(t *testing.T) {
  174. g := createTestGroupWithHeadSizeLimit(t, 0)
  175. assert.Zero(t, g.MinIndex(), "MinIndex should be zero at the beginning")
  176. // Cleanup
  177. destroyTestGroup(t, g)
  178. }
  179. func TestMaxIndex(t *testing.T) {
  180. g := createTestGroupWithHeadSizeLimit(t, 0)
  181. assert.Zero(t, g.MaxIndex(), "MaxIndex should be zero at the beginning")
  182. g.WriteLine("Line 1")
  183. g.FlushAndSync()
  184. g.RotateFile()
  185. assert.Equal(t, 1, g.MaxIndex(), "MaxIndex should point to the last file")
  186. // Cleanup
  187. destroyTestGroup(t, g)
  188. }