Fork to maintain patches against the official gitea for https://code.ceondo.com https://github.com/go-gitea/gitea

utils.go 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package utils
  5. import (
  6. "errors"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "log"
  11. "net/http"
  12. "os"
  13. "os/exec"
  14. "path/filepath"
  15. "syscall"
  16. "testing"
  17. )
  18. // T wraps testing.T and the configurations of the testing instance.
  19. type T struct {
  20. *testing.T
  21. Config *Config
  22. }
  23. // New create an instance of T
  24. func New(t *testing.T, c *Config) *T {
  25. return &T{T: t, Config: c}
  26. }
  27. // Config Settings of the testing program
  28. type Config struct {
  29. // The executable path of the tested program.
  30. Program string
  31. // Working directory prepared for the tested program.
  32. // If empty, a directory named with random suffixes is picked, and created under the platform-dependent default temporary directory.
  33. // The directory will be removed when the test finishes.
  34. WorkDir string
  35. // Command-line arguments passed to the tested program.
  36. Args []string
  37. // Where to redirect the stdout/stderr to. For debugging purposes.
  38. LogFile *os.File
  39. }
  40. func redirect(cmd *exec.Cmd, f *os.File) error {
  41. stdout, err := cmd.StdoutPipe()
  42. if err != nil {
  43. return err
  44. }
  45. stderr, err := cmd.StderrPipe()
  46. if err != nil {
  47. return err
  48. }
  49. go io.Copy(f, stdout)
  50. go io.Copy(f, stderr)
  51. return nil
  52. }
  53. // RunTest Helper function for setting up a running Gitea server for functional testing and then gracefully terminating it.
  54. func (t *T) RunTest(tests ...func(*T) error) (err error) {
  55. if t.Config.Program == "" {
  56. return errors.New("Need input file")
  57. }
  58. path, err := filepath.Abs(t.Config.Program)
  59. if err != nil {
  60. return err
  61. }
  62. workdir := t.Config.WorkDir
  63. if workdir == "" {
  64. workdir, err = ioutil.TempDir(os.TempDir(), "gitea_tests-")
  65. if err != nil {
  66. return err
  67. }
  68. defer os.RemoveAll(workdir)
  69. }
  70. newpath := filepath.Join(workdir, filepath.Base(path))
  71. if err := os.Symlink(path, newpath); err != nil {
  72. return err
  73. }
  74. log.Printf("Starting the server: %s args:%s workdir:%s", newpath, t.Config.Args, workdir)
  75. cmd := exec.Command(newpath, t.Config.Args...)
  76. cmd.Dir = workdir
  77. if t.Config.LogFile != nil && testing.Verbose() {
  78. if err := redirect(cmd, t.Config.LogFile); err != nil {
  79. return err
  80. }
  81. }
  82. if err := cmd.Start(); err != nil {
  83. return err
  84. }
  85. log.Println("Server started.")
  86. defer func() {
  87. // Do not early return. We have to call Wait anyway.
  88. _ = cmd.Process.Signal(syscall.SIGTERM)
  89. if _err := cmd.Wait(); _err != nil {
  90. if _err.Error() != "signal: terminated" {
  91. err = _err
  92. return
  93. }
  94. }
  95. log.Println("Server exited")
  96. }()
  97. for _, fn := range tests {
  98. if err := fn(t); err != nil {
  99. return err
  100. }
  101. }
  102. // Note that the return value 'err' may be updated by the 'defer' statement before despite it's returning nil here.
  103. return nil
  104. }
  105. // GetAndPost provides a convenient helper function for testing an HTTP endpoint with GET and POST method.
  106. // The function sends GET first and then POST with the given form.
  107. func GetAndPost(url string, form map[string][]string) error {
  108. var err error
  109. var r *http.Response
  110. r, err = http.Get(url)
  111. if err != nil {
  112. return err
  113. }
  114. defer r.Body.Close()
  115. if r.StatusCode != http.StatusOK {
  116. return fmt.Errorf("GET '%s': %s", url, r.Status)
  117. }
  118. r, err = http.PostForm(url, form)
  119. if err != nil {
  120. return err
  121. }
  122. defer r.Body.Close()
  123. if r.StatusCode != http.StatusOK {
  124. return fmt.Errorf("POST '%s': %s", url, r.Status)
  125. }
  126. return nil
  127. }