config_test.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
  2. // Use of this source code is governed by an MIT-style license that can be
  3. // found in the LICENSE file.
  4. package config
  5. import (
  6. "bytes"
  7. "io"
  8. "os"
  9. "reflect"
  10. "testing"
  11. "github.com/calmh/syncthing/files"
  12. "github.com/calmh/syncthing/scanner"
  13. )
  14. func TestDefaultValues(t *testing.T) {
  15. expected := OptionsConfiguration{
  16. ListenAddress: []string{"0.0.0.0:22000"},
  17. GlobalAnnServer: "announce.syncthing.net:22025",
  18. GlobalAnnEnabled: true,
  19. LocalAnnEnabled: true,
  20. LocalAnnPort: 21025,
  21. ParallelRequests: 16,
  22. MaxSendKbps: 0,
  23. RescanIntervalS: 60,
  24. ReconnectIntervalS: 60,
  25. MaxChangeKbps: 10000,
  26. StartBrowser: true,
  27. UPnPEnabled: true,
  28. }
  29. cfg, err := Load(bytes.NewReader(nil), "nodeID")
  30. if err != io.EOF {
  31. t.Error(err)
  32. }
  33. if !reflect.DeepEqual(cfg.Options, expected) {
  34. t.Errorf("Default config differs;\n E: %#v\n A: %#v", expected, cfg.Options)
  35. }
  36. }
  37. func TestNodeConfig(t *testing.T) {
  38. v1data := []byte(`
  39. <configuration version="1">
  40. <repository id="test" directory="~/Sync">
  41. <node id="NODE1" name="node one">
  42. <address>a</address>
  43. </node>
  44. <node id="NODE2" name="node two">
  45. <address>b</address>
  46. </node>
  47. </repository>
  48. <options>
  49. <readOnly>true</readOnly>
  50. </options>
  51. </configuration>
  52. `)
  53. v2data := []byte(`
  54. <configuration version="2">
  55. <repository id="test" directory="~/Sync" ro="true">
  56. <node id="NODE1"/>
  57. <node id="NODE2"/>
  58. </repository>
  59. <node id="NODE1" name="node one">
  60. <address>a</address>
  61. </node>
  62. <node id="NODE2" name="node two">
  63. <address>b</address>
  64. </node>
  65. </configuration>
  66. `)
  67. for i, data := range [][]byte{v1data, v2data} {
  68. cfg, err := Load(bytes.NewReader(data), "NODE1")
  69. if err != nil {
  70. t.Error(err)
  71. }
  72. expectedRepos := []RepositoryConfiguration{
  73. {
  74. ID: "test",
  75. Directory: "~/Sync",
  76. Nodes: []NodeConfiguration{{NodeID: "NODE1"}, {NodeID: "NODE2"}},
  77. ReadOnly: true,
  78. },
  79. }
  80. expectedNodes := []NodeConfiguration{
  81. {
  82. NodeID: "NODE1",
  83. Name: "node one",
  84. Addresses: []string{"a"},
  85. },
  86. {
  87. NodeID: "NODE2",
  88. Name: "node two",
  89. Addresses: []string{"b"},
  90. },
  91. }
  92. expectedNodeIDs := []string{"NODE1", "NODE2"}
  93. if cfg.Version != 2 {
  94. t.Errorf("%d: Incorrect version %d != 2", i, cfg.Version)
  95. }
  96. if !reflect.DeepEqual(cfg.Repositories, expectedRepos) {
  97. t.Errorf("%d: Incorrect Repositories\n A: %#v\n E: %#v", i, cfg.Repositories, expectedRepos)
  98. }
  99. if !reflect.DeepEqual(cfg.Nodes, expectedNodes) {
  100. t.Errorf("%d: Incorrect Nodes\n A: %#v\n E: %#v", i, cfg.Nodes, expectedNodes)
  101. }
  102. if !reflect.DeepEqual(cfg.Repositories[0].NodeIDs(), expectedNodeIDs) {
  103. t.Errorf("%d: Incorrect NodeIDs\n A: %#v\n E: %#v", i, cfg.Repositories[0].NodeIDs(), expectedNodeIDs)
  104. }
  105. }
  106. }
  107. func TestNoListenAddress(t *testing.T) {
  108. data := []byte(`<configuration version="1">
  109. <repository directory="~/Sync">
  110. <node id="..." name="...">
  111. <address>dynamic</address>
  112. </node>
  113. </repository>
  114. <options>
  115. <listenAddress></listenAddress>
  116. </options>
  117. </configuration>
  118. `)
  119. cfg, err := Load(bytes.NewReader(data), "nodeID")
  120. if err != nil {
  121. t.Error(err)
  122. }
  123. expected := []string{""}
  124. if !reflect.DeepEqual(cfg.Options.ListenAddress, expected) {
  125. t.Errorf("Unexpected ListenAddress %#v", cfg.Options.ListenAddress)
  126. }
  127. }
  128. func TestOverriddenValues(t *testing.T) {
  129. data := []byte(`<configuration version="2">
  130. <repository directory="~/Sync">
  131. <node id="..." name="...">
  132. <address>dynamic</address>
  133. </node>
  134. </repository>
  135. <options>
  136. <listenAddress>:23000</listenAddress>
  137. <allowDelete>false</allowDelete>
  138. <globalAnnounceServer>syncthing.nym.se:22025</globalAnnounceServer>
  139. <globalAnnounceEnabled>false</globalAnnounceEnabled>
  140. <localAnnounceEnabled>false</localAnnounceEnabled>
  141. <localAnnouncePort>42123</localAnnouncePort>
  142. <parallelRequests>32</parallelRequests>
  143. <maxSendKbps>1234</maxSendKbps>
  144. <rescanIntervalS>600</rescanIntervalS>
  145. <reconnectionIntervalS>6000</reconnectionIntervalS>
  146. <maxChangeKbps>2345</maxChangeKbps>
  147. <startBrowser>false</startBrowser>
  148. <upnpEnabled>false</upnpEnabled>
  149. </options>
  150. </configuration>
  151. `)
  152. expected := OptionsConfiguration{
  153. ListenAddress: []string{":23000"},
  154. GlobalAnnServer: "syncthing.nym.se:22025",
  155. GlobalAnnEnabled: false,
  156. LocalAnnEnabled: false,
  157. LocalAnnPort: 42123,
  158. ParallelRequests: 32,
  159. MaxSendKbps: 1234,
  160. RescanIntervalS: 600,
  161. ReconnectIntervalS: 6000,
  162. MaxChangeKbps: 2345,
  163. StartBrowser: false,
  164. UPnPEnabled: false,
  165. }
  166. cfg, err := Load(bytes.NewReader(data), "nodeID")
  167. if err != nil {
  168. t.Error(err)
  169. }
  170. if !reflect.DeepEqual(cfg.Options, expected) {
  171. t.Errorf("Overridden config differs;\n E: %#v\n A: %#v", expected, cfg.Options)
  172. }
  173. }
  174. func TestNodeAddresses(t *testing.T) {
  175. data := []byte(`
  176. <configuration version="2">
  177. <node id="n1">
  178. <address>dynamic</address>
  179. </node>
  180. <node id="n2">
  181. <address></address>
  182. </node>
  183. <node id="n3">
  184. </node>
  185. </configuration>
  186. `)
  187. name, _ := os.Hostname()
  188. expected := []NodeConfiguration{
  189. {
  190. NodeID: "N1",
  191. Addresses: []string{"dynamic"},
  192. },
  193. {
  194. NodeID: "N2",
  195. Addresses: []string{"dynamic"},
  196. },
  197. {
  198. NodeID: "N3",
  199. Addresses: []string{"dynamic"},
  200. },
  201. {
  202. NodeID: "N4",
  203. Name: name, // Set when auto created
  204. Addresses: []string{"dynamic"},
  205. },
  206. }
  207. cfg, err := Load(bytes.NewReader(data), "N4")
  208. if err != nil {
  209. t.Error(err)
  210. }
  211. if !reflect.DeepEqual(cfg.Nodes, expected) {
  212. t.Errorf("Nodes differ;\n E: %#v\n A: %#v", expected, cfg.Nodes)
  213. }
  214. }
  215. func TestStripNodeIs(t *testing.T) {
  216. data := []byte(`
  217. <configuration version="2">
  218. <node id="AAAA-BBBB-CCCC">
  219. <address>dynamic</address>
  220. </node>
  221. <node id="AAAA BBBB DDDD">
  222. <address></address>
  223. </node>
  224. <node id="AAAABBBBEEEE">
  225. <address></address>
  226. </node>
  227. <repository directory="~/Sync">
  228. <node id="AAA ABBB-BCC CC" name=""></node>
  229. <node id="AA-AAB BBBD-DDD" name=""></node>
  230. <node id="AAA AB-BBB EEE-E" name=""></node>
  231. </repository>
  232. </configuration>
  233. `)
  234. expected := []NodeConfiguration{
  235. {
  236. NodeID: "AAAABBBBCCCC",
  237. Addresses: []string{"dynamic"},
  238. },
  239. {
  240. NodeID: "AAAABBBBDDDD",
  241. Addresses: []string{"dynamic"},
  242. },
  243. {
  244. NodeID: "AAAABBBBEEEE",
  245. Addresses: []string{"dynamic"},
  246. },
  247. }
  248. cfg, err := Load(bytes.NewReader(data), "n4")
  249. if err != nil {
  250. t.Error(err)
  251. }
  252. for i := range expected {
  253. if !reflect.DeepEqual(cfg.Nodes[i], expected[i]) {
  254. t.Errorf("Nodes[%d] differ;\n E: %#v\n A: %#v", i, expected[i], cfg.Nodes[i])
  255. }
  256. if cfg.Repositories[0].Nodes[i].NodeID != expected[i].NodeID {
  257. t.Errorf("Repo nodes[%d] differ;\n E: %#v\n A: %#v", i, expected[i].NodeID, cfg.Repositories[0].Nodes[i].NodeID)
  258. }
  259. }
  260. }
  261. func TestSyncOrders(t *testing.T) {
  262. data := []byte(`
  263. <configuration version="2">
  264. <node id="AAAA-BBBB-CCCC">
  265. <address>dynamic</address>
  266. </node>
  267. <repository directory="~/Sync">
  268. <syncorder>
  269. <pattern pattern="\.jpg$" priority="1" />
  270. </syncorder>
  271. <node id="AAAA-BBBB-CCCC" name=""></node>
  272. </repository>
  273. </configuration>
  274. `)
  275. expected := []SyncOrderPattern{
  276. {
  277. Pattern: "\\.jpg$",
  278. Priority: 1,
  279. },
  280. }
  281. cfg, err := Load(bytes.NewReader(data), "n4")
  282. if err != nil {
  283. t.Error(err)
  284. }
  285. for i := range expected {
  286. if !reflect.DeepEqual(cfg.Repositories[0].SyncOrderPatterns[i], expected[i]) {
  287. t.Errorf("Nodes[%d] differ;\n E: %#v\n A: %#v", i, expected[i], cfg.Repositories[0].SyncOrderPatterns[i])
  288. }
  289. }
  290. }
  291. func TestFileSorter(t *testing.T) {
  292. rcfg := RepositoryConfiguration{
  293. SyncOrderPatterns: []SyncOrderPattern{
  294. {"\\.jpg$", 10, nil},
  295. {"\\.mov$", 5, nil},
  296. {"^camera-uploads", 100, nil},
  297. },
  298. }
  299. f := []scanner.File{
  300. {Name: "bar.mov"},
  301. {Name: "baz.txt"},
  302. {Name: "foo.jpg"},
  303. {Name: "frew/foo.jpg"},
  304. {Name: "frew/lol.go"},
  305. {Name: "frew/rofl.copter"},
  306. {Name: "frew/bar.mov"},
  307. {Name: "camera-uploads/foo.jpg"},
  308. {Name: "camera-uploads/hurr.pl"},
  309. {Name: "camera-uploads/herp.mov"},
  310. {Name: "camera-uploads/wee.txt"},
  311. }
  312. files.SortBy(rcfg.FileRanker()).Sort(f)
  313. expected := []scanner.File{
  314. {Name: "camera-uploads/foo.jpg"},
  315. {Name: "camera-uploads/herp.mov"},
  316. {Name: "camera-uploads/hurr.pl"},
  317. {Name: "camera-uploads/wee.txt"},
  318. {Name: "foo.jpg"},
  319. {Name: "frew/foo.jpg"},
  320. {Name: "bar.mov"},
  321. {Name: "frew/bar.mov"},
  322. {Name: "frew/lol.go"},
  323. {Name: "baz.txt"},
  324. {Name: "frew/rofl.copter"},
  325. }
  326. if !reflect.DeepEqual(f, expected) {
  327. t.Errorf(
  328. "\n\nexpected:\n" +
  329. formatFiles(expected) + "\n" +
  330. "got:\n" +
  331. formatFiles(f) + "\n\n",
  332. )
  333. }
  334. }
  335. func formatFiles(f []scanner.File) string {
  336. ret := ""
  337. for _, v := range f {
  338. ret += " " + v.Name + "\n"
  339. }
  340. return ret
  341. }