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.

296 lines
9.1 KiB

7 years ago
7 years ago
7 years ago
7 years ago
  1. package filer2
  2. import (
  3. "testing"
  4. "log"
  5. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  6. )
  7. func TestCompactFileChunks(t *testing.T) {
  8. chunks := []*filer_pb.FileChunk{
  9. {Offset: 10, Size: 100, FileId: "abc", Mtime: 50},
  10. {Offset: 100, Size: 100, FileId: "def", Mtime: 100},
  11. {Offset: 200, Size: 100, FileId: "ghi", Mtime: 200},
  12. {Offset: 110, Size: 200, FileId: "jkl", Mtime: 300},
  13. }
  14. compacted, garbarge := CompactFileChunks(chunks)
  15. log.Printf("Compacted: %+v", compacted)
  16. log.Printf("Garbage : %+v", garbarge)
  17. if len(compacted) != 3 {
  18. t.Fatalf("unexpected compacted: %d", len(compacted))
  19. }
  20. if len(garbarge) != 1 {
  21. t.Fatalf("unexpected garbarge: %d", len(garbarge))
  22. }
  23. }
  24. func TestIntervalMerging(t *testing.T) {
  25. testcases := []struct {
  26. Chunks []*filer_pb.FileChunk
  27. Expected []*visibleInterval
  28. }{
  29. // case 0: normal
  30. {
  31. Chunks: []*filer_pb.FileChunk{
  32. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  33. {Offset: 100, Size: 100, FileId: "asdf", Mtime: 134},
  34. {Offset: 200, Size: 100, FileId: "fsad", Mtime: 353},
  35. },
  36. Expected: []*visibleInterval{
  37. {start: 0, stop: 100, fileId: "abc"},
  38. {start: 100, stop: 200, fileId: "asdf"},
  39. {start: 200, stop: 300, fileId: "fsad"},
  40. },
  41. },
  42. // case 1: updates overwrite full chunks
  43. {
  44. Chunks: []*filer_pb.FileChunk{
  45. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  46. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 134},
  47. },
  48. Expected: []*visibleInterval{
  49. {start: 0, stop: 200, fileId: "asdf"},
  50. },
  51. },
  52. // case 2: updates overwrite part of previous chunks
  53. {
  54. Chunks: []*filer_pb.FileChunk{
  55. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  56. {Offset: 0, Size: 50, FileId: "asdf", Mtime: 134},
  57. },
  58. Expected: []*visibleInterval{
  59. {start: 0, stop: 50, fileId: "asdf"},
  60. {start: 50, stop: 100, fileId: "abc"},
  61. },
  62. },
  63. // case 3: updates overwrite full chunks
  64. {
  65. Chunks: []*filer_pb.FileChunk{
  66. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  67. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 134},
  68. {Offset: 50, Size: 250, FileId: "xxxx", Mtime: 154},
  69. },
  70. Expected: []*visibleInterval{
  71. {start: 0, stop: 50, fileId: "asdf"},
  72. {start: 50, stop: 300, fileId: "xxxx"},
  73. },
  74. },
  75. // case 4: updates far away from prev chunks
  76. {
  77. Chunks: []*filer_pb.FileChunk{
  78. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  79. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 134},
  80. {Offset: 250, Size: 250, FileId: "xxxx", Mtime: 154},
  81. },
  82. Expected: []*visibleInterval{
  83. {start: 0, stop: 200, fileId: "asdf"},
  84. {start: 250, stop: 500, fileId: "xxxx"},
  85. },
  86. },
  87. // case 5: updates overwrite full chunks
  88. {
  89. Chunks: []*filer_pb.FileChunk{
  90. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  91. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 184},
  92. {Offset: 70, Size: 150, FileId: "abc", Mtime: 143},
  93. {Offset: 80, Size: 100, FileId: "xxxx", Mtime: 134},
  94. },
  95. Expected: []*visibleInterval{
  96. {start: 0, stop: 200, fileId: "asdf"},
  97. {start: 200, stop: 220, fileId: "abc"},
  98. },
  99. },
  100. // case 6: same updates
  101. {
  102. Chunks: []*filer_pb.FileChunk{
  103. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  104. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  105. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  106. },
  107. Expected: []*visibleInterval{
  108. {start: 0, stop: 100, fileId: "abc"},
  109. },
  110. },
  111. }
  112. for i, testcase := range testcases {
  113. log.Printf("++++++++++ merged test case %d ++++++++++++++++++++", i)
  114. intervals := nonOverlappingVisibleIntervals(testcase.Chunks)
  115. for x, interval := range intervals {
  116. log.Printf("test case %d, interval %d, start=%d, stop=%d, fileId=%s",
  117. i, x, interval.start, interval.stop, interval.fileId)
  118. if interval.start != testcase.Expected[x].start {
  119. t.Fatalf("failed on test case %d, interval %d, start %d, expect %d",
  120. i, x, interval.start, testcase.Expected[x].start)
  121. }
  122. if interval.stop != testcase.Expected[x].stop {
  123. t.Fatalf("failed on test case %d, interval %d, stop %d, expect %d",
  124. i, x, interval.stop, testcase.Expected[x].stop)
  125. }
  126. if interval.fileId != testcase.Expected[x].fileId {
  127. t.Fatalf("failed on test case %d, interval %d, chunkId %s, expect %s",
  128. i, x, interval.fileId, testcase.Expected[x].fileId)
  129. }
  130. }
  131. if len(intervals) != len(testcase.Expected) {
  132. t.Fatalf("failed to compact test case %d, len %d expected %d", i, len(intervals), len(testcase.Expected))
  133. }
  134. }
  135. }
  136. func TestChunksReading(t *testing.T) {
  137. testcases := []struct {
  138. Chunks []*filer_pb.FileChunk
  139. Offset int64
  140. Size int
  141. Expected []*ChunkView
  142. }{
  143. // case 0: normal
  144. {
  145. Chunks: []*filer_pb.FileChunk{
  146. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  147. {Offset: 100, Size: 100, FileId: "asdf", Mtime: 134},
  148. {Offset: 200, Size: 100, FileId: "fsad", Mtime: 353},
  149. },
  150. Offset: 0,
  151. Size: 250,
  152. Expected: []*ChunkView{
  153. {Offset: 0, Size: 100, FileId: "abc", LogicOffset:0},
  154. {Offset: 0, Size: 100, FileId: "asdf", LogicOffset:100},
  155. {Offset: 0, Size: 50, FileId: "fsad", LogicOffset:200},
  156. },
  157. },
  158. // case 1: updates overwrite full chunks
  159. {
  160. Chunks: []*filer_pb.FileChunk{
  161. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  162. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 134},
  163. },
  164. Offset: 50,
  165. Size: 100,
  166. Expected: []*ChunkView{
  167. {Offset: 50, Size: 100, FileId: "asdf", LogicOffset:50},
  168. },
  169. },
  170. // case 2: updates overwrite part of previous chunks
  171. {
  172. Chunks: []*filer_pb.FileChunk{
  173. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  174. {Offset: 0, Size: 50, FileId: "asdf", Mtime: 134},
  175. },
  176. Offset: 25,
  177. Size: 50,
  178. Expected: []*ChunkView{
  179. {Offset: 25, Size: 25, FileId: "asdf", LogicOffset:25},
  180. {Offset: 0, Size: 25, FileId: "abc", LogicOffset:50},
  181. },
  182. },
  183. // case 3: updates overwrite full chunks
  184. {
  185. Chunks: []*filer_pb.FileChunk{
  186. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  187. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 134},
  188. {Offset: 50, Size: 250, FileId: "xxxx", Mtime: 154},
  189. },
  190. Offset: 0,
  191. Size: 200,
  192. Expected: []*ChunkView{
  193. {Offset: 0, Size: 50, FileId: "asdf", LogicOffset:0},
  194. {Offset: 0, Size: 150, FileId: "xxxx", LogicOffset:50},
  195. },
  196. },
  197. // case 4: updates far away from prev chunks
  198. {
  199. Chunks: []*filer_pb.FileChunk{
  200. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  201. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 134},
  202. {Offset: 250, Size: 250, FileId: "xxxx", Mtime: 154},
  203. },
  204. Offset: 0,
  205. Size: 400,
  206. Expected: []*ChunkView{
  207. {Offset: 0, Size: 200, FileId: "asdf", LogicOffset:0},
  208. // {Offset: 0, Size: 150, FileId: "xxxx"}, // missing intervals should not happen
  209. },
  210. },
  211. // case 5: updates overwrite full chunks
  212. {
  213. Chunks: []*filer_pb.FileChunk{
  214. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  215. {Offset: 0, Size: 200, FileId: "asdf", Mtime: 184},
  216. {Offset: 70, Size: 150, FileId: "abc", Mtime: 143},
  217. {Offset: 80, Size: 100, FileId: "xxxx", Mtime: 134},
  218. },
  219. Offset: 0,
  220. Size: 220,
  221. Expected: []*ChunkView{
  222. {Offset: 0, Size: 200, FileId: "asdf", LogicOffset:0},
  223. {Offset: 0, Size: 20, FileId: "abc", LogicOffset:200},
  224. },
  225. },
  226. // case 6: same updates
  227. {
  228. Chunks: []*filer_pb.FileChunk{
  229. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  230. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  231. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  232. },
  233. Offset: 0,
  234. Size: 100,
  235. Expected: []*ChunkView{
  236. {Offset: 0, Size: 100, FileId: "abc", LogicOffset:0},
  237. },
  238. },
  239. // case 7: edge cases
  240. {
  241. Chunks: []*filer_pb.FileChunk{
  242. {Offset: 0, Size: 100, FileId: "abc", Mtime: 123},
  243. {Offset: 100, Size: 100, FileId: "asdf", Mtime: 134},
  244. {Offset: 200, Size: 100, FileId: "fsad", Mtime: 353},
  245. },
  246. Offset: 0,
  247. Size: 200,
  248. Expected: []*ChunkView{
  249. {Offset: 0, Size: 100, FileId: "abc", LogicOffset:0},
  250. {Offset: 0, Size: 100, FileId: "asdf", LogicOffset:100},
  251. },
  252. },
  253. }
  254. for i, testcase := range testcases {
  255. log.Printf("++++++++++ read test case %d ++++++++++++++++++++", i)
  256. chunks := ReadFromChunks(testcase.Chunks, testcase.Offset, testcase.Size)
  257. for x, chunk := range chunks {
  258. log.Printf("read case %d, chunk %d, offset=%d, size=%d, fileId=%s",
  259. i, x, chunk.Offset, chunk.Size, chunk.FileId)
  260. if chunk.Offset != testcase.Expected[x].Offset {
  261. t.Fatalf("failed on read case %d, chunk %d, Offset %d, expect %d",
  262. i, x, chunk.Offset, testcase.Expected[x].Offset)
  263. }
  264. if chunk.Size != testcase.Expected[x].Size {
  265. t.Fatalf("failed on read case %d, chunk %d, Size %d, expect %d",
  266. i, x, chunk.Size, testcase.Expected[x].Size)
  267. }
  268. if chunk.FileId != testcase.Expected[x].FileId {
  269. t.Fatalf("failed on read case %d, chunk %d, FileId %s, expect %s",
  270. i, x, chunk.FileId, testcase.Expected[x].FileId)
  271. }
  272. if chunk.LogicOffset != testcase.Expected[x].LogicOffset {
  273. t.Fatalf("failed on read case %d, chunk %d, LogicOffset %d, expect %d",
  274. i, x, chunk.LogicOffset, testcase.Expected[x].LogicOffset)
  275. }
  276. }
  277. if len(chunks) != len(testcase.Expected) {
  278. t.Fatalf("failed to read test case %d, len %d expected %d", i, len(chunks), len(testcase.Expected))
  279. }
  280. }
  281. }