provider_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. package worker
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "strconv"
  8. "testing"
  9. "time"
  10. . "github.com/smartystreets/goconvey/convey"
  11. )
  12. func TestRsyncProvider(t *testing.T) {
  13. Convey("Rsync Provider should work", t, func() {
  14. tmpDir, err := ioutil.TempDir("", "tunasync")
  15. defer os.RemoveAll(tmpDir)
  16. So(err, ShouldBeNil)
  17. scriptFile := filepath.Join(tmpDir, "myrsync")
  18. tmpFile := filepath.Join(tmpDir, "log_file")
  19. c := rsyncConfig{
  20. name: "tuna",
  21. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  22. rsyncCmd: scriptFile,
  23. workingDir: tmpDir,
  24. logDir: tmpDir,
  25. logFile: tmpFile,
  26. useIPv6: true,
  27. timeout: 100 * time.Second,
  28. interval: 600 * time.Second,
  29. }
  30. provider, err := newRsyncProvider(c)
  31. So(err, ShouldBeNil)
  32. So(provider.Type(), ShouldEqual, provRsync)
  33. So(provider.Name(), ShouldEqual, c.name)
  34. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  35. So(provider.LogDir(), ShouldEqual, c.logDir)
  36. So(provider.LogFile(), ShouldEqual, c.logFile)
  37. So(provider.Interval(), ShouldEqual, c.interval)
  38. So(provider.Timeout(), ShouldEqual, c.timeout)
  39. Convey("When entering a context (auto exit)", func() {
  40. func() {
  41. ctx := provider.EnterContext()
  42. defer provider.ExitContext()
  43. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  44. newWorkingDir := "/srv/mirror/working/tuna"
  45. ctx.Set(_WorkingDirKey, newWorkingDir)
  46. So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
  47. }()
  48. Convey("After context is done", func() {
  49. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  50. })
  51. })
  52. Convey("When entering a context (manually exit)", func() {
  53. ctx := provider.EnterContext()
  54. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  55. newWorkingDir := "/srv/mirror/working/tuna"
  56. ctx.Set(_WorkingDirKey, newWorkingDir)
  57. So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
  58. Convey("After context is done", func() {
  59. provider.ExitContext()
  60. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  61. })
  62. })
  63. Convey("Let's try a run", func() {
  64. scriptContent := `#!/bin/bash
  65. echo "syncing to $(pwd)"
  66. echo $RSYNC_PASSWORD $@
  67. sleep 1
  68. echo "Total file size: 1.33T bytes"
  69. echo "Done"
  70. exit 0
  71. `
  72. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  73. So(err, ShouldBeNil)
  74. targetDir, _ := filepath.EvalSymlinks(provider.WorkingDir())
  75. expectedOutput := fmt.Sprintf(
  76. "syncing to %s\n"+
  77. "%s\n"+
  78. "Total file size: 1.33T bytes\n"+
  79. "Done\n",
  80. targetDir,
  81. fmt.Sprintf(
  82. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ "+
  83. "--delete --delete-after --delay-updates --safe-links "+
  84. "--timeout=120 -6 %s %s",
  85. provider.upstreamURL, provider.WorkingDir(),
  86. ),
  87. )
  88. err = provider.Run(make(chan empty, 1))
  89. So(err, ShouldBeNil)
  90. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  91. So(err, ShouldBeNil)
  92. So(string(loggedContent), ShouldEqual, expectedOutput)
  93. // fmt.Println(string(loggedContent))
  94. So(provider.DataSize(), ShouldEqual, "1.33T")
  95. })
  96. })
  97. Convey("If the rsync program fails", t, func() {
  98. tmpDir, err := ioutil.TempDir("", "tunasync")
  99. defer os.RemoveAll(tmpDir)
  100. So(err, ShouldBeNil)
  101. tmpFile := filepath.Join(tmpDir, "log_file")
  102. Convey("in the rsyncProvider", func() {
  103. c := rsyncConfig{
  104. name: "tuna",
  105. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  106. workingDir: tmpDir,
  107. logDir: tmpDir,
  108. logFile: tmpFile,
  109. extraOptions: []string{"--somethine-invalid"},
  110. interval: 600 * time.Second,
  111. }
  112. provider, err := newRsyncProvider(c)
  113. So(err, ShouldBeNil)
  114. err = provider.Run(make(chan empty, 1))
  115. So(err, ShouldNotBeNil)
  116. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  117. So(err, ShouldBeNil)
  118. So(string(loggedContent), ShouldContainSubstring, "Syntax or usage error")
  119. })
  120. })
  121. }
  122. func TestRsyncProviderWithAuthentication(t *testing.T) {
  123. Convey("Rsync Provider with password should work", t, func() {
  124. tmpDir, err := ioutil.TempDir("", "tunasync")
  125. defer os.RemoveAll(tmpDir)
  126. So(err, ShouldBeNil)
  127. scriptFile := filepath.Join(tmpDir, "myrsync")
  128. tmpFile := filepath.Join(tmpDir, "log_file")
  129. proxyAddr := "127.0.0.1:1233"
  130. c := rsyncConfig{
  131. name: "tuna",
  132. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  133. rsyncCmd: scriptFile,
  134. username: "tunasync",
  135. password: "tunasyncpassword",
  136. workingDir: tmpDir,
  137. extraOptions: []string{"--delete-excluded"},
  138. rsyncTimeoutValue: 30,
  139. rsyncEnv: map[string]string{"RSYNC_PROXY": proxyAddr},
  140. logDir: tmpDir,
  141. logFile: tmpFile,
  142. useIPv4: true,
  143. interval: 600 * time.Second,
  144. }
  145. provider, err := newRsyncProvider(c)
  146. So(err, ShouldBeNil)
  147. So(provider.Name(), ShouldEqual, c.name)
  148. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  149. So(provider.LogDir(), ShouldEqual, c.logDir)
  150. So(provider.LogFile(), ShouldEqual, c.logFile)
  151. So(provider.Interval(), ShouldEqual, c.interval)
  152. Convey("Let's try a run", func() {
  153. scriptContent := `#!/bin/bash
  154. echo "syncing to $(pwd)"
  155. echo $USER $RSYNC_PASSWORD $RSYNC_PROXY $@
  156. sleep 1
  157. echo "Done"
  158. exit 0
  159. `
  160. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  161. So(err, ShouldBeNil)
  162. targetDir, _ := filepath.EvalSymlinks(provider.WorkingDir())
  163. expectedOutput := fmt.Sprintf(
  164. "syncing to %s\n"+
  165. "%s\n"+
  166. "Done\n",
  167. targetDir,
  168. fmt.Sprintf(
  169. "%s %s %s -aHvh --no-o --no-g --stats --exclude .~tmp~/ "+
  170. "--delete --delete-after --delay-updates --safe-links "+
  171. "--timeout=30 -4 --delete-excluded %s %s",
  172. provider.username, provider.password, proxyAddr,
  173. provider.upstreamURL, provider.WorkingDir(),
  174. ),
  175. )
  176. err = provider.Run(make(chan empty, 1))
  177. So(err, ShouldBeNil)
  178. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  179. So(err, ShouldBeNil)
  180. So(string(loggedContent), ShouldEqual, expectedOutput)
  181. // fmt.Println(string(loggedContent))
  182. })
  183. })
  184. }
  185. func TestRsyncProviderWithOverriddenOptions(t *testing.T) {
  186. Convey("Rsync Provider with overridden options should work", t, func() {
  187. tmpDir, err := ioutil.TempDir("", "tunasync")
  188. defer os.RemoveAll(tmpDir)
  189. So(err, ShouldBeNil)
  190. scriptFile := filepath.Join(tmpDir, "myrsync")
  191. tmpFile := filepath.Join(tmpDir, "log_file")
  192. c := rsyncConfig{
  193. name: "tuna",
  194. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  195. rsyncCmd: scriptFile,
  196. workingDir: tmpDir,
  197. rsyncNeverTimeout: true,
  198. overriddenOptions: []string{"-aHvh", "--no-o", "--no-g", "--stats"},
  199. extraOptions: []string{"--delete-excluded"},
  200. logDir: tmpDir,
  201. logFile: tmpFile,
  202. useIPv6: true,
  203. interval: 600 * time.Second,
  204. }
  205. provider, err := newRsyncProvider(c)
  206. So(err, ShouldBeNil)
  207. So(provider.Name(), ShouldEqual, c.name)
  208. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  209. So(provider.LogDir(), ShouldEqual, c.logDir)
  210. So(provider.LogFile(), ShouldEqual, c.logFile)
  211. So(provider.Interval(), ShouldEqual, c.interval)
  212. Convey("Let's try a run", func() {
  213. scriptContent := `#!/bin/bash
  214. echo "syncing to $(pwd)"
  215. echo $@
  216. sleep 1
  217. echo "Done"
  218. exit 0
  219. `
  220. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  221. So(err, ShouldBeNil)
  222. targetDir, _ := filepath.EvalSymlinks(provider.WorkingDir())
  223. expectedOutput := fmt.Sprintf(
  224. "syncing to %s\n"+
  225. "-aHvh --no-o --no-g --stats -6 --delete-excluded %s %s\n"+
  226. "Done\n",
  227. targetDir,
  228. provider.upstreamURL,
  229. provider.WorkingDir(),
  230. )
  231. err = provider.Run(make(chan empty, 1))
  232. So(err, ShouldBeNil)
  233. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  234. So(err, ShouldBeNil)
  235. So(string(loggedContent), ShouldEqual, expectedOutput)
  236. // fmt.Println(string(loggedContent))
  237. })
  238. })
  239. }
  240. func TestCmdProvider(t *testing.T) {
  241. Convey("Command Provider should work", t, func(ctx C) {
  242. tmpDir, err := ioutil.TempDir("", "tunasync")
  243. defer os.RemoveAll(tmpDir)
  244. So(err, ShouldBeNil)
  245. scriptFile := filepath.Join(tmpDir, "cmd.sh")
  246. tmpFile := filepath.Join(tmpDir, "log_file")
  247. c := cmdConfig{
  248. name: "tuna-cmd",
  249. upstreamURL: "http://mirrors.tuna.moe/",
  250. command: "bash " + scriptFile,
  251. workingDir: tmpDir,
  252. logDir: tmpDir,
  253. logFile: tmpFile,
  254. interval: 600 * time.Second,
  255. env: map[string]string{
  256. "AOSP_REPO_BIN": "/usr/local/bin/repo",
  257. },
  258. }
  259. provider, err := newCmdProvider(c)
  260. So(err, ShouldBeNil)
  261. So(provider.Type(), ShouldEqual, provCommand)
  262. So(provider.Name(), ShouldEqual, c.name)
  263. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  264. So(provider.LogDir(), ShouldEqual, c.logDir)
  265. So(provider.LogFile(), ShouldEqual, c.logFile)
  266. So(provider.Interval(), ShouldEqual, c.interval)
  267. Convey("Let's try to run a simple command", func() {
  268. scriptContent := `#!/bin/bash
  269. echo $TUNASYNC_WORKING_DIR
  270. echo $TUNASYNC_MIRROR_NAME
  271. echo $TUNASYNC_UPSTREAM_URL
  272. echo $TUNASYNC_LOG_FILE
  273. echo $AOSP_REPO_BIN
  274. `
  275. expectedOutput := fmt.Sprintf(
  276. "%s\n%s\n%s\n%s\n%s\n",
  277. provider.WorkingDir(),
  278. provider.Name(),
  279. provider.upstreamURL,
  280. provider.LogFile(),
  281. "/usr/local/bin/repo",
  282. )
  283. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  284. So(err, ShouldBeNil)
  285. readedScriptContent, err := ioutil.ReadFile(scriptFile)
  286. So(err, ShouldBeNil)
  287. So(readedScriptContent, ShouldResemble, []byte(scriptContent))
  288. err = provider.Run(make(chan empty, 1))
  289. So(err, ShouldBeNil)
  290. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  291. So(err, ShouldBeNil)
  292. So(string(loggedContent), ShouldEqual, expectedOutput)
  293. })
  294. Convey("If a command fails", func() {
  295. scriptContent := `exit 1`
  296. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  297. So(err, ShouldBeNil)
  298. readedScriptContent, err := ioutil.ReadFile(scriptFile)
  299. So(err, ShouldBeNil)
  300. So(readedScriptContent, ShouldResemble, []byte(scriptContent))
  301. err = provider.Run(make(chan empty, 1))
  302. So(err, ShouldNotBeNil)
  303. })
  304. Convey("If a long job is killed", func(ctx C) {
  305. scriptContent := `#!/bin/bash
  306. sleep 10
  307. `
  308. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  309. So(err, ShouldBeNil)
  310. started := make(chan empty, 1)
  311. go func() {
  312. err := provider.Run(started)
  313. ctx.So(err, ShouldNotBeNil)
  314. }()
  315. <-started
  316. So(provider.IsRunning(), ShouldBeTrue)
  317. time.Sleep(1 * time.Second)
  318. err = provider.Terminate()
  319. So(err, ShouldBeNil)
  320. })
  321. })
  322. Convey("Command Provider without log file should work", t, func(ctx C) {
  323. tmpDir, err := ioutil.TempDir("", "tunasync")
  324. defer os.RemoveAll(tmpDir)
  325. So(err, ShouldBeNil)
  326. c := cmdConfig{
  327. name: "run-ls",
  328. upstreamURL: "http://mirrors.tuna.moe/",
  329. command: "ls",
  330. workingDir: tmpDir,
  331. logDir: tmpDir,
  332. logFile: "/dev/null",
  333. interval: 600 * time.Second,
  334. }
  335. provider, err := newCmdProvider(c)
  336. So(err, ShouldBeNil)
  337. So(provider.IsMaster(), ShouldEqual, false)
  338. So(provider.ZFS(), ShouldBeNil)
  339. So(provider.Type(), ShouldEqual, provCommand)
  340. So(provider.Name(), ShouldEqual, c.name)
  341. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  342. So(provider.LogDir(), ShouldEqual, c.logDir)
  343. So(provider.LogFile(), ShouldEqual, c.logFile)
  344. So(provider.Interval(), ShouldEqual, c.interval)
  345. Convey("Run the command", func() {
  346. err = provider.Run(make(chan empty, 1))
  347. So(err, ShouldBeNil)
  348. })
  349. })
  350. Convey("Command Provider with RegExprs should work", t, func(ctx C) {
  351. tmpDir, err := ioutil.TempDir("", "tunasync")
  352. defer os.RemoveAll(tmpDir)
  353. So(err, ShouldBeNil)
  354. tmpFile := filepath.Join(tmpDir, "log_file")
  355. c := cmdConfig{
  356. name: "run-uptime",
  357. upstreamURL: "http://mirrors.tuna.moe/",
  358. command: "uptime",
  359. failOnMatch: "",
  360. sizePattern: "",
  361. workingDir: tmpDir,
  362. logDir: tmpDir,
  363. logFile: tmpFile,
  364. interval: 600 * time.Second,
  365. }
  366. Convey("when fail-on-match regexp matches", func() {
  367. c.failOnMatch = `[a-z]+`
  368. provider, err := newCmdProvider(c)
  369. So(err, ShouldBeNil)
  370. err = provider.Run(make(chan empty, 1))
  371. So(err, ShouldNotBeNil)
  372. So(provider.DataSize(), ShouldBeEmpty)
  373. })
  374. Convey("when fail-on-match regexp does not match", func() {
  375. c.failOnMatch = `load average_`
  376. provider, err := newCmdProvider(c)
  377. So(err, ShouldBeNil)
  378. err = provider.Run(make(chan empty, 1))
  379. So(err, ShouldBeNil)
  380. })
  381. Convey("when fail-on-match regexp meets /dev/null", func() {
  382. c.failOnMatch = `load average_`
  383. c.logFile = "/dev/null"
  384. provider, err := newCmdProvider(c)
  385. So(err, ShouldBeNil)
  386. err = provider.Run(make(chan empty, 1))
  387. So(err, ShouldNotBeNil)
  388. })
  389. Convey("when size-pattern regexp matches", func() {
  390. c.sizePattern = `load average: ([\d\.]+)`
  391. provider, err := newCmdProvider(c)
  392. So(err, ShouldBeNil)
  393. err = provider.Run(make(chan empty, 1))
  394. So(err, ShouldBeNil)
  395. So(provider.DataSize(), ShouldNotBeEmpty)
  396. _, err = strconv.ParseFloat(provider.DataSize(), 32)
  397. So(err, ShouldBeNil)
  398. })
  399. Convey("when size-pattern regexp does not match", func() {
  400. c.sizePattern = `load ave: ([\d\.]+)`
  401. provider, err := newCmdProvider(c)
  402. So(err, ShouldBeNil)
  403. err = provider.Run(make(chan empty, 1))
  404. So(err, ShouldBeNil)
  405. So(provider.DataSize(), ShouldBeEmpty)
  406. })
  407. Convey("when size-pattern regexp meets /dev/null", func() {
  408. c.sizePattern = `load ave: ([\d\.]+)`
  409. c.logFile = "/dev/null"
  410. provider, err := newCmdProvider(c)
  411. So(err, ShouldBeNil)
  412. err = provider.Run(make(chan empty, 1))
  413. So(err, ShouldNotBeNil)
  414. So(provider.DataSize(), ShouldBeEmpty)
  415. })
  416. })
  417. }
  418. func TestTwoStageRsyncProvider(t *testing.T) {
  419. Convey("TwoStageRsync Provider should work", t, func(ctx C) {
  420. tmpDir, err := ioutil.TempDir("", "tunasync")
  421. defer os.RemoveAll(tmpDir)
  422. So(err, ShouldBeNil)
  423. scriptFile := filepath.Join(tmpDir, "myrsync")
  424. tmpFile := filepath.Join(tmpDir, "log_file")
  425. c := twoStageRsyncConfig{
  426. name: "tuna-two-stage-rsync",
  427. upstreamURL: "rsync://mirrors.tuna.moe/",
  428. stage1Profile: "debian",
  429. rsyncCmd: scriptFile,
  430. workingDir: tmpDir,
  431. logDir: tmpDir,
  432. logFile: tmpFile,
  433. useIPv6: true,
  434. excludeFile: tmpFile,
  435. rsyncTimeoutValue: 30,
  436. extraOptions: []string{"--delete-excluded", "--cache"},
  437. username: "hello",
  438. password: "world",
  439. }
  440. provider, err := newTwoStageRsyncProvider(c)
  441. So(err, ShouldBeNil)
  442. So(provider.Type(), ShouldEqual, provTwoStageRsync)
  443. So(provider.Name(), ShouldEqual, c.name)
  444. So(provider.WorkingDir(), ShouldEqual, c.workingDir)
  445. So(provider.LogDir(), ShouldEqual, c.logDir)
  446. So(provider.LogFile(), ShouldEqual, c.logFile)
  447. So(provider.Interval(), ShouldEqual, c.interval)
  448. Convey("Try a command", func(ctx C) {
  449. scriptContent := `#!/bin/bash
  450. echo "syncing to $(pwd)"
  451. echo $@
  452. sleep 1
  453. echo "Done"
  454. exit 0
  455. `
  456. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  457. So(err, ShouldBeNil)
  458. err = provider.Run(make(chan empty, 2))
  459. So(err, ShouldBeNil)
  460. targetDir, _ := filepath.EvalSymlinks(provider.WorkingDir())
  461. expectedOutput := fmt.Sprintf(
  462. "syncing to %s\n"+
  463. "%s\n"+
  464. "Done\n"+
  465. "syncing to %s\n"+
  466. "%s\n"+
  467. "Done\n",
  468. targetDir,
  469. fmt.Sprintf(
  470. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ --safe-links "+
  471. "--exclude dists/ --timeout=30 -6 "+
  472. "--exclude-from %s %s %s",
  473. provider.excludeFile, provider.upstreamURL, provider.WorkingDir(),
  474. ),
  475. targetDir,
  476. fmt.Sprintf(
  477. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ "+
  478. "--delete --delete-after --delay-updates --safe-links "+
  479. "--delete-excluded --cache --timeout=30 -6 --exclude-from %s %s %s",
  480. provider.excludeFile, provider.upstreamURL, provider.WorkingDir(),
  481. ),
  482. )
  483. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  484. So(err, ShouldBeNil)
  485. So(string(loggedContent), ShouldEqual, expectedOutput)
  486. // fmt.Println(string(loggedContent))
  487. })
  488. Convey("Try terminating", func(ctx C) {
  489. scriptContent := `#!/bin/bash
  490. echo $@
  491. sleep 10
  492. exit 0
  493. `
  494. err = ioutil.WriteFile(scriptFile, []byte(scriptContent), 0755)
  495. So(err, ShouldBeNil)
  496. started := make(chan empty, 2)
  497. go func() {
  498. err := provider.Run(started)
  499. ctx.So(err, ShouldNotBeNil)
  500. }()
  501. <-started
  502. So(provider.IsRunning(), ShouldBeTrue)
  503. time.Sleep(1 * time.Second)
  504. err = provider.Terminate()
  505. So(err, ShouldBeNil)
  506. expectedOutput := fmt.Sprintf(
  507. "-aHvh --no-o --no-g --stats --exclude .~tmp~/ --safe-links "+
  508. "--exclude dists/ --timeout=30 -6 "+
  509. "--exclude-from %s %s %s\n",
  510. provider.excludeFile, provider.upstreamURL, provider.WorkingDir(),
  511. )
  512. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  513. So(err, ShouldBeNil)
  514. So(string(loggedContent), ShouldStartWith, expectedOutput)
  515. // fmt.Println(string(loggedContent))
  516. })
  517. })
  518. Convey("If the rsync program fails", t, func(ctx C) {
  519. tmpDir, err := ioutil.TempDir("", "tunasync")
  520. defer os.RemoveAll(tmpDir)
  521. So(err, ShouldBeNil)
  522. tmpFile := filepath.Join(tmpDir, "log_file")
  523. Convey("in the twoStageRsyncProvider", func() {
  524. c := twoStageRsyncConfig{
  525. name: "tuna-two-stage-rsync",
  526. upstreamURL: "rsync://0.0.0.1/",
  527. stage1Profile: "debian",
  528. workingDir: tmpDir,
  529. logDir: tmpDir,
  530. logFile: tmpFile,
  531. excludeFile: tmpFile,
  532. }
  533. provider, err := newTwoStageRsyncProvider(c)
  534. So(err, ShouldBeNil)
  535. err = provider.Run(make(chan empty, 2))
  536. So(err, ShouldNotBeNil)
  537. loggedContent, err := ioutil.ReadFile(provider.LogFile())
  538. So(err, ShouldBeNil)
  539. So(string(loggedContent), ShouldContainSubstring, "Error in socket I/O")
  540. })
  541. })
  542. }