2
0

provider_test.go 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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 TestRsyncProvider(t *testing.T) {
  12. Convey("Rsync Provider should work", t, func() {
  13. tmpDir, err := ioutil.TempDir("", "tunasync")
  14. defer os.RemoveAll(tmpDir)
  15. So(err, ShouldBeNil)
  16. scriptFile := filepath.Join(tmpDir, "myrsync")
  17. tmpFile := filepath.Join(tmpDir, "log_file")
  18. c := rsyncConfig{
  19. name: "tuna",
  20. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  21. rsyncCmd: scriptFile,
  22. workingDir: tmpDir,
  23. logDir: tmpDir,
  24. logFile: tmpFile,
  25. useIPv6: true,
  26. interval: 600 * time.Second,
  27. }
  28. provider, err := newRsyncProvider(c)
  29. So(err, ShouldBeNil)
  30. So(provider.Type(), ShouldEqual, provRsync)
  31. So(provider.Name(), ShouldEqual, c.name)
  32. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  33. So(provider.LogDir(), ShouldEqual, c.logDir)
  34. So(provider.LogFile(), ShouldEqual, c.logFile)
  35. So(provider.Interval(), ShouldEqual, c.interval)
  36. Convey("When entering a context (auto exit)", func() {
  37. func() {
  38. ctx := provider.EnterContext()
  39. defer provider.ExitContext()
  40. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  41. newWorkingDir := "/srv/mirror/working/tuna"
  42. ctx.Set(_WorkingDirKey, newWorkingDir)
  43. So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
  44. }()
  45. Convey("After context is done", func() {
  46. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  47. })
  48. })
  49. Convey("When entering a context (manually exit)", func() {
  50. ctx := provider.EnterContext()
  51. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  52. newWorkingDir := "/srv/mirror/working/tuna"
  53. ctx.Set(_WorkingDirKey, newWorkingDir)
  54. So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
  55. Convey("After context is done", func() {
  56. provider.ExitContext()
  57. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  58. })
  59. })
  60. Convey("Let's try a run", func() {
  61. scriptContent := `#!/bin/bash
  62. echo "syncing to $(pwd)"
  63. echo $RSYNC_PASSWORD $@
  64. sleep 1
  65. echo "Done"
  66. exit 0
  67. `
  68. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  69. So(err, ShouldBeNil)
  70. expectedOutput := fmt.Sprintf(
  71. "syncing to %s\n"+
  72. "%s\n"+
  73. "Done\n",
  74. provider.WorkingDir(),
  75. fmt.Sprintf(
  76. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ "+
  77. "--delete --delete-after --delay-updates --safe-links "+
  78. "--timeout=120 --contimeout=120 -6 %s %s",
  79. provider.upstreamURL, provider.WorkingDir(),
  80. ),
  81. )
  82. err = provider.Run()
  83. So(err, ShouldBeNil)
  84. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  85. So(err, ShouldBeNil)
  86. So(string(loggedContent), ShouldEqual, expectedOutput)
  87. // fmt.Println(string(loggedContent))
  88. })
  89. })
  90. }
  91. func TestRsyncProviderWithAuthentication(t *testing.T) {
  92. Convey("Rsync Provider with password should work", t, func() {
  93. tmpDir, err := ioutil.TempDir("", "tunasync")
  94. defer os.RemoveAll(tmpDir)
  95. So(err, ShouldBeNil)
  96. scriptFile := filepath.Join(tmpDir, "myrsync")
  97. tmpFile := filepath.Join(tmpDir, "log_file")
  98. c := rsyncConfig{
  99. name: "tuna",
  100. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  101. rsyncCmd: scriptFile,
  102. username: "tunasync",
  103. password: "tunasyncpassword",
  104. workingDir: tmpDir,
  105. logDir: tmpDir,
  106. logFile: tmpFile,
  107. useIPv6: true,
  108. interval: 600 * time.Second,
  109. }
  110. provider, err := newRsyncProvider(c)
  111. So(err, ShouldBeNil)
  112. So(provider.Name(), ShouldEqual, c.name)
  113. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  114. So(provider.LogDir(), ShouldEqual, c.logDir)
  115. So(provider.LogFile(), ShouldEqual, c.logFile)
  116. So(provider.Interval(), ShouldEqual, c.interval)
  117. Convey("Let's try a run", func() {
  118. scriptContent := `#!/bin/bash
  119. echo "syncing to $(pwd)"
  120. echo $USER $RSYNC_PASSWORD $@
  121. sleep 1
  122. echo "Done"
  123. exit 0
  124. `
  125. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  126. So(err, ShouldBeNil)
  127. expectedOutput := fmt.Sprintf(
  128. "syncing to %s\n"+
  129. "%s\n"+
  130. "Done\n",
  131. provider.WorkingDir(),
  132. fmt.Sprintf(
  133. "%s %s -aHvh --no-o --no-g --stats --exclude .~tmp~/ "+
  134. "--delete --delete-after --delay-updates --safe-links "+
  135. "--timeout=120 --contimeout=120 -6 %s %s",
  136. provider.username, provider.password, provider.upstreamURL, provider.WorkingDir(),
  137. ),
  138. )
  139. err = provider.Run()
  140. So(err, ShouldBeNil)
  141. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  142. So(err, ShouldBeNil)
  143. So(string(loggedContent), ShouldEqual, expectedOutput)
  144. // fmt.Println(string(loggedContent))
  145. })
  146. })
  147. }
  148. func TestCmdProvider(t *testing.T) {
  149. Convey("Command Provider should work", t, func(ctx C) {
  150. tmpDir, err := ioutil.TempDir("", "tunasync")
  151. defer os.RemoveAll(tmpDir)
  152. So(err, ShouldBeNil)
  153. scriptFile := filepath.Join(tmpDir, "cmd.sh")
  154. tmpFile := filepath.Join(tmpDir, "log_file")
  155. c := cmdConfig{
  156. name: "tuna-cmd",
  157. upstreamURL: "http://mirrors.tuna.moe/",
  158. command: "bash " + scriptFile,
  159. workingDir: tmpDir,
  160. logDir: tmpDir,
  161. logFile: tmpFile,
  162. interval: 600 * time.Second,
  163. env: map[string]string{
  164. "AOSP_REPO_BIN": "/usr/local/bin/repo",
  165. },
  166. }
  167. provider, err := newCmdProvider(c)
  168. So(err, ShouldBeNil)
  169. So(provider.Type(), ShouldEqual, provCommand)
  170. So(provider.Name(), ShouldEqual, c.name)
  171. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  172. So(provider.LogDir(), ShouldEqual, c.logDir)
  173. So(provider.LogFile(), ShouldEqual, c.logFile)
  174. So(provider.Interval(), ShouldEqual, c.interval)
  175. Convey("Let's try to run a simple command", func() {
  176. scriptContent := `#!/bin/bash
  177. echo $TUNASYNC_WORKING_DIR
  178. echo $TUNASYNC_MIRROR_NAME
  179. echo $TUNASYNC_UPSTREAM_URL
  180. echo $TUNASYNC_LOG_FILE
  181. echo $AOSP_REPO_BIN
  182. `
  183. expectedOutput := fmt.Sprintf(
  184. "%s\n%s\n%s\n%s\n%s\n",
  185. provider.WorkingDir(),
  186. provider.Name(),
  187. provider.upstreamURL,
  188. provider.LogFile(),
  189. "/usr/local/bin/repo",
  190. )
  191. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  192. So(err, ShouldBeNil)
  193. readedScriptContent, err := ioutil.ReadFile(scriptFile)
  194. So(err, ShouldBeNil)
  195. So(readedScriptContent, ShouldResemble, []byte(scriptContent))
  196. err = provider.Run()
  197. So(err, ShouldBeNil)
  198. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  199. So(err, ShouldBeNil)
  200. So(string(loggedContent), ShouldEqual, expectedOutput)
  201. })
  202. Convey("If a command fails", func() {
  203. scriptContent := `exit 1`
  204. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  205. So(err, ShouldBeNil)
  206. readedScriptContent, err := ioutil.ReadFile(scriptFile)
  207. So(err, ShouldBeNil)
  208. So(readedScriptContent, ShouldResemble, []byte(scriptContent))
  209. err = provider.Run()
  210. So(err, ShouldNotBeNil)
  211. })
  212. Convey("If a long job is killed", func(ctx C) {
  213. scriptContent := `#!/bin/bash
  214. sleep 5
  215. `
  216. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  217. So(err, ShouldBeNil)
  218. go func() {
  219. err = provider.Run()
  220. ctx.So(err, ShouldNotBeNil)
  221. }()
  222. time.Sleep(1 * time.Second)
  223. err = provider.Terminate()
  224. So(err, ShouldBeNil)
  225. })
  226. })
  227. }
  228. func TestTwoStageRsyncProvider(t *testing.T) {
  229. Convey("TwoStageRsync Provider should work", t, func(ctx C) {
  230. tmpDir, err := ioutil.TempDir("", "tunasync")
  231. defer os.RemoveAll(tmpDir)
  232. So(err, ShouldBeNil)
  233. scriptFile := filepath.Join(tmpDir, "myrsync")
  234. tmpFile := filepath.Join(tmpDir, "log_file")
  235. c := twoStageRsyncConfig{
  236. name: "tuna-two-stage-rsync",
  237. upstreamURL: "rsync://mirrors.tuna.moe/",
  238. stage1Profile: "debian",
  239. rsyncCmd: scriptFile,
  240. workingDir: tmpDir,
  241. logDir: tmpDir,
  242. logFile: tmpFile,
  243. useIPv6: true,
  244. excludeFile: tmpFile,
  245. }
  246. provider, err := newTwoStageRsyncProvider(c)
  247. So(err, ShouldBeNil)
  248. So(provider.Type(), ShouldEqual, provTwoStageRsync)
  249. So(provider.Name(), ShouldEqual, c.name)
  250. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  251. So(provider.LogDir(), ShouldEqual, c.logDir)
  252. So(provider.LogFile(), ShouldEqual, c.logFile)
  253. So(provider.Interval(), ShouldEqual, c.interval)
  254. Convey("Try a command", func(ctx C) {
  255. scriptContent := `#!/bin/bash
  256. echo "syncing to $(pwd)"
  257. echo $@
  258. sleep 1
  259. echo "Done"
  260. exit 0
  261. `
  262. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  263. So(err, ShouldBeNil)
  264. err = provider.Run()
  265. So(err, ShouldBeNil)
  266. expectedOutput := fmt.Sprintf(
  267. "syncing to %s\n"+
  268. "%s\n"+
  269. "Done\n"+
  270. "syncing to %s\n"+
  271. "%s\n"+
  272. "Done\n",
  273. provider.WorkingDir(),
  274. fmt.Sprintf(
  275. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ --safe-links "+
  276. "--timeout=120 --contimeout=120 --exclude dists/ -6 "+
  277. "--exclude-from %s %s %s",
  278. provider.excludeFile, provider.upstreamURL, provider.WorkingDir(),
  279. ),
  280. provider.WorkingDir(),
  281. fmt.Sprintf(
  282. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ "+
  283. "--delete --delete-after --delay-updates --safe-links "+
  284. "--timeout=120 --contimeout=120 -6 --exclude-from %s %s %s",
  285. provider.excludeFile, provider.upstreamURL, provider.WorkingDir(),
  286. ),
  287. )
  288. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  289. So(err, ShouldBeNil)
  290. So(string(loggedContent), ShouldEqual, expectedOutput)
  291. // fmt.Println(string(loggedContent))
  292. })
  293. Convey("Try terminating", func(ctx C) {
  294. scriptContent := `#!/bin/bash
  295. echo $@
  296. sleep 4
  297. exit 0
  298. `
  299. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  300. So(err, ShouldBeNil)
  301. go func() {
  302. err = provider.Run()
  303. ctx.So(err, ShouldNotBeNil)
  304. }()
  305. time.Sleep(1 * time.Second)
  306. err = provider.Terminate()
  307. So(err, ShouldBeNil)
  308. expectedOutput := fmt.Sprintf(
  309. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ --safe-links "+
  310. "--timeout=120 --contimeout=120 --exclude dists/ -6 "+
  311. "--exclude-from %s %s %s\n",
  312. provider.excludeFile, provider.upstreamURL, provider.WorkingDir(),
  313. )
  314. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  315. So(err, ShouldBeNil)
  316. So(string(loggedContent), ShouldEqual, expectedOutput)
  317. // fmt.Println(string(loggedContent))
  318. })
  319. })
  320. }