-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic integration test infrastructure (and new endpoint `/api/v1/…
…version` for testing it) (#741) * Implement '/api/v1/version' * Cleanup and various fixes * Enhance run.sh * Add install_test.go * Add parameter utils.Config for testing handlers * Re-organize TestVersion.go * Rename functions * handling process cleanup properly * Fix missing function renaming * Cleanup the 'retry' logic * Cleanup * Remove unneeded logging code * Logging messages tweaking * Logging message tweaking * Fix logging messages * Use 'const' instead of hardwired numbers * We don't really need retries anymore * Move constant ServerHttpPort to install_test.go * Restore mistakenly removed constant * Add required comments to make the linter happy. * Fix comments and naming to address linter's complaints * Detect Gitea executale version automatically * Remove tests/run.sh, `go test` suffices. * Make `make build` a prerequisite of `make test` * Do not sleep before trying * Speedup the server pinging loop * Use defined const instead of hardwired numbers * Remove redundant error handling * Use a dedicated target for running code.gitea.io/tests * Do not make 'test' depend on 'build' target * Rectify the excluded package list * Remove redundant 'exit 1' * Change the API to allow passing test.T to test handlers * Make testing.T an embedded field * Use assert.Equal to comparing results * Add copyright info * Parametrized logging output * Use tmpdir instead * Eliminate redundant casting * Remove unneeded variable * Fix last commit * Add missing copyright info * Replace fmt.Fprintf with fmt.Fprint * rename the xtest to integration-test * Use Symlink instead of hard-link for cross-device linking * Turn debugging logs on * Follow the existing framework for APIs * Output logs only if test.v is true * Re-order import statements * Enhance the error message * Fix comment which breaks the linter's rule * Rename 'integration-test' to 'e2e-test' for saving keystrokes * Add comment to avoid possible confusion * Rename tests -> integration-tests Also change back the Makefile to use `make integration-test`. * Use tests/integration for now * tests/integration -> integrations Slightly flattened directory hierarchy is better. * Update Makefile accordingly * Fix a missing change in Makefile * govendor update code.gitea.io/sdk/gitea * Fix comment of struct fields * Fix conditional nonsense * Fix missing updates regarding version string changes * Make variable naming more consistent * Check http status code * Rectify error messages
- Loading branch information
Showing
8 changed files
with
341 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// 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 integration | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"os/user" | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
"code.gitea.io/gitea/integrations/internal/utils" | ||
) | ||
|
||
// The HTTP port listened by the Gitea server. | ||
const ServerHTTPPort = "3001" | ||
|
||
const _RetryLimit = 10 | ||
|
||
func makeSimpleSettings(user, workdir, port string) map[string][]string { | ||
return map[string][]string{ | ||
"db_type": {"SQLite3"}, | ||
"db_host": {"localhost"}, | ||
"db_path": {workdir + "data/gitea.db"}, | ||
"app_name": {"Gitea: Git with a cup of tea"}, | ||
"repo_root_path": {workdir + "repositories"}, | ||
"run_user": {user}, | ||
"domain": {"localhost"}, | ||
"ssh_port": {"22"}, | ||
"http_port": {port}, | ||
"app_url": {"http://localhost:" + port}, | ||
"log_root_path": {workdir + "log"}, | ||
} | ||
} | ||
|
||
func install(t *utils.T) error { | ||
var r *http.Response | ||
var err error | ||
|
||
for i := 1; i <= _RetryLimit; i++ { | ||
|
||
r, err = http.Get("http://:" + ServerHTTPPort + "/") | ||
if err == nil { | ||
fmt.Fprintln(os.Stderr) | ||
break | ||
} | ||
|
||
// Give the server some amount of time to warm up. | ||
time.Sleep(100 * time.Millisecond) | ||
fmt.Fprint(os.Stderr, ".") | ||
} | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
defer r.Body.Close() | ||
|
||
_user, err := user.Current() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
path, err := filepath.Abs(t.Config.WorkDir) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
settings := makeSimpleSettings(_user.Username, path, ServerHTTPPort) | ||
r, err = http.PostForm("http://:"+ServerHTTPPort+"/install", settings) | ||
if err != nil { | ||
return err | ||
} | ||
defer r.Body.Close() | ||
|
||
if r.StatusCode != http.StatusOK { | ||
return fmt.Errorf("'/install': %s", r.Status) | ||
} | ||
return nil | ||
} | ||
|
||
func TestInstall(t *testing.T) { | ||
conf := utils.Config{ | ||
Program: "../gitea", | ||
WorkDir: "", | ||
Args: []string{"web", "--port", ServerHTTPPort}, | ||
LogFile: os.Stderr, | ||
} | ||
|
||
if err := utils.New(t, &conf).RunTest(install); err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// 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 integration | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
"code.gitea.io/gitea/integrations/internal/utils" | ||
"code.gitea.io/sdk/gitea" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func version(t *utils.T) error { | ||
var err error | ||
|
||
path, err := filepath.Abs(t.Config.Program) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cmd := exec.Command(path, "--version") | ||
out, err := cmd.Output() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fields := strings.Fields(string(out)) | ||
if !strings.HasPrefix(string(out), "Gitea version") { | ||
return fmt.Errorf("unexpected version string '%s' of the gitea executable", out) | ||
} | ||
|
||
expected := fields[2] | ||
|
||
var r *http.Response | ||
r, err = http.Get("http://:" + ServerHTTPPort + "/api/v1/version") | ||
if err != nil { | ||
return err | ||
} | ||
defer r.Body.Close() | ||
|
||
if r.StatusCode != http.StatusOK { | ||
return fmt.Errorf("'/api/v1/version': %s\n", r.Status) | ||
} | ||
|
||
var v gitea.ServerVersion | ||
|
||
dec := json.NewDecoder(r.Body) | ||
if err := dec.Decode(&v); err != nil { | ||
return err | ||
} | ||
|
||
actual := v.Version | ||
|
||
log.Printf("Actual: \"%s\" Expected: \"%s\"\n", actual, expected) | ||
assert.Equal(t, expected, actual) | ||
|
||
return nil | ||
} | ||
|
||
func TestVersion(t *testing.T) { | ||
conf := utils.Config{ | ||
Program: "../gitea", | ||
WorkDir: "", | ||
Args: []string{"web", "--port", ServerHTTPPort}, | ||
LogFile: os.Stderr, | ||
} | ||
|
||
if err := utils.New(t, &conf).RunTest(install, version); err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// 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 misc | ||
|
||
import ( | ||
"code.gitea.io/gitea/modules/context" | ||
"code.gitea.io/gitea/modules/setting" | ||
"code.gitea.io/sdk/gitea" | ||
) | ||
|
||
// Version shows the version of the Gitea server | ||
func Version(ctx *context.APIContext) { | ||
ctx.JSON(200, &gitea.ServerVersion{Version: setting.AppVer}) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters