docker_test.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package worker
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "testing"
  8. "time"
  9. units "github.com/docker/go-units"
  10. "github.com/codeskyblue/go-sh"
  11. . "github.com/smartystreets/goconvey/convey"
  12. )
  13. func cmdRun(p string, args []string) {
  14. cmd := exec.Command(p, args...)
  15. out, err := cmd.CombinedOutput()
  16. if err != nil {
  17. logger.Debugf("cmdRun failed %s", err)
  18. return
  19. }
  20. logger.Debugf("cmdRun: ", string(out))
  21. }
  22. func getDockerByName(name string) (string, error) {
  23. // docker ps -f 'name=$name' --format '{{.Names}}'
  24. out, err := sh.Command(
  25. "docker", "ps", "-a",
  26. "--filter", "name="+name,
  27. "--format", "{{.Names}}",
  28. ).Output()
  29. if err == nil {
  30. logger.Debugf("docker ps: '%s'", string(out))
  31. }
  32. return string(out), err
  33. }
  34. func TestDocker(t *testing.T) {
  35. Convey("Docker Should Work", t, func(ctx C) {
  36. tmpDir, err := os.MkdirTemp("", "tunasync")
  37. defer os.RemoveAll(tmpDir)
  38. So(err, ShouldBeNil)
  39. cmdScript := filepath.Join(tmpDir, "cmd.sh")
  40. tmpFile := filepath.Join(tmpDir, "log_file")
  41. expectedOutput := "HELLO_WORLD"
  42. c := cmdConfig{
  43. name: "tuna-docker",
  44. upstreamURL: "http://mirrors.tuna.moe/",
  45. command: "/bin/cmd.sh",
  46. workingDir: tmpDir,
  47. logDir: tmpDir,
  48. logFile: tmpFile,
  49. interval: 600 * time.Second,
  50. env: map[string]string{
  51. "TEST_CONTENT": expectedOutput,
  52. },
  53. }
  54. cmdScriptContent := `#!/bin/sh
  55. echo ${TEST_CONTENT}
  56. sleep 20
  57. `
  58. err = os.WriteFile(cmdScript, []byte(cmdScriptContent), 0755)
  59. So(err, ShouldBeNil)
  60. provider, err := newCmdProvider(c)
  61. So(err, ShouldBeNil)
  62. d := &dockerHook{
  63. emptyHook: emptyHook{
  64. provider: provider,
  65. },
  66. image: "alpine:3.8",
  67. volumes: []string{
  68. fmt.Sprintf("%s:%s", cmdScript, "/bin/cmd.sh"),
  69. },
  70. memoryLimit: 512 * units.MiB,
  71. }
  72. provider.AddHook(d)
  73. So(provider.Docker(), ShouldNotBeNil)
  74. err = d.preExec()
  75. So(err, ShouldBeNil)
  76. cmdRun("docker", []string{"images"})
  77. exitedErr := make(chan error, 1)
  78. go func() {
  79. err = provider.Run(make(chan empty, 1))
  80. logger.Debugf("provider.Run() exited")
  81. if err != nil {
  82. logger.Errorf("provider.Run() failed: %v", err)
  83. }
  84. exitedErr <- err
  85. }()
  86. // Wait for docker running
  87. for wait := 0; wait < 8; wait++ {
  88. names, err := getDockerByName(d.Name())
  89. So(err, ShouldBeNil)
  90. if names != "" {
  91. break
  92. }
  93. time.Sleep(1 * time.Second)
  94. }
  95. // cmdRun("ps", []string{"aux"})
  96. // assert container running
  97. names, err := getDockerByName(d.Name())
  98. So(err, ShouldBeNil)
  99. So(names, ShouldEqual, d.Name()+"\n")
  100. err = provider.Terminate()
  101. So(err, ShouldBeNil)
  102. // cmdRun("ps", []string{"aux"})
  103. <-exitedErr
  104. // container should be terminated and removed
  105. names, err = getDockerByName(d.Name())
  106. So(err, ShouldBeNil)
  107. So(names, ShouldEqual, "")
  108. // check log content
  109. loggedContent, err := os.ReadFile(provider.LogFile())
  110. So(err, ShouldBeNil)
  111. So(string(loggedContent), ShouldEqual, expectedOutput+"\n")
  112. d.postExec()
  113. })
  114. }