2
0

config_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. package worker
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "testing"
  8. . "github.com/smartystreets/goconvey/convey"
  9. )
  10. func TestConfig(t *testing.T) {
  11. var cfgBlob = `
  12. [global]
  13. name = "test_worker"
  14. log_dir = "/var/log/tunasync/{{.Name}}"
  15. mirror_dir = "/data/mirrors"
  16. concurrent = 10
  17. interval = 240
  18. retry = 3
  19. [manager]
  20. api_base = "https://127.0.0.1:5000"
  21. token = "some_token"
  22. [server]
  23. hostname = "worker1.example.com"
  24. listen_addr = "127.0.0.1"
  25. listen_port = 6000
  26. ssl_cert = "/etc/tunasync.d/worker1.cert"
  27. ssl_key = "/etc/tunasync.d/worker1.key"
  28. [[mirrors]]
  29. name = "AOSP"
  30. provider = "command"
  31. upstream = "https://aosp.google.com/"
  32. interval = 720
  33. retry = 2
  34. mirror_dir = "/data/git/AOSP"
  35. exec_on_success = [
  36. "bash -c 'echo ${TUNASYNC_JOB_EXIT_STATUS} > ${TUNASYNC_WORKING_DIR}/exit_status'"
  37. ]
  38. [mirrors.env]
  39. REPO = "/usr/local/bin/aosp-repo"
  40. [[mirrors]]
  41. name = "debian"
  42. provider = "two-stage-rsync"
  43. stage1_profile = "debian"
  44. upstream = "rsync://ftp.debian.org/debian/"
  45. use_ipv6 = true
  46. [[mirrors]]
  47. name = "fedora"
  48. provider = "rsync"
  49. upstream = "rsync://ftp.fedoraproject.org/fedora/"
  50. use_ipv6 = true
  51. exclude_file = "/etc/tunasync.d/fedora-exclude.txt"
  52. exec_on_failure = [
  53. "bash -c 'echo ${TUNASYNC_JOB_EXIT_STATUS} > ${TUNASYNC_WORKING_DIR}/exit_status'"
  54. ]
  55. `
  56. Convey("When giving invalid file", t, func() {
  57. cfg, err := LoadConfig("/path/to/invalid/file")
  58. So(err, ShouldNotBeNil)
  59. So(cfg, ShouldBeNil)
  60. })
  61. Convey("Everything should work on valid config file", t, func() {
  62. tmpfile, err := ioutil.TempFile("", "tunasync")
  63. So(err, ShouldEqual, nil)
  64. defer os.Remove(tmpfile.Name())
  65. tmpDir, err := ioutil.TempDir("", "tunasync")
  66. So(err, ShouldBeNil)
  67. defer os.RemoveAll(tmpDir)
  68. incSection := fmt.Sprintf(
  69. "\n[include]\n"+
  70. "include_mirrors = \"%s/*.conf\"",
  71. tmpDir,
  72. )
  73. curCfgBlob := cfgBlob + incSection
  74. err = ioutil.WriteFile(tmpfile.Name(), []byte(curCfgBlob), 0644)
  75. So(err, ShouldEqual, nil)
  76. defer tmpfile.Close()
  77. incBlob1 := `
  78. [[mirrors]]
  79. name = "debian-cd"
  80. provider = "two-stage-rsync"
  81. stage1_profile = "debian"
  82. use_ipv6 = true
  83. [[mirrors]]
  84. name = "debian-security"
  85. provider = "two-stage-rsync"
  86. stage1_profile = "debian"
  87. use_ipv6 = true
  88. `
  89. incBlob2 := `
  90. [[mirrors]]
  91. name = "ubuntu"
  92. provider = "two-stage-rsync"
  93. stage1_profile = "debian"
  94. use_ipv6 = true
  95. `
  96. err = ioutil.WriteFile(filepath.Join(tmpDir, "debian.conf"), []byte(incBlob1), 0644)
  97. So(err, ShouldEqual, nil)
  98. err = ioutil.WriteFile(filepath.Join(tmpDir, "ubuntu.conf"), []byte(incBlob2), 0644)
  99. So(err, ShouldEqual, nil)
  100. cfg, err := LoadConfig(tmpfile.Name())
  101. So(err, ShouldBeNil)
  102. So(cfg.Global.Name, ShouldEqual, "test_worker")
  103. So(cfg.Global.Interval, ShouldEqual, 240)
  104. So(cfg.Global.Retry, ShouldEqual, 3)
  105. So(cfg.Global.MirrorDir, ShouldEqual, "/data/mirrors")
  106. So(cfg.Manager.APIBase, ShouldEqual, "https://127.0.0.1:5000")
  107. So(cfg.Server.Hostname, ShouldEqual, "worker1.example.com")
  108. m := cfg.Mirrors[0]
  109. So(m.Name, ShouldEqual, "AOSP")
  110. So(m.MirrorDir, ShouldEqual, "/data/git/AOSP")
  111. So(m.Provider, ShouldEqual, provCommand)
  112. So(m.Interval, ShouldEqual, 720)
  113. So(m.Retry, ShouldEqual, 2)
  114. So(m.Env["REPO"], ShouldEqual, "/usr/local/bin/aosp-repo")
  115. m = cfg.Mirrors[1]
  116. So(m.Name, ShouldEqual, "debian")
  117. So(m.MirrorDir, ShouldEqual, "")
  118. So(m.Provider, ShouldEqual, provTwoStageRsync)
  119. m = cfg.Mirrors[2]
  120. So(m.Name, ShouldEqual, "fedora")
  121. So(m.MirrorDir, ShouldEqual, "")
  122. So(m.Provider, ShouldEqual, provRsync)
  123. So(m.ExcludeFile, ShouldEqual, "/etc/tunasync.d/fedora-exclude.txt")
  124. m = cfg.Mirrors[3]
  125. So(m.Name, ShouldEqual, "debian-cd")
  126. So(m.MirrorDir, ShouldEqual, "")
  127. So(m.Provider, ShouldEqual, provTwoStageRsync)
  128. m = cfg.Mirrors[4]
  129. So(m.Name, ShouldEqual, "debian-security")
  130. m = cfg.Mirrors[5]
  131. So(m.Name, ShouldEqual, "ubuntu")
  132. So(len(cfg.Mirrors), ShouldEqual, 6)
  133. })
  134. Convey("Everything should work on nested config file", t, func() {
  135. tmpfile, err := ioutil.TempFile("", "tunasync")
  136. So(err, ShouldEqual, nil)
  137. defer os.Remove(tmpfile.Name())
  138. tmpDir, err := ioutil.TempDir("", "tunasync")
  139. So(err, ShouldBeNil)
  140. defer os.RemoveAll(tmpDir)
  141. incSection := fmt.Sprintf(
  142. "\n[include]\n"+
  143. "include_mirrors = \"%s/*.conf\"",
  144. tmpDir,
  145. )
  146. curCfgBlob := cfgBlob + incSection
  147. err = ioutil.WriteFile(tmpfile.Name(), []byte(curCfgBlob), 0644)
  148. So(err, ShouldEqual, nil)
  149. defer tmpfile.Close()
  150. incBlob1 := `
  151. [[mirrors]]
  152. name = "ipv6s"
  153. use_ipv6 = true
  154. [[mirrors.mirrors]]
  155. name = "debians"
  156. mirror_subdir = "debian"
  157. provider = "two-stage-rsync"
  158. stage1_profile = "debian"
  159. [[mirrors.mirrors.mirrors]]
  160. name = "debian-security"
  161. upstream = "rsync://test.host/debian-security/"
  162. [[mirrors.mirrors.mirrors]]
  163. name = "ubuntu"
  164. stage1_profile = "ubuntu"
  165. upstream = "rsync://test.host2/ubuntu/"
  166. [[mirrors.mirrors]]
  167. name = "debian-cd"
  168. provider = "rsync"
  169. upstream = "rsync://test.host3/debian-cd/"
  170. `
  171. err = ioutil.WriteFile(filepath.Join(tmpDir, "nest.conf"), []byte(incBlob1), 0644)
  172. So(err, ShouldEqual, nil)
  173. cfg, err := LoadConfig(tmpfile.Name())
  174. So(err, ShouldBeNil)
  175. So(cfg.Global.Name, ShouldEqual, "test_worker")
  176. So(cfg.Global.Interval, ShouldEqual, 240)
  177. So(cfg.Global.Retry, ShouldEqual, 3)
  178. So(cfg.Global.MirrorDir, ShouldEqual, "/data/mirrors")
  179. So(cfg.Manager.APIBase, ShouldEqual, "https://127.0.0.1:5000")
  180. So(cfg.Server.Hostname, ShouldEqual, "worker1.example.com")
  181. m := cfg.Mirrors[0]
  182. So(m.Name, ShouldEqual, "AOSP")
  183. So(m.MirrorDir, ShouldEqual, "/data/git/AOSP")
  184. So(m.Provider, ShouldEqual, provCommand)
  185. So(m.Interval, ShouldEqual, 720)
  186. So(m.Retry, ShouldEqual, 2)
  187. So(m.Env["REPO"], ShouldEqual, "/usr/local/bin/aosp-repo")
  188. m = cfg.Mirrors[1]
  189. So(m.Name, ShouldEqual, "debian")
  190. So(m.MirrorDir, ShouldEqual, "")
  191. So(m.Provider, ShouldEqual, provTwoStageRsync)
  192. m = cfg.Mirrors[2]
  193. So(m.Name, ShouldEqual, "fedora")
  194. So(m.MirrorDir, ShouldEqual, "")
  195. So(m.Provider, ShouldEqual, provRsync)
  196. So(m.ExcludeFile, ShouldEqual, "/etc/tunasync.d/fedora-exclude.txt")
  197. m = cfg.Mirrors[3]
  198. So(m.Name, ShouldEqual, "debian-security")
  199. So(m.MirrorDir, ShouldEqual, "")
  200. So(m.Provider, ShouldEqual, provTwoStageRsync)
  201. So(m.UseIPv6, ShouldEqual, true)
  202. So(m.Stage1Profile, ShouldEqual, "debian")
  203. m = cfg.Mirrors[4]
  204. So(m.Name, ShouldEqual, "ubuntu")
  205. So(m.MirrorDir, ShouldEqual, "")
  206. So(m.Provider, ShouldEqual, provTwoStageRsync)
  207. So(m.UseIPv6, ShouldEqual, true)
  208. So(m.Stage1Profile, ShouldEqual, "ubuntu")
  209. m = cfg.Mirrors[5]
  210. So(m.Name, ShouldEqual, "debian-cd")
  211. So(m.UseIPv6, ShouldEqual, true)
  212. So(m.Provider, ShouldEqual, provRsync)
  213. So(len(cfg.Mirrors), ShouldEqual, 6)
  214. })
  215. Convey("Providers can be inited from a valid config file", t, func() {
  216. tmpfile, err := ioutil.TempFile("", "tunasync")
  217. So(err, ShouldEqual, nil)
  218. defer os.Remove(tmpfile.Name())
  219. err = ioutil.WriteFile(tmpfile.Name(), []byte(cfgBlob), 0644)
  220. So(err, ShouldEqual, nil)
  221. defer tmpfile.Close()
  222. cfg, err := LoadConfig(tmpfile.Name())
  223. So(err, ShouldBeNil)
  224. providers := map[string]mirrorProvider{}
  225. for _, m := range cfg.Mirrors {
  226. p := newMirrorProvider(m, cfg)
  227. providers[p.Name()] = p
  228. }
  229. p := providers["AOSP"]
  230. So(p.Name(), ShouldEqual, "AOSP")
  231. So(p.LogDir(), ShouldEqual, "/var/log/tunasync/AOSP")
  232. So(p.LogFile(), ShouldEqual, "/var/log/tunasync/AOSP/latest.log")
  233. _, ok := p.(*cmdProvider)
  234. So(ok, ShouldBeTrue)
  235. for _, hook := range p.Hooks() {
  236. switch h := hook.(type) {
  237. case *execPostHook:
  238. So(h.command, ShouldResemble, []string{"bash", "-c", `echo ${TUNASYNC_JOB_EXIT_STATUS} > ${TUNASYNC_WORKING_DIR}/exit_status`})
  239. }
  240. }
  241. p = providers["debian"]
  242. So(p.Name(), ShouldEqual, "debian")
  243. So(p.LogDir(), ShouldEqual, "/var/log/tunasync/debian")
  244. So(p.LogFile(), ShouldEqual, "/var/log/tunasync/debian/latest.log")
  245. r2p, ok := p.(*twoStageRsyncProvider)
  246. So(ok, ShouldBeTrue)
  247. So(r2p.stage1Profile, ShouldEqual, "debian")
  248. So(r2p.WorkingDir(), ShouldEqual, "/data/mirrors/debian")
  249. p = providers["fedora"]
  250. So(p.Name(), ShouldEqual, "fedora")
  251. So(p.LogDir(), ShouldEqual, "/var/log/tunasync/fedora")
  252. So(p.LogFile(), ShouldEqual, "/var/log/tunasync/fedora/latest.log")
  253. rp, ok := p.(*rsyncProvider)
  254. So(ok, ShouldBeTrue)
  255. So(rp.WorkingDir(), ShouldEqual, "/data/mirrors/fedora")
  256. So(rp.excludeFile, ShouldEqual, "/etc/tunasync.d/fedora-exclude.txt")
  257. })
  258. Convey("MirrorSubdir should work", t, func() {
  259. tmpfile, err := ioutil.TempFile("", "tunasync")
  260. So(err, ShouldEqual, nil)
  261. defer os.Remove(tmpfile.Name())
  262. cfgBlob1 := `
  263. [global]
  264. name = "test_worker"
  265. log_dir = "/var/log/tunasync/{{.Name}}"
  266. mirror_dir = "/data/mirrors"
  267. concurrent = 10
  268. interval = 240
  269. retry = 3
  270. [manager]
  271. api_base = "https://127.0.0.1:5000"
  272. token = "some_token"
  273. [server]
  274. hostname = "worker1.example.com"
  275. listen_addr = "127.0.0.1"
  276. listen_port = 6000
  277. ssl_cert = "/etc/tunasync.d/worker1.cert"
  278. ssl_key = "/etc/tunasync.d/worker1.key"
  279. [[mirrors]]
  280. name = "ipv6s"
  281. use_ipv6 = true
  282. [[mirrors.mirrors]]
  283. name = "debians"
  284. mirror_subdir = "debian"
  285. provider = "two-stage-rsync"
  286. stage1_profile = "debian"
  287. [[mirrors.mirrors.mirrors]]
  288. name = "debian-security"
  289. upstream = "rsync://test.host/debian-security/"
  290. [[mirrors.mirrors.mirrors]]
  291. name = "ubuntu"
  292. stage1_profile = "ubuntu"
  293. upstream = "rsync://test.host2/ubuntu/"
  294. [[mirrors.mirrors]]
  295. name = "debian-cd"
  296. provider = "rsync"
  297. upstream = "rsync://test.host3/debian-cd/"
  298. `
  299. err = ioutil.WriteFile(tmpfile.Name(), []byte(cfgBlob1), 0644)
  300. So(err, ShouldEqual, nil)
  301. defer tmpfile.Close()
  302. cfg, err := LoadConfig(tmpfile.Name())
  303. So(err, ShouldBeNil)
  304. providers := map[string]mirrorProvider{}
  305. for _, m := range cfg.Mirrors {
  306. p := newMirrorProvider(m, cfg)
  307. providers[p.Name()] = p
  308. }
  309. p := providers["debian-security"]
  310. So(p.Name(), ShouldEqual, "debian-security")
  311. So(p.LogDir(), ShouldEqual, "/var/log/tunasync/debian-security")
  312. So(p.LogFile(), ShouldEqual, "/var/log/tunasync/debian-security/latest.log")
  313. r2p, ok := p.(*twoStageRsyncProvider)
  314. So(ok, ShouldBeTrue)
  315. So(r2p.stage1Profile, ShouldEqual, "debian")
  316. So(r2p.WorkingDir(), ShouldEqual, "/data/mirrors/debian/debian-security")
  317. p = providers["ubuntu"]
  318. So(p.Name(), ShouldEqual, "ubuntu")
  319. So(p.LogDir(), ShouldEqual, "/var/log/tunasync/ubuntu")
  320. So(p.LogFile(), ShouldEqual, "/var/log/tunasync/ubuntu/latest.log")
  321. r2p, ok = p.(*twoStageRsyncProvider)
  322. So(ok, ShouldBeTrue)
  323. So(r2p.stage1Profile, ShouldEqual, "ubuntu")
  324. So(r2p.WorkingDir(), ShouldEqual, "/data/mirrors/debian/ubuntu")
  325. p = providers["debian-cd"]
  326. So(p.Name(), ShouldEqual, "debian-cd")
  327. So(p.LogDir(), ShouldEqual, "/var/log/tunasync/debian-cd")
  328. So(p.LogFile(), ShouldEqual, "/var/log/tunasync/debian-cd/latest.log")
  329. rp, ok := p.(*rsyncProvider)
  330. So(ok, ShouldBeTrue)
  331. So(rp.WorkingDir(), ShouldEqual, "/data/mirrors/debian-cd")
  332. })
  333. }