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.

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