diff --git a/main.go b/main.go index 8af388e..49c315b 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,7 @@ import ( // Version is the default value that should be overridden in the // build/release process. +// TODO: Actually set this var Version = "dev" func home(w http.ResponseWriter, _ *http.Request) { @@ -39,17 +40,20 @@ func healthz(w http.ResponseWriter, _ *http.Request) { } func createEvent(cfg *libhoney.Config) (*libhoney.Event, error) { - libhoney.UserAgentAddition = fmt.Sprintf("buildevents/%s", Version) - libhoney.UserAgentAddition += fmt.Sprintf(" (%s)", "GitLab-CI") + libhoney.UserAgentAddition = fmt.Sprintf("buildevents/%s (GitLab-CI)", Version) if cfg.APIKey == "" { cfg.Transmission = &transmission.WriterSender{} } + // TODO: I thinks this should maybe be not using the default package-level client ev := libhoney.NewEvent() - ev.AddField("ci_provider", "GitLab-CI") - ev.AddField("meta.version", Version) - + ev.Add( + map[string]interface{}{ + "ci_provider": "GitLab-CI", + "meta.version": Version, + }, + ) return ev, nil } @@ -214,7 +218,7 @@ func handleJob(cfg *libhoney.Config, w http.ResponseWriter, body []byte) { } } -func handleRequest(cfg *libhoney.Config, w http.ResponseWriter, req *http.Request) { +func handleRequest(defaultConfig *libhoney.Config, w http.ResponseWriter, req *http.Request) { if req.Method != http.MethodPost { http.Error(w, "Unsupported method", http.StatusMethodNotAllowed) return @@ -241,6 +245,27 @@ func handleRequest(cfg *libhoney.Config, w http.ResponseWriter, req *http.Reques return } + // Load potential custom query parameters + // e.g. API key, dataset name, and honeycomb host + // TODO: check for additional unsupported query parameters + cfg := &libhoney.Config{} + cfg.APIKey = defaultConfig.APIKey + cfg.Dataset = defaultConfig.Dataset + cfg.APIHost = defaultConfig.APIHost + query := req.URL.Query() + key := query.Get("api_key") + if key != "" { + cfg.APIKey = key + } + dataset := query.Get("dataset") + if dataset != "" { + cfg.Dataset = dataset + } + host := query.Get("api_host") + if host != "" { + cfg.APIHost = host + } + switch eventType { case "Pipeline Hook": log.Println("Received pipeline webhook:", string(body)) diff --git a/main_test.go b/main_test.go index 737ec71..faeb47f 100644 --- a/main_test.go +++ b/main_test.go @@ -1,17 +1,26 @@ package main import ( - "github.com/honeycombio/libhoney-go" + "encoding/json" + "io/ioutil" + "net/http" + "net/http/httptest" "reflect" + "strings" "testing" + "time" + + "github.com/honeycombio/libhoney-go" + "github.com/honeycombio/libhoney-go/transmission" ) func Test_createEvent(t *testing.T) { defer libhoney.Close() var config libhoney.Config - wantedFields := make(map[string]string) - wantedFields["ci_provider"] = "GitLab-CI" - wantedFields["meta.version"] = "dev" + wantedFields := map[string]string{ + "ci_provider": "GitLab-CI", + "meta.version": "dev", + } wantedUserAgentAddition := "buildevents/dev (GitLab-CI)" t.Run("valid event", func(t *testing.T) { got, err := createEvent(&config) @@ -74,3 +83,93 @@ func Test_createTraceFromPipeline(t *testing.T) { }) } } + +func TestRequestHandler(t *testing.T) { + defer libhoney.Close() + var config libhoney.Config + mockSender := &transmission.MockSender{} + config.Transmission = mockSender + tests := []struct { + name string + eventType string + hook interface{} + }{ + { + name: "finished pipeline creates an event", + eventType: "Pipeline Hook", + hook: Pipeline{ + MergeRequest: MergeRequest{ + Iid: 1, + SourceBranch: "feature-branch-1", + SourceProjectID: 1, + }, + ObjectAttributes: PipelineObjectAttributes{ + ID: 1, + Status: "success", + Ref: "main", + Duration: 5, + QueuedDuration: 2, + CreatedAt: time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC), + }, + Project: Project{ + WebURL: "https://gitlab.com/zoidyzoidzoid/sample-gitlab-project", + }, + }, + }, + { + name: "finished job creates an event", + eventType: "Job Hook", + hook: Job{ + PipelineID: 1, + BuildID: 1, + BuildStatus: "success", + BuildName: "build", + Ref: "main", + BuildDuration: 5, + BuildQueuedDuration: 2, + BuildStartedAt: time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC), + Repository: Repository{ + Homepage: "https://gitlab.com/zoidyzoidzoid/sample-gitlab-project", + }, + Runner: Runner{ + Description: "shared-runners-manager-5.gitlab.com", + ID: 380986, + Tags: []string{ + "docker", + "gce", + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + marshalled, err := json.Marshal(tt.hook) + if err != nil { + t.Errorf("unexpected error marshalling request body: %v", err) + } + bodyReader := strings.NewReader(string(marshalled)) + req := httptest.NewRequest(http.MethodPost, "/api/message", bodyReader) + req.Header.Set("X-Gitlab-Event", tt.eventType) + w := httptest.NewRecorder() + handleRequest(&config, w, req) + res := w.Result() + defer res.Body.Close() + data, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Errorf("expected error to be nil got %v", err) + } + wanted := "Thanks!\n" + if string(data) != wanted { + t.Errorf("expected %+v got %+v", wanted, string(data)) + } + // if (err != nil) != tt.wantErr { + // t.Errorf("createTraceFromPipeline() error = %v, wantErr %v", err, tt.wantErr) + // return + // } + // if !reflect.DeepEqual(got, tt.want) { + // t.Errorf("createTraceFromPipeline() = %v, want %v", got, tt.want) + // } + }) + } +}