Skip to content

Commit

Permalink
ci(workflows): initial support for test (#14)
Browse files Browse the repository at this point in the history
* ci(workflows): initial support for test

Add a Makefile task to locally run it

* test: create new tests for vault tasks using vault test server

* build: add new dependancies for testing purpose

* test: correct healthcheck test and prom test + Makefile issue

---------

Co-authored-by: Guillaume LEGRAIN <[email protected]>
  • Loading branch information
Lujeni and SoulKyu authored Jun 10, 2024
1 parent 2d3b69d commit 3334cc5
Show file tree
Hide file tree
Showing 7 changed files with 2,069 additions and 192 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
20 changes: 19 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,36 @@

VERSION ?= $(shell ./hack/get-version.sh)

.PHONY:fmt vet build
GO_IMG ?= golang:alpine3.20@sha256:1b455a3f7786e5765dbeb4f7ab32a36cdc0c3f4ddd35406606df612dc6e3269b

.PHONY: fmt vet build unit-test

DOCKER_CMD = docker run --rm -v $(PWD):/app -w /app ${GO_IMG}

## verify: Format code
fmt:
go fmt ./...

## verify: Verify code
vet: fmt
go vet ./...

## build: Build binary
build: vet
go build

## unit-test: Run unit tests
unit-test:
ifeq ($(USE_DOCKER), 1)
@${DOCKER_CMD} go test -v ./...
else
go test -v ./... ;
endif

## build-image: Build image
build-docker: vet
docker build -t numberly/vault-db-injector:${VERSION} .

## build-image: Push image
push-docker: build-docker
docker push numberly/vault-db-injector:${VERSION}
281 changes: 246 additions & 35 deletions go.mod

Large diffs are not rendered by default.

1,546 changes: 1,441 additions & 105 deletions go.sum

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package healthcheck

import (
"context"
"io"
"net/http"
"net/http/httptest"
"strings"
"sync/atomic"
"testing"
"time"

Expand All @@ -32,11 +30,13 @@ func TestHealthzHandler(t *testing.T) {
// logger.Initialize(yourConfigHere)

service := NewService()
service.RegisterHandlers()

mux := http.NewServeMux()
mux.HandleFunc("/healthz", service.healthzHandler)

req := httptest.NewRequest("GET", "/healthz", nil)
w := httptest.NewRecorder()
http.DefaultServeMux.ServeHTTP(w, req)
mux.ServeHTTP(w, req)

if w.Code != http.StatusNoContent {
t.Errorf("expected status %d, got %d", http.StatusNoContent, w.Code)
Expand All @@ -48,12 +48,15 @@ func TestReadyzHandler(t *testing.T) {
// Assuming your logger has been initialized elsewhere or doing it here if needed

service := NewService()
service.RegisterHandlers()

mux := http.NewServeMux()
mux.HandleFunc("/readyz", service.readyzHandler())
mux.HandleFunc("/healthz", service.healthzHandler)

// Test when the service is ready
reqReady := httptest.NewRequest("GET", "/readyz", nil)
wReady := httptest.NewRecorder()
http.DefaultServeMux.ServeHTTP(wReady, reqReady)
mux.ServeHTTP(wReady, reqReady)

if wReady.Code != http.StatusNoContent {
t.Errorf("expected status %d when ready, got %d", http.StatusNoContent, wReady.Code)
Expand All @@ -63,58 +66,26 @@ func TestReadyzHandler(t *testing.T) {
service.isReady.Store(false)
reqNotReady := httptest.NewRequest("GET", "/readyz", nil)
wNotReady := httptest.NewRecorder()
http.DefaultServeMux.ServeHTTP(wNotReady, reqNotReady)
mux.ServeHTTP(wNotReady, reqNotReady)

if wNotReady.Code != http.StatusServiceUnavailable {
t.Errorf("expected status %d when not ready, got %d", http.StatusServiceUnavailable, wNotReady.Code)
}
}

// TestServiceStart remains largely the same as previously described.
func TestServiceStart(t *testing.T) {
ctx := context.TODO()
// Assuming your logger has been initialized elsewhere or doing it here if needed
initTestLogger()
service := &Service{
isReady: &atomic.Value{},
server: &http.Server{
Addr: "127.0.0.1:8888", // Use an ephemeral port
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
log: logger.GetLogger(), // Assuming logger has been initialized
}
service.isReady.Store(true)

service.RegisterHandlers()
// Starting the service in a goroutine since it's blocking
go func() {
if err := service.Start(ctx, stopChan); err != nil {
t.Errorf("failed to start service: %v", err)
}
}()

// Wait a short period to let the server start
time.Sleep(1000 * time.Millisecond)

// Make a request to ensure the server is up and running
resp, err := http.Get("http://" + service.server.Addr + "/healthz")
if err != nil {
t.Fatalf("failed to make request to the server: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusNoContent {
bodyBytes, _ := io.ReadAll(resp.Body)
t.Errorf("expected status %d, got %d, body: %s", http.StatusNoContent, resp.StatusCode, string(bodyBytes))
}
}

func TestServiceShutdown(t *testing.T) {
initTestLogger() // Ensure the logger is initialized if it's required for the test

// Create a new service and register handlers
service := NewService()

mux := http.NewServeMux()
service.server = &http.Server{
Addr: "127.0.0.1:8888",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
service.RegisterHandlers()

// Create a cancelable context
Expand Down
23 changes: 19 additions & 4 deletions pkg/prometheus/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestRunMetrics(t *testing.T) {
// Initialize the metric service
service := prom.NewService(successChan)

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

go service.RunMetrics()
Expand All @@ -46,13 +46,28 @@ func TestRunMetrics(t *testing.T) {
t.Fatal("Test timed out waiting for RunMetrics to send success signal")
}

serverURL := "http://" + "127.0.0.1:8080" + "/metrics"
resp, err := http.Get(serverURL)
serverURL := "http://127.0.0.1:8080/metrics"
var resp *http.Response
var err error

// Retry mechanism
for i := 0; i < 5; i++ {
resp, err = http.Get(serverURL)
if err == nil {
break
}
time.Sleep(500 * time.Millisecond)
}

if err != nil {
t.Fatalf("Failed to make a request to the server: %v", err)
}
defer resp.Body.Close()

bodyBytes, _ := io.ReadAll(resp.Body)
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatalf("Failed to read response body: %v", err)
}

assert.Equal(t, http.StatusOK, resp.StatusCode, "Expected status %d, got %d, body: %s", http.StatusOK, resp.StatusCode, string(bodyBytes))
}
Loading

0 comments on commit 3334cc5

Please sign in to comment.