hsync_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* Filename convention for test data: "STV"
  2. S: size in bytes.
  3. T: 's' for single or 'd' for duplicates.
  4. V: version
  5. To help identifying files, we set the content to:
  6. - Only one line, no new line.
  7. - Duplicates contain 123...S.
  8. - Unique files contain VVVV... (times S).
  9. Manual tests for source:
  10. - Read errors.
  11. - Stat errors.
  12. Manual tests for target:
  13. - Read errors.
  14. - Stat errors.
  15. */
  16. package main
  17. import (
  18. "fmt"
  19. "testing"
  20. )
  21. func printEntries(entries map[partialHash]fileMatch) {
  22. hashformat := "%x"
  23. for k, v := range entries {
  24. if v.sourceID != nil {
  25. // `partialHash.hash` is not in hex in the main program, but for
  26. // convenience we store them in hex here.
  27. if v.sourceID.h == nil {
  28. hashformat = "%v"
  29. }
  30. if v.targetID != nil && v.targetID != &unsolvable {
  31. fmt.Printf("%vB %v("+hashformat+"): %v -> %v\n", k.size, k.pos, k.hash, v.targetID.path, v.sourceID.path)
  32. } else {
  33. fmt.Printf("%vB %v("+hashformat+"): %v\n", k.size, k.pos, k.hash, v.sourceID.path)
  34. }
  35. }
  36. }
  37. }
  38. func sameEntries(got, want map[partialHash]fileMatch) bool {
  39. count := 0
  40. for k, v := range got {
  41. if v.sourceID != nil {
  42. count++
  43. hash := fmt.Sprintf("%x", k.hash)
  44. w, ok := want[partialHash{size: k.size, pos: k.pos, hash: hash}]
  45. if !ok || v.sourceID.path != w.sourceID.path ||
  46. ((v.targetID == nil || v.targetID == &unsolvable) && w.targetID != nil) ||
  47. ((v.targetID != nil && v.targetID != &unsolvable) && w.targetID == nil) ||
  48. (w.targetID != nil && v.targetID.path != w.targetID.path) {
  49. return false
  50. }
  51. }
  52. }
  53. return !(count != len(want))
  54. }
  55. /* Test cases for source:
  56. - Empty files.
  57. - Different sizes.
  58. - Subfolders.
  59. - 2 singles of one size.
  60. - 2 duplicates of one size.
  61. - 3 duplicates of one size in different folders.
  62. - 2 singles and 3 duplicates of one size.
  63. Test cases for target:
  64. - Matching source duplicate.
  65. - Pre-existing conflict with other target file.
  66. - No identical file in source.
  67. - Only 1 match.
  68. - Conflict: Drop different fid and conflict.
  69. - Conflict: Drop fid, keep conflict.
  70. - Conflict: Drop conflict, keep fid.
  71. - Conflict: Drop identical fid and conflict.
  72. */
  73. func TestVisit(t *testing.T) {
  74. source := "./testdata/src"
  75. target := "./testdata/tgt"
  76. entries := make(map[partialHash]fileMatch)
  77. visitSource(source, entries)
  78. visitTarget(target, source, entries)
  79. // Remove in-place renames.
  80. for k, v := range entries {
  81. if v.targetID != nil && v.targetID.path == v.sourceID.path {
  82. delete(entries, k)
  83. }
  84. }
  85. want := map[partialHash]fileMatch{
  86. {size: 1}: {sourceID: &fileID{path: "1"}},
  87. {size: 4, pos: 1, hash: "b59c67bf196a4758191e42f76670ceba"}: {sourceID: &fileID{path: "4s1"}},
  88. {size: 4, pos: 1, hash: "934b535800b1cba8f96a5d72f72f1611"}: {sourceID: &fileID{path: "sub/4s2"}, targetID: &fileID{path: "folder/4d2"}},
  89. {size: 5, pos: 1, hash: "b0baee9d279d34fa1dfd71aadb908c3f"}: {sourceID: &fileID{path: "5s1"}},
  90. {size: 5, pos: 1, hash: "3d2172418ce305c7d16d4b05597c6a59"}: {sourceID: &fileID{path: "5s2"}},
  91. {size: 6, pos: 1, hash: "96e79218965eb72c92a549dd5a330112"}: {sourceID: &fileID{path: "6"}},
  92. }
  93. if !sameEntries(entries, want) {
  94. t.Errorf("Structure does not match.")
  95. fmt.Println("==> Got:")
  96. printEntries(entries)
  97. fmt.Println("==> Want:")
  98. printEntries(want)
  99. }
  100. }