walk_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
  2. // All rights reserved. Use of this source code is governed by an MIT-style
  3. // license that can be found in the LICENSE file.
  4. package scanner
  5. import (
  6. "bytes"
  7. "fmt"
  8. "path/filepath"
  9. "reflect"
  10. rdebug "runtime/debug"
  11. "sort"
  12. "testing"
  13. "github.com/syncthing/syncthing/internal/ignore"
  14. "github.com/syncthing/syncthing/internal/protocol"
  15. )
  16. type testfile struct {
  17. name string
  18. size int
  19. hash string
  20. }
  21. type testfileList []testfile
  22. var testdata = testfileList{
  23. {"afile", 4, "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"},
  24. {"dir1", 128, ""},
  25. {filepath.Join("dir1", "dfile"), 5, "49ae93732fcf8d63fe1cce759664982dbd5b23161f007dba8561862adc96d063"},
  26. {"dir2", 128, ""},
  27. {filepath.Join("dir2", "cfile"), 4, "bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c"},
  28. {"excludes", 37, "df90b52f0c55dba7a7a940affe482571563b1ac57bd5be4d8a0291e7de928e06"},
  29. {"further-excludes", 5, "7eb0a548094fa6295f7fd9200d69973e5f5ec5c04f2a86d998080ac43ecf89f1"},
  30. }
  31. var correctIgnores = map[string][]string{
  32. ".": {".*", "quux"},
  33. }
  34. func init() {
  35. // This test runs the risk of entering infinite recursion if it fails.
  36. // Limit the stack size to 10 megs to creash early in that case instead of
  37. // potentially taking down the box...
  38. rdebug.SetMaxStack(10 * 1 << 20)
  39. }
  40. func TestWalkSub(t *testing.T) {
  41. ignores, err := ignore.Load("testdata/.stignore")
  42. if err != nil {
  43. t.Fatal(err)
  44. }
  45. w := Walker{
  46. Dir: "testdata",
  47. Sub: "dir2",
  48. BlockSize: 128 * 1024,
  49. Ignores: ignores,
  50. }
  51. fchan, err := w.Walk()
  52. var files []protocol.FileInfo
  53. for f := range fchan {
  54. files = append(files, f)
  55. }
  56. if err != nil {
  57. t.Fatal(err)
  58. }
  59. // The directory contains two files, where one is ignored from a higher
  60. // level. We should see only the directory and one of the files.
  61. if len(files) != 2 {
  62. t.Fatalf("Incorrect length %d != 2", len(files))
  63. }
  64. if files[0].Name != "dir2" {
  65. t.Errorf("Incorrect file %v != dir2", files[0])
  66. }
  67. if files[1].Name != filepath.Join("dir2", "cfile") {
  68. t.Errorf("Incorrect file %v != dir2/cfile", files[1])
  69. }
  70. }
  71. func TestWalk(t *testing.T) {
  72. ignores, err := ignore.Load("testdata/.stignore")
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. t.Log(ignores)
  77. w := Walker{
  78. Dir: "testdata",
  79. BlockSize: 128 * 1024,
  80. Ignores: ignores,
  81. }
  82. fchan, err := w.Walk()
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. var tmp []protocol.FileInfo
  87. for f := range fchan {
  88. tmp = append(tmp, f)
  89. }
  90. sort.Sort(fileList(tmp))
  91. files := fileList(tmp).testfiles()
  92. if !reflect.DeepEqual(files, testdata) {
  93. t.Errorf("Walk returned unexpected data\nExpected: %v\nActual: %v", testdata, files)
  94. }
  95. }
  96. func TestWalkError(t *testing.T) {
  97. w := Walker{
  98. Dir: "testdata-missing",
  99. BlockSize: 128 * 1024,
  100. }
  101. _, err := w.Walk()
  102. if err == nil {
  103. t.Error("no error from missing directory")
  104. }
  105. w = Walker{
  106. Dir: "testdata/bar",
  107. BlockSize: 128 * 1024,
  108. }
  109. _, err = w.Walk()
  110. if err == nil {
  111. t.Error("no error from non-directory")
  112. }
  113. }
  114. type fileList []protocol.FileInfo
  115. func (f fileList) Len() int {
  116. return len(f)
  117. }
  118. func (f fileList) Less(a, b int) bool {
  119. return f[a].Name < f[b].Name
  120. }
  121. func (f fileList) Swap(a, b int) {
  122. f[a], f[b] = f[b], f[a]
  123. }
  124. func (l fileList) testfiles() testfileList {
  125. testfiles := make(testfileList, len(l))
  126. for i, f := range l {
  127. if len(f.Blocks) > 1 {
  128. panic("simple test case stuff only supports a single block per file")
  129. }
  130. testfiles[i] = testfile{name: f.Name, size: int(f.Size())}
  131. if len(f.Blocks) == 1 {
  132. testfiles[i].hash = fmt.Sprintf("%x", f.Blocks[0].Hash)
  133. }
  134. }
  135. return testfiles
  136. }
  137. func (l testfileList) String() string {
  138. var b bytes.Buffer
  139. b.WriteString("{\n")
  140. for _, f := range l {
  141. fmt.Fprintf(&b, " %s (%d bytes): %s\n", f.name, f.size, f.hash)
  142. }
  143. b.WriteString("}")
  144. return b.String()
  145. }