aboutsummaryrefslogtreecommitdiffstats
path: root/integrations/internal/utils/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'integrations/internal/utils/utils.go')
-rw-r--r--integrations/internal/utils/utils.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/integrations/internal/utils/utils.go b/integrations/internal/utils/utils.go
new file mode 100644
index 0000000000..511fa478b9
--- /dev/null
+++ b/integrations/internal/utils/utils.go
@@ -0,0 +1,125 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package utils
+
+import (
+ "errors"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "syscall"
+ "testing"
+)
+
+// T wraps testing.T and the configurations of the testing instance.
+type T struct {
+ *testing.T
+ Config *Config
+}
+
+// New create an instance of T
+func New(t *testing.T, c *Config) *T {
+ return &T{T: t, Config: c}
+}
+
+// Config Settings of the testing program
+type Config struct {
+ // The executable path of the tested program.
+ Program string
+ // Working directory prepared for the tested program.
+ // If empty, a directory named with random suffixes is picked, and created under the platform-dependent default temporary directory.
+ // The directory will be removed when the test finishes.
+ WorkDir string
+ // Command-line arguments passed to the tested program.
+ Args []string
+
+ // Where to redirect the stdout/stderr to. For debugging purposes.
+ LogFile *os.File
+}
+
+func redirect(cmd *exec.Cmd, f *os.File) error {
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return err
+ }
+
+ stderr, err := cmd.StderrPipe()
+ if err != nil {
+ return err
+ }
+
+ go io.Copy(f, stdout)
+ go io.Copy(f, stderr)
+ return nil
+}
+
+// RunTest Helper function for setting up a running Gitea server for functional testing and then gracefully terminating it.
+func (t *T) RunTest(tests ...func(*T) error) (err error) {
+ if t.Config.Program == "" {
+ return errors.New("Need input file")
+ }
+
+ path, err := filepath.Abs(t.Config.Program)
+ if err != nil {
+ return err
+ }
+
+ workdir := t.Config.WorkDir
+ if workdir == "" {
+ workdir, err = ioutil.TempDir(os.TempDir(), "gitea_tests-")
+ if err != nil {
+ return err
+ }
+ defer os.RemoveAll(workdir)
+ }
+
+ newpath := filepath.Join(workdir, filepath.Base(path))
+ if err := os.Symlink(path, newpath); err != nil {
+ return err
+ }
+
+ log.Printf("Starting the server: %s args:%s workdir:%s", newpath, t.Config.Args, workdir)
+
+ cmd := exec.Command(newpath, t.Config.Args...)
+ cmd.Dir = workdir
+
+ if t.Config.LogFile != nil && testing.Verbose() {
+ if err := redirect(cmd, t.Config.LogFile); err != nil {
+ return err
+ }
+ }
+
+ if err := cmd.Start(); err != nil {
+ return err
+ }
+
+ log.Println("Server started.")
+
+ defer func() {
+ // Do not early return. We have to call Wait anyway.
+ _ = cmd.Process.Signal(syscall.SIGTERM)
+
+ if _err := cmd.Wait(); _err != nil {
+ if _err.Error() != "signal: terminated" {
+ err = _err
+ return
+ }
+ }
+
+ log.Println("Server exited")
+ }()
+
+ for _, fn := range tests {
+ if err := fn(t); err != nil {
+ return err
+ }
+ }
+
+ // Note that the return value 'err' may be updated by the 'defer' statement before despite it's returning nil here.
+ return nil
+}