2
0

config_test.go 11 KB

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