config_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  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 config
  5. import (
  6. "bytes"
  7. "io"
  8. "os"
  9. "reflect"
  10. "testing"
  11. "github.com/syncthing/syncthing/protocol"
  12. )
  13. var node1, node2, node3, node4 protocol.NodeID
  14. func init() {
  15. node1, _ = protocol.NodeIDFromString("AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ")
  16. node2, _ = protocol.NodeIDFromString("GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY")
  17. node3, _ = protocol.NodeIDFromString("LGFPDIT-7SKNNJL-VJZA4FC-7QNCRKA-CE753K7-2BW5QDK-2FOZ7FR-FEP57QJ")
  18. node4, _ = protocol.NodeIDFromString("P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2")
  19. }
  20. func TestDefaultValues(t *testing.T) {
  21. expected := OptionsConfiguration{
  22. ListenAddress: []string{"0.0.0.0:22000"},
  23. GlobalAnnServer: "announce.syncthing.net:22026",
  24. GlobalAnnEnabled: true,
  25. LocalAnnEnabled: true,
  26. LocalAnnPort: 21025,
  27. LocalAnnMCAddr: "[ff32::5222]:21026",
  28. ParallelRequests: 16,
  29. MaxSendKbps: 0,
  30. ReconnectIntervalS: 60,
  31. StartBrowser: true,
  32. UPnPEnabled: true,
  33. UPnPLease: 0,
  34. UPnPRenewal: 30,
  35. }
  36. cfg, err := Load(bytes.NewReader(nil), node1)
  37. if err != io.EOF {
  38. t.Error(err)
  39. }
  40. if !reflect.DeepEqual(cfg.Options, expected) {
  41. t.Errorf("Default config differs;\n E: %#v\n A: %#v", expected, cfg.Options)
  42. }
  43. }
  44. func TestNodeConfig(t *testing.T) {
  45. v1data := []byte(`
  46. <configuration version="1">
  47. <repository id="test" directory="~/Sync">
  48. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ" name="node one">
  49. <address>a</address>
  50. </node>
  51. <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ" name="node two">
  52. <address>b</address>
  53. </node>
  54. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ" name="node one">
  55. <address>a</address>
  56. </node>
  57. <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ" name="node two">
  58. <address>b</address>
  59. </node>
  60. </repository>
  61. <options>
  62. <readOnly>true</readOnly>
  63. <rescanIntervalS>600</rescanIntervalS>
  64. </options>
  65. </configuration>
  66. `)
  67. v2data := []byte(`
  68. <configuration version="2">
  69. <repository id="test" directory="~/Sync" ro="true">
  70. <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ"/>
  71. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ"/>
  72. <node id="C4YBIESWDUAIGU62GOSRXCRAAJDWVE3TKCPMURZE2LH5QHAF576A"/>
  73. <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ"/>
  74. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ"/>
  75. <node id="C4YBIESWDUAIGU62GOSRXCRAAJDWVE3TKCPMURZE2LH5QHAF576A"/>
  76. </repository>
  77. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ" name="node one">
  78. <address>a</address>
  79. </node>
  80. <node id="P56IOI7MZJNU2IQGDREYDM2MGTMGL3BXNPQ6W5BTBBZ4TJXZWICQ" name="node two">
  81. <address>b</address>
  82. </node>
  83. <options>
  84. <rescanIntervalS>600</rescanIntervalS>
  85. </options>
  86. </configuration>
  87. `)
  88. v3data := []byte(`
  89. <configuration version="3">
  90. <repository id="test" directory="~/Sync" ro="true" ignorePerms="false">
  91. <node id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" compression="false"></node>
  92. <node id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" compression="false"></node>
  93. </repository>
  94. <node id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="true">
  95. <address>a</address>
  96. </node>
  97. <node id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" name="node two" compression="true">
  98. <address>b</address>
  99. </node>
  100. <options>
  101. <rescanIntervalS>600</rescanIntervalS>
  102. </options>
  103. </configuration>`)
  104. v4data := []byte(`
  105. <configuration version="4">
  106. <repository id="test" directory="~/Sync" ro="true" ignorePerms="false" rescanIntervalS="600">
  107. <node id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></node>
  108. <node id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"></node>
  109. </repository>
  110. <node id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="true">
  111. <address>a</address>
  112. </node>
  113. <node id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2" name="node two" compression="true">
  114. <address>b</address>
  115. </node>
  116. </configuration>`)
  117. for i, data := range [][]byte{v1data, v2data, v3data, v4data} {
  118. cfg, err := Load(bytes.NewReader(data), node1)
  119. if err != nil {
  120. t.Error(err)
  121. }
  122. expectedRepos := []RepositoryConfiguration{
  123. {
  124. ID: "test",
  125. Directory: "~/Sync",
  126. Nodes: []RepositoryNodeConfiguration{{NodeID: node1}, {NodeID: node4}},
  127. ReadOnly: true,
  128. RescanIntervalS: 600,
  129. },
  130. }
  131. expectedNodes := []NodeConfiguration{
  132. {
  133. NodeID: node1,
  134. Name: "node one",
  135. Addresses: []string{"a"},
  136. Compression: true,
  137. },
  138. {
  139. NodeID: node4,
  140. Name: "node two",
  141. Addresses: []string{"b"},
  142. Compression: true,
  143. },
  144. }
  145. expectedNodeIDs := []protocol.NodeID{node1, node4}
  146. if cfg.Version != 4 {
  147. t.Errorf("%d: Incorrect version %d != 3", i, cfg.Version)
  148. }
  149. if !reflect.DeepEqual(cfg.Repositories, expectedRepos) {
  150. t.Errorf("%d: Incorrect Repositories\n A: %#v\n E: %#v", i, cfg.Repositories, expectedRepos)
  151. }
  152. if !reflect.DeepEqual(cfg.Nodes, expectedNodes) {
  153. t.Errorf("%d: Incorrect Nodes\n A: %#v\n E: %#v", i, cfg.Nodes, expectedNodes)
  154. }
  155. if !reflect.DeepEqual(cfg.Repositories[0].NodeIDs(), expectedNodeIDs) {
  156. t.Errorf("%d: Incorrect NodeIDs\n A: %#v\n E: %#v", i, cfg.Repositories[0].NodeIDs(), expectedNodeIDs)
  157. }
  158. if len(cfg.NodeMap()) != len(expectedNodes) {
  159. t.Errorf("Unexpected number of NodeMap() entries")
  160. }
  161. if len(cfg.RepoMap()) != len(expectedRepos) {
  162. t.Errorf("Unexpected number of RepoMap() entries")
  163. }
  164. }
  165. }
  166. func TestNoListenAddress(t *testing.T) {
  167. data := []byte(`<configuration version="1">
  168. <options>
  169. <listenAddress></listenAddress>
  170. </options>
  171. </configuration>
  172. `)
  173. cfg, err := Load(bytes.NewReader(data), node1)
  174. if err != nil {
  175. t.Error(err)
  176. }
  177. expected := []string{""}
  178. if !reflect.DeepEqual(cfg.Options.ListenAddress, expected) {
  179. t.Errorf("Unexpected ListenAddress %#v", cfg.Options.ListenAddress)
  180. }
  181. }
  182. func TestOverriddenValues(t *testing.T) {
  183. data := []byte(`<configuration version="2">
  184. <options>
  185. <listenAddress>:23000</listenAddress>
  186. <allowDelete>false</allowDelete>
  187. <globalAnnounceServer>syncthing.nym.se:22026</globalAnnounceServer>
  188. <globalAnnounceEnabled>false</globalAnnounceEnabled>
  189. <localAnnounceEnabled>false</localAnnounceEnabled>
  190. <localAnnouncePort>42123</localAnnouncePort>
  191. <localAnnounceMCAddr>quux:3232</localAnnounceMCAddr>
  192. <parallelRequests>32</parallelRequests>
  193. <maxSendKbps>1234</maxSendKbps>
  194. <reconnectionIntervalS>6000</reconnectionIntervalS>
  195. <startBrowser>false</startBrowser>
  196. <upnpEnabled>false</upnpEnabled>
  197. <upnpLeaseMinutes>60</upnpLeaseMinutes>
  198. <upnpRenewalMinutes>15</upnpRenewalMinutes>
  199. </options>
  200. </configuration>
  201. `)
  202. expected := OptionsConfiguration{
  203. ListenAddress: []string{":23000"},
  204. GlobalAnnServer: "syncthing.nym.se:22026",
  205. GlobalAnnEnabled: false,
  206. LocalAnnEnabled: false,
  207. LocalAnnPort: 42123,
  208. LocalAnnMCAddr: "quux:3232",
  209. ParallelRequests: 32,
  210. MaxSendKbps: 1234,
  211. ReconnectIntervalS: 6000,
  212. StartBrowser: false,
  213. UPnPEnabled: false,
  214. UPnPLease: 60,
  215. UPnPRenewal: 15,
  216. }
  217. cfg, err := Load(bytes.NewReader(data), node1)
  218. if err != nil {
  219. t.Error(err)
  220. }
  221. if !reflect.DeepEqual(cfg.Options, expected) {
  222. t.Errorf("Overridden config differs;\n E: %#v\n A: %#v", expected, cfg.Options)
  223. }
  224. }
  225. func TestNodeAddressesDynamic(t *testing.T) {
  226. data := []byte(`
  227. <configuration version="2">
  228. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ">
  229. <address></address>
  230. </node>
  231. <node id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA">
  232. </node>
  233. <node id="LGFPDIT7SKNNJVJZA4FC7QNCRKCE753K72BW5QD2FOZ7FRFEP57Q">
  234. <address>dynamic</address>
  235. </node>
  236. </configuration>
  237. `)
  238. name, _ := os.Hostname()
  239. expected := []NodeConfiguration{
  240. {
  241. NodeID: node1,
  242. Addresses: []string{"dynamic"},
  243. Compression: true,
  244. },
  245. {
  246. NodeID: node2,
  247. Addresses: []string{"dynamic"},
  248. Compression: true,
  249. },
  250. {
  251. NodeID: node3,
  252. Addresses: []string{"dynamic"},
  253. Compression: true,
  254. },
  255. {
  256. NodeID: node4,
  257. Name: name, // Set when auto created
  258. Addresses: []string{"dynamic"},
  259. },
  260. }
  261. cfg, err := Load(bytes.NewReader(data), node4)
  262. if err != nil {
  263. t.Error(err)
  264. }
  265. if !reflect.DeepEqual(cfg.Nodes, expected) {
  266. t.Errorf("Nodes differ;\n E: %#v\n A: %#v", expected, cfg.Nodes)
  267. }
  268. }
  269. func TestNodeAddressesStatic(t *testing.T) {
  270. data := []byte(`
  271. <configuration version="3">
  272. <node id="AIR6LPZ7K4PTTUXQSMUUCPQ5YWOEDFIIQJUG7772YQXXR5YD6AWQ">
  273. <address>192.0.2.1</address>
  274. <address>192.0.2.2</address>
  275. </node>
  276. <node id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA">
  277. <address>192.0.2.3:6070</address>
  278. <address>[2001:db8::42]:4242</address>
  279. </node>
  280. <node id="LGFPDIT7SKNNJVJZA4FC7QNCRKCE753K72BW5QD2FOZ7FRFEP57Q">
  281. <address>[2001:db8::44]:4444</address>
  282. <address>192.0.2.4:6090</address>
  283. </node>
  284. </configuration>
  285. `)
  286. name, _ := os.Hostname()
  287. expected := []NodeConfiguration{
  288. {
  289. NodeID: node1,
  290. Addresses: []string{"192.0.2.1", "192.0.2.2"},
  291. },
  292. {
  293. NodeID: node2,
  294. Addresses: []string{"192.0.2.3:6070", "[2001:db8::42]:4242"},
  295. },
  296. {
  297. NodeID: node3,
  298. Addresses: []string{"[2001:db8::44]:4444", "192.0.2.4:6090"},
  299. },
  300. {
  301. NodeID: node4,
  302. Name: name, // Set when auto created
  303. Addresses: []string{"dynamic"},
  304. },
  305. }
  306. cfg, err := Load(bytes.NewReader(data), node4)
  307. if err != nil {
  308. t.Error(err)
  309. }
  310. if !reflect.DeepEqual(cfg.Nodes, expected) {
  311. t.Errorf("Nodes differ;\n E: %#v\n A: %#v", expected, cfg.Nodes)
  312. }
  313. }
  314. func TestVersioningConfig(t *testing.T) {
  315. data := []byte(`
  316. <configuration version="2">
  317. <repository id="test" directory="~/Sync" ro="true">
  318. <versioning type="simple">
  319. <param key="foo" val="bar"/>
  320. <param key="baz" val="quux"/>
  321. </versioning>
  322. </repository>
  323. </configuration>
  324. `)
  325. cfg, err := Load(bytes.NewReader(data), node4)
  326. if err != nil {
  327. t.Error(err)
  328. }
  329. vc := cfg.Repositories[0].Versioning
  330. if vc.Type != "simple" {
  331. t.Errorf(`vc.Type %q != "simple"`, vc.Type)
  332. }
  333. if l := len(vc.Params); l != 2 {
  334. t.Errorf("len(vc.Params) %d != 2", l)
  335. }
  336. expected := map[string]string{
  337. "foo": "bar",
  338. "baz": "quux",
  339. }
  340. if !reflect.DeepEqual(vc.Params, expected) {
  341. t.Errorf("vc.Params differ;\n E: %#v\n A: %#v", expected, vc.Params)
  342. }
  343. }