140 lines
3.3 KiB
Go
140 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"math"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.rootprojects.org/root/gitdeploy/internal/jobs"
|
|
"git.rootprojects.org/root/gitdeploy/internal/options"
|
|
"git.rootprojects.org/root/gitdeploy/internal/webhooks"
|
|
|
|
"github.com/go-chi/chi"
|
|
)
|
|
|
|
var server *httptest.Server
|
|
var runOpts *options.ServerConfig
|
|
var debounceDelay time.Duration
|
|
var jobDelay time.Duration
|
|
var logDir string
|
|
|
|
func init() {
|
|
tmpDir, _ := ioutil.TempDir("", "gitdeploy-*")
|
|
runOpts = &options.ServerConfig{
|
|
//Addr: "localhost:4483",
|
|
ScriptsPath: "./testdata",
|
|
LogDir: "./test-logs/api",
|
|
TmpDir: tmpDir,
|
|
DebounceDelay: 25 * time.Millisecond,
|
|
DefaultMaxJobTime: 5 * time.Second, // very short
|
|
StaleJobAge: 5 * time.Minute,
|
|
StaleLogAge: 5 * time.Minute,
|
|
ExpiredLogAge: 10 * time.Minute,
|
|
}
|
|
logDir, _ = filepath.Abs(runOpts.LogDir)
|
|
|
|
r := chi.NewRouter()
|
|
server = httptest.NewServer(r)
|
|
runOpts.Addr = server.Listener.Addr().String()
|
|
RouteStopped(r, runOpts)
|
|
|
|
os.Setenv("GIT_DEPLOY_TEST_WAIT", "0.1")
|
|
debounceDelay = 50 * time.Millisecond
|
|
jobDelay = 250 * time.Millisecond
|
|
|
|
jobs.Start(runOpts)
|
|
|
|
//server.Close()
|
|
}
|
|
|
|
func ToUnixSeconds(t time.Time) float64 {
|
|
// 1614236182.651912345
|
|
secs := float64(t.Unix()) // 1614236182
|
|
nanos := float64(t.Nanosecond()) / 1_000_000_000.0 // 0.651912345
|
|
//nanos := (float64(t.UnixNano()) - secs) / 1_000_000_000.0 // 0.651912345
|
|
|
|
// in my case I want to truncate the precision to milliseconds
|
|
nanos = math.Round((10000 * nanos) / 10000) // 0.6519
|
|
|
|
s := secs + nanos // 1614236182.651912345
|
|
return s
|
|
}
|
|
|
|
func TestCallback(t *testing.T) {
|
|
// TODO use full API request with local webhook
|
|
t7 := time.Now().Add(-40 * time.Second)
|
|
r7 := "ef1234abcd"
|
|
|
|
// skip debounce
|
|
hook := webhooks.Ref{
|
|
Timestamp: t7,
|
|
RepoID: "git.example.com/owner/repo",
|
|
HTTPSURL: "https://git.example.com/owner/repo.git",
|
|
Rev: r7,
|
|
RefName: "master",
|
|
RefType: "branch",
|
|
Owner: "owner",
|
|
Repo: "repo",
|
|
}
|
|
// , _ := json.MarshallIndent(&hook , "", " ")
|
|
jobs.Debounce(hook)
|
|
/*
|
|
body := bytes.NewReader(hook)
|
|
r := httptest.NewRequest("POST", "/api/local/webhook", body)
|
|
*/
|
|
|
|
// TODO use callback or chan chan to avoid sleeps?
|
|
time.Sleep(debounceDelay)
|
|
t.Log("sleep so job can finish")
|
|
time.Sleep(jobDelay)
|
|
time.Sleep(jobDelay)
|
|
|
|
// TODO test that the API gives this back to us
|
|
urlRevID := hook.GetURLSafeRevID()
|
|
|
|
s := ToUnixSeconds(t7.Add(-1 * time.Second))
|
|
|
|
// TODO needs auth
|
|
reqURL := fmt.Sprintf(
|
|
"http://%s/api/admin/logs/%s?since=%f",
|
|
runOpts.Addr, string(urlRevID), s,
|
|
)
|
|
resp, err := http.Get(reqURL)
|
|
if nil != err {
|
|
t.Errorf("HTTP response error: %s\n%#v", reqURL, err)
|
|
return
|
|
}
|
|
|
|
job := &jobs.Job{}
|
|
b, _ := ioutil.ReadAll(resp.Body)
|
|
if err := json.Unmarshal(b, job); nil != err {
|
|
t.Errorf(
|
|
"response decode error: %d %s\n%#v\n%#v",
|
|
resp.StatusCode, reqURL, resp.Header, err,
|
|
)
|
|
return
|
|
}
|
|
|
|
if len(job.Logs) < 3 {
|
|
t.Errorf("too few logs: %s\n%s\n%#v", reqURL, string(b), job)
|
|
return
|
|
}
|
|
|
|
if nil == job.Report || len(job.Report.Results) < 1 {
|
|
t.Errorf("too few results: %s\n%#v", reqURL, job)
|
|
return
|
|
}
|
|
|
|
if nil == job.ExitCode || 0 != *job.ExitCode {
|
|
t.Errorf("non-zero exit code: %s\n%#v", reqURL, job)
|
|
return
|
|
}
|
|
}
|