testutils_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright (C) 2016 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package model
  7. import (
  8. "io/ioutil"
  9. "os"
  10. "testing"
  11. "time"
  12. "github.com/syncthing/syncthing/lib/config"
  13. "github.com/syncthing/syncthing/lib/db"
  14. "github.com/syncthing/syncthing/lib/db/backend"
  15. "github.com/syncthing/syncthing/lib/events"
  16. "github.com/syncthing/syncthing/lib/fs"
  17. "github.com/syncthing/syncthing/lib/protocol"
  18. "github.com/syncthing/syncthing/lib/rand"
  19. )
  20. var (
  21. myID, device1, device2 protocol.DeviceID
  22. defaultCfgWrapper config.Wrapper
  23. defaultFolderConfig config.FolderConfiguration
  24. defaultFs fs.Filesystem
  25. defaultCfg config.Configuration
  26. defaultAutoAcceptCfg config.Configuration
  27. )
  28. func init() {
  29. myID, _ = protocol.DeviceIDFromString("ZNWFSWE-RWRV2BD-45BLMCV-LTDE2UR-4LJDW6J-R5BPWEB-TXD27XJ-IZF5RA4")
  30. device1, _ = protocol.DeviceIDFromString("AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR")
  31. device2, _ = protocol.DeviceIDFromString("GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY")
  32. defaultFs = fs.NewFilesystem(fs.FilesystemTypeBasic, "testdata")
  33. defaultFolderConfig = testFolderConfig("testdata")
  34. defaultCfgWrapper = createTmpWrapper(config.New(myID))
  35. _, _ = defaultCfgWrapper.SetDevice(config.NewDeviceConfiguration(device1, "device1"))
  36. _, _ = defaultCfgWrapper.SetFolder(defaultFolderConfig)
  37. opts := defaultCfgWrapper.Options()
  38. opts.KeepTemporariesH = 1
  39. _, _ = defaultCfgWrapper.SetOptions(opts)
  40. defaultCfg = defaultCfgWrapper.RawCopy()
  41. defaultAutoAcceptCfg = config.Configuration{
  42. Devices: []config.DeviceConfiguration{
  43. {
  44. DeviceID: myID, // self
  45. },
  46. {
  47. DeviceID: device1,
  48. AutoAcceptFolders: true,
  49. },
  50. {
  51. DeviceID: device2,
  52. AutoAcceptFolders: true,
  53. },
  54. },
  55. Options: config.OptionsConfiguration{
  56. DefaultFolderPath: ".",
  57. },
  58. }
  59. }
  60. func tmpDefaultWrapper() (config.Wrapper, config.FolderConfiguration) {
  61. w := createTmpWrapper(defaultCfgWrapper.RawCopy())
  62. fcfg := testFolderConfigTmp()
  63. _, _ = w.SetFolder(fcfg)
  64. return w, fcfg
  65. }
  66. func testFolderConfigTmp() config.FolderConfiguration {
  67. tmpDir := createTmpDir()
  68. return testFolderConfig(tmpDir)
  69. }
  70. func testFolderConfig(path string) config.FolderConfiguration {
  71. cfg := config.NewFolderConfiguration(myID, "default", "default", fs.FilesystemTypeBasic, path)
  72. cfg.FSWatcherEnabled = false
  73. cfg.Devices = append(cfg.Devices, config.FolderDeviceConfiguration{DeviceID: device1})
  74. return cfg
  75. }
  76. func testFolderConfigFake() config.FolderConfiguration {
  77. cfg := config.NewFolderConfiguration(myID, "default", "default", fs.FilesystemTypeFake, rand.String(32)+"?content=true")
  78. cfg.FSWatcherEnabled = false
  79. cfg.Devices = append(cfg.Devices, config.FolderDeviceConfiguration{DeviceID: device1})
  80. return cfg
  81. }
  82. func setupModelWithConnection() (*model, *fakeConnection, config.FolderConfiguration) {
  83. w, fcfg := tmpDefaultWrapper()
  84. m, fc := setupModelWithConnectionFromWrapper(w)
  85. return m, fc, fcfg
  86. }
  87. func setupModelWithConnectionFromWrapper(w config.Wrapper) (*model, *fakeConnection) {
  88. m := setupModel(w)
  89. fc := addFakeConn(m, device1)
  90. fc.folder = "default"
  91. _ = m.ScanFolder("default")
  92. return m, fc
  93. }
  94. func setupModel(w config.Wrapper) *model {
  95. db := db.NewLowlevel(backend.OpenMemory())
  96. m := newModel(w, myID, "syncthing", "dev", db, nil)
  97. m.ServeBackground()
  98. m.ScanFolders()
  99. return m
  100. }
  101. func newModel(cfg config.Wrapper, id protocol.DeviceID, clientName, clientVersion string, ldb *db.Lowlevel, protectedFiles []string) *model {
  102. evLogger := events.NewLogger()
  103. m := NewModel(cfg, id, clientName, clientVersion, ldb, protectedFiles, evLogger).(*model)
  104. go evLogger.Serve()
  105. return m
  106. }
  107. func cleanupModel(m *model) {
  108. m.Stop()
  109. m.db.Close()
  110. m.evLogger.Stop()
  111. os.Remove(m.cfg.ConfigPath())
  112. }
  113. func cleanupModelAndRemoveDir(m *model, dir string) {
  114. cleanupModel(m)
  115. os.RemoveAll(dir)
  116. }
  117. func createTmpDir() string {
  118. tmpDir, err := ioutil.TempDir("", "syncthing_testFolder-")
  119. if err != nil {
  120. panic("Failed to create temporary testing dir")
  121. }
  122. return tmpDir
  123. }
  124. type alwaysChangedKey struct {
  125. fs fs.Filesystem
  126. name string
  127. }
  128. // alwaysChanges is an ignore.ChangeDetector that always returns true on Changed()
  129. type alwaysChanged struct {
  130. seen map[alwaysChangedKey]struct{}
  131. }
  132. func newAlwaysChanged() *alwaysChanged {
  133. return &alwaysChanged{
  134. seen: make(map[alwaysChangedKey]struct{}),
  135. }
  136. }
  137. func (c *alwaysChanged) Remember(fs fs.Filesystem, name string, _ time.Time) {
  138. c.seen[alwaysChangedKey{fs, name}] = struct{}{}
  139. }
  140. func (c *alwaysChanged) Reset() {
  141. c.seen = make(map[alwaysChangedKey]struct{})
  142. }
  143. func (c *alwaysChanged) Seen(fs fs.Filesystem, name string) bool {
  144. _, ok := c.seen[alwaysChangedKey{fs, name}]
  145. return ok
  146. }
  147. func (c *alwaysChanged) Changed() bool {
  148. return true
  149. }
  150. func localSize(t *testing.T, m Model, folder string) db.Counts {
  151. t.Helper()
  152. snap := dbSnapshot(t, m, folder)
  153. defer snap.Release()
  154. return snap.LocalSize()
  155. }
  156. func globalSize(t *testing.T, m Model, folder string) db.Counts {
  157. t.Helper()
  158. snap := dbSnapshot(t, m, folder)
  159. defer snap.Release()
  160. return snap.GlobalSize()
  161. }
  162. func receiveOnlyChangedSize(t *testing.T, m Model, folder string) db.Counts {
  163. t.Helper()
  164. snap := dbSnapshot(t, m, folder)
  165. defer snap.Release()
  166. return snap.ReceiveOnlyChangedSize()
  167. }
  168. func needSize(t *testing.T, m Model, folder string) db.Counts {
  169. t.Helper()
  170. snap := dbSnapshot(t, m, folder)
  171. defer snap.Release()
  172. return snap.NeedSize()
  173. }
  174. func dbSnapshot(t *testing.T, m Model, folder string) *db.Snapshot {
  175. t.Helper()
  176. snap, err := m.DBSnapshot(folder)
  177. if err != nil {
  178. t.Fatal(err)
  179. }
  180. return snap
  181. }