Handle updates via git webhooks

This commit is contained in:
simon987
2019-01-13 14:58:52 -05:00
parent a2b5de0e01
commit ef333b6b25
17 changed files with 514 additions and 70 deletions

104
test/api_git_test.go Normal file
View File

@@ -0,0 +1,104 @@
package test
import (
"bytes"
"crypto"
"crypto/hmac"
"encoding/hex"
"fmt"
"net/http"
"src/task_tracker/api"
"src/task_tracker/config"
"testing"
)
func TestWebHookNoSignature(t *testing.T) {
r := Post("/git/receivehook", api.GitPayload{})
fmt.Println(r.StatusCode)
if r.StatusCode != 403 {
t.Error()
}
}
func TestWebHookInvalidSignature(t *testing.T) {
req, _ := http.NewRequest("POST", "http://"+config.Cfg.ServerAddr+"/git/receivehook", nil)
req.Header.Add("X-Hub-Signature", "invalid")
client := http.Client{}
r, _ := client.Do(req)
fmt.Println(r.StatusCode)
if r.StatusCode != 403 {
t.Error()
}
}
func TestWebHookDontUpdateVersion(t *testing.T) {
resp := createProject(api.CreateProjectRequest{
Name: "My version should not be updated",
Version: "old",
GitRepo: "username/not_this_one",
})
body := []byte(`{"ref": "refs/heads/master", "after": "new", "repository": {"full_name": "username/repo_name"}}`)
bodyReader := bytes.NewReader(body)
mac := hmac.New(crypto.SHA1.New, config.Cfg.WebHookSecret)
mac.Write(body)
signature := hex.EncodeToString(mac.Sum(nil))
signature = "sha1=" + signature
req, _ := http.NewRequest("POST", "http://"+config.Cfg.ServerAddr+"/git/receivehook", bodyReader)
req.Header.Add("X-Hub-Signature", signature)
client := http.Client{}
r, _ := client.Do(req)
if r.StatusCode != 200 {
t.Error()
}
getResp, _ := getProject(resp.Id)
if getResp.Project.Version != "old" {
t.Error()
}
}
func TestWebHookUpdateVersion(t *testing.T) {
resp := createProject(api.CreateProjectRequest{
Name: "My version should be updated",
Version: "old",
GitRepo: "username/repo_name",
})
body := []byte(`{"ref": "refs/heads/master", "after": "new", "repository": {"full_name": "username/repo_name"}}`)
bodyReader := bytes.NewReader(body)
mac := hmac.New(crypto.SHA1.New, config.Cfg.WebHookSecret)
mac.Write(body)
signature := hex.EncodeToString(mac.Sum(nil))
signature = "sha1=" + signature
req, _ := http.NewRequest("POST", "http://"+config.Cfg.ServerAddr+"/git/receivehook", bodyReader)
req.Header.Add("X-Hub-Signature", signature)
client := http.Client{}
r, _ := client.Do(req)
if r.StatusCode != 200 {
t.Error()
}
getResp, _ := getProject(resp.Id)
if getResp.Project.Version != "new" {
t.Error()
}
}

View File

@@ -13,7 +13,8 @@ func TestCreateGetProject(t *testing.T) {
resp := createProject(api.CreateProjectRequest{
Name: "Test name",
GitUrl: "http://github.com/test/test",
CloneUrl: "http://github.com/test/test",
GitRepo: "drone/webhooktest",
Version: "Test Version",
Priority: 123,
})
@@ -41,7 +42,10 @@ func TestCreateGetProject(t *testing.T) {
t.Error()
}
if getResp.Project.GitUrl != "http://github.com/test/test" {
if getResp.Project.CloneUrl != "http://github.com/test/test" {
t.Error()
}
if getResp.Project.GitRepo != "drone/webhooktest" {
t.Error()
}
if getResp.Project.Priority != 123 {
@@ -57,7 +61,7 @@ func TestCreateProjectInvalid(t *testing.T) {
}
}
func TestCreateDuplicateProject(t *testing.T) {
func TestCreateDuplicateProjectName(t *testing.T) {
createProject(api.CreateProjectRequest{
Name: "duplicate name",
})
@@ -74,6 +78,25 @@ func TestCreateDuplicateProject(t *testing.T) {
}
}
func TestCreateDuplicateProjectRepo(t *testing.T) {
createProject(api.CreateProjectRequest{
Name: "different name",
GitRepo: "user/same",
})
resp := createProject(api.CreateProjectRequest{
Name: "but same repo",
GitRepo: "user/same",
})
if resp.Ok != false {
t.Error()
}
if len(resp.Message) <= 0 {
t.Error()
}
}
func TestGetProjectNotFound(t *testing.T) {
getResp, r := getProject(12345)

View File

@@ -13,9 +13,9 @@ func TestCreateTaskValid(t *testing.T) {
//Make sure there is always a project for id:1
createProject(api.CreateProjectRequest{
Name: "Some Test name",
Version: "Test Version",
GitUrl: "http://github.com/test/test",
Name: "Some Test name",
Version: "Test Version",
CloneUrl: "http://github.com/test/test",
})
resp := createTask(api.CreateTaskRequest{
@@ -68,7 +68,8 @@ func TestCreateGetTask(t *testing.T) {
resp := createProject(api.CreateProjectRequest{
Name: "My project",
Version: "1.0",
GitUrl: "http://github.com/test/test",
CloneUrl: "http://github.com/test/test",
GitRepo: "myrepo",
Priority: 999,
})
@@ -108,7 +109,7 @@ func TestCreateGetTask(t *testing.T) {
if taskResp.Task.Project.Version != "1.0" {
t.Error()
}
if taskResp.Task.Project.GitUrl != "http://github.com/test/test" {
if taskResp.Task.Project.CloneUrl != "http://github.com/test/test" {
t.Error()
}
}
@@ -118,13 +119,15 @@ func createTasks(prefix string) (int64, int64) {
lowP := createProject(api.CreateProjectRequest{
Name: prefix + "low",
Version: "1.0",
GitUrl: "http://github.com/test/test",
CloneUrl: "http://github.com/test/test",
GitRepo: prefix + "low1",
Priority: 1,
})
highP := createProject(api.CreateProjectRequest{
Name: prefix + "high",
Version: "1.0",
GitUrl: "http://github.com/test/test",
CloneUrl: "http://github.com/test/test",
GitRepo: prefix + "high1",
Priority: 999,
})
createTask(api.CreateTaskRequest{

View File

@@ -15,21 +15,27 @@ func TestCreateGetWorker(t *testing.T) {
resp, r := createWorker(api.CreateWorkerRequest{})
if r.StatusCode != 200 {
t.Fail()
t.Error()
}
if resp.Ok != true {
t.Fail()
t.Error()
}
getResp, r := getWorker(resp.WorkerId.String())
if r.StatusCode != 200 {
t.Fail()
t.Error()
}
if resp.WorkerId != getResp.Worker.Id {
t.Error()
}
if resp.WorkerId != getResp.Worker.Id {
t.Fail()
if len(getResp.Worker.Identity.RemoteAddr) <= 0 {
t.Error()
}
if len(getResp.Worker.Identity.UserAgent) <= 0 {
t.Error()
}
}
@@ -38,10 +44,10 @@ func TestGetWorkerNotFound(t *testing.T) {
resp, r := getWorker("8bfc0ccd-d5ce-4dc5-a235-3a7ae760d9c6")
if r.StatusCode != 404 {
t.Fail()
t.Error()
}
if resp.Ok != false {
t.Fail()
t.Error()
}
}
@@ -50,13 +56,13 @@ func TestGetWorkerInvalid(t *testing.T) {
resp, r := getWorker("invalid-uuid")
if r.StatusCode != 400 {
t.Fail()
t.Error()
}
if resp.Ok != false {
t.Fail()
t.Error()
}
if len(resp.Message) <= 0 {
t.Fail()
t.Error()
}
}

View File

@@ -3,3 +3,8 @@ server:
database:
conn_str : "user=task_tracker dbname=task_tracker_test sslmode=disable"
git:
webhook_secret: "very_secret_secret"
webhook_hash: "sha1"
webhook_sig_header: "X-Hub-Signature"

View File

@@ -1 +0,0 @@
../schema.sql

48
test/schema.sql Normal file
View File

@@ -0,0 +1,48 @@
DROP TABLE IF EXISTS workerIdentity, Worker, Project, Task;
DROP TYPE IF EXISTS Status;
CREATE TYPE status as ENUM (
'new',
'failed',
'closed'
);
CREATE TABLE workerIdentity
(
id SERIAL PRIMARY KEY,
remote_addr TEXT,
user_agent TEXT,
UNIQUE (remote_addr)
);
CREATE TABLE worker
(
id TEXT PRIMARY KEY,
created INTEGER,
identity INTEGER REFERENCES workerIdentity (id)
);
CREATE TABLE project
(
id SERIAL PRIMARY KEY,
priority INTEGER DEFAULT 0,
name TEXT UNIQUE,
clone_url TEXT,
git_repo TEXT UNIQUE,
version TEXT
);
CREATE TABLE task
(
id SERIAL PRIMARY KEY,
priority INTEGER DEFAULT 0,
project INTEGER REFERENCES project (id),
assignee TEXT REFERENCES worker (id),
retries INTEGER DEFAULT 0,
max_retries INTEGER,
status Status DEFAULT 'new',
recipe TEXT
);