2
0

provider_test.go 17 KB

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