cgroup_test.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package worker
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. "testing"
  8. "time"
  9. . "github.com/smartystreets/goconvey/convey"
  10. )
  11. func TestCgroup(t *testing.T) {
  12. Convey("Cgroup Should Work", t, func(ctx C) {
  13. tmpDir, err := ioutil.TempDir("", "tunasync")
  14. defer os.RemoveAll(tmpDir)
  15. So(err, ShouldBeNil)
  16. cmdScript := filepath.Join(tmpDir, "cmd.sh")
  17. daemonScript := filepath.Join(tmpDir, "daemon.sh")
  18. tmpFile := filepath.Join(tmpDir, "log_file")
  19. bgPidfile := filepath.Join(tmpDir, "bg.pid")
  20. c := cmdConfig{
  21. name: "tuna-cgroup",
  22. upstreamURL: "http://mirrors.tuna.moe/",
  23. command: cmdScript + " " + daemonScript,
  24. workingDir: tmpDir,
  25. logDir: tmpDir,
  26. logFile: tmpFile,
  27. interval: 600 * time.Second,
  28. env: map[string]string{
  29. "BG_PIDFILE": bgPidfile,
  30. },
  31. }
  32. cmdScriptContent := `#!/bin/bash
  33. redirect-std() {
  34. [[ -t 0 ]] && exec </dev/null
  35. [[ -t 1 ]] && exec >/dev/null
  36. [[ -t 2 ]] && exec 2>/dev/null
  37. }
  38. # close all non-std* fds
  39. close-fds() {
  40. eval exec {3..255}\>\&-
  41. }
  42. # full daemonization of external command with setsid
  43. daemonize() {
  44. (
  45. redirect-std
  46. cd /
  47. close-fds
  48. exec setsid "$@"
  49. ) &
  50. }
  51. echo $$
  52. daemonize $@
  53. sleep 5
  54. `
  55. daemonScriptContent := `#!/bin/bash
  56. echo $$ > $BG_PIDFILE
  57. sleep 30
  58. `
  59. err = ioutil.WriteFile(cmdScript, []byte(cmdScriptContent), 0755)
  60. So(err, ShouldBeNil)
  61. err = ioutil.WriteFile(daemonScript, []byte(daemonScriptContent), 0755)
  62. So(err, ShouldBeNil)
  63. provider, err := newCmdProvider(c)
  64. So(err, ShouldBeNil)
  65. initCgroup("/sys/fs/cgroup")
  66. cg := newCgroupHook(provider, "/sys/fs/cgroup", "tunasync")
  67. provider.AddHook(cg)
  68. err = cg.preExec()
  69. So(err, ShouldBeNil)
  70. go func() {
  71. err = provider.Run()
  72. ctx.So(err, ShouldNotBeNil)
  73. }()
  74. time.Sleep(1 * time.Second)
  75. // Deamon should be started
  76. daemonPidBytes, err := ioutil.ReadFile(bgPidfile)
  77. So(err, ShouldBeNil)
  78. daemonPid := strings.Trim(string(daemonPidBytes), " \n")
  79. logger.Debug("daemon pid: %s", daemonPid)
  80. procDir := filepath.Join("/proc", daemonPid)
  81. _, err = os.Stat(procDir)
  82. So(err, ShouldBeNil)
  83. err = provider.Terminate()
  84. So(err, ShouldBeNil)
  85. // Deamon won't be killed
  86. _, err = os.Stat(procDir)
  87. So(err, ShouldBeNil)
  88. // Deamon can be killed by cgroup killer
  89. cg.postExec()
  90. _, err = os.Stat(procDir)
  91. So(os.IsNotExist(err), ShouldBeTrue)
  92. })
  93. Convey("Rsync Memory Should Be Limited", t, func() {
  94. tmpDir, err := ioutil.TempDir("", "tunasync")
  95. defer os.RemoveAll(tmpDir)
  96. So(err, ShouldBeNil)
  97. scriptFile := filepath.Join(tmpDir, "myrsync")
  98. tmpFile := filepath.Join(tmpDir, "log_file")
  99. c := rsyncConfig{
  100. name: "tuna-cgroup",
  101. upstreamURL: "rsync://rsync.tuna.moe/tuna/",
  102. rsyncCmd: scriptFile,
  103. workingDir: tmpDir,
  104. logDir: tmpDir,
  105. logFile: tmpFile,
  106. useIPv6: true,
  107. interval: 600 * time.Second,
  108. }
  109. provider, err := newRsyncProvider(c)
  110. So(err, ShouldBeNil)
  111. initCgroup("/sys/fs/cgroup")
  112. cg := newCgroupHook(provider, "/sys/fs/cgroup", "tunasync")
  113. provider.AddHook(cg)
  114. cg.preExec()
  115. //if cgSubsystem == "memory" {
  116. // memoLimit, err := ioutil.ReadFile(filepath.Join(cg.basePath, "memory", cg.baseGroup, provider.Name(), "memory.limit_in_bytes"))
  117. // So(err, ShouldBeNil)
  118. // So(strings.Trim(string(memoLimit), "\n"), ShouldEqual, strconv.Itoa(512*1024*1024))
  119. //}
  120. cg.postExec()
  121. })
  122. }