Skip to content

Commit

Permalink
Merge pull request #49 from bmf-san/feature/improve-test-coverage
Browse files Browse the repository at this point in the history
Improve test coverage
  • Loading branch information
bmf-san authored Jun 23, 2024
2 parents 104b7a2 + e4b6e04 commit 23effd8
Show file tree
Hide file tree
Showing 18 changed files with 362 additions and 214 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.22.3' ]
go-version: [ '1.22.4' ]
steps:
- uses: actions/checkout@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-dry-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.22.3' ]
go-version: [ '1.22.4' ]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.22.3' ]
go-version: [ '1.22.4' ]
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.22.3' ]
go-version: [ '1.22.4' ]
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -21,3 +21,13 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: Run test
run: make test
- name: Run coverage
run: make test-cover OUT=coverage.out
- name: Upload coverage to Codecov
uses: codecov/[email protected]
with:
fail_ci_if_error: true
file: ./coverage.out
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true

2 changes: 1 addition & 1 deletion _examples/backend1/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.22.3-alpine
FROM golang:1.22.4-alpine

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion _examples/backend1/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/bmf-san/gondola/_examples/backend

go 1.22.3
go 1.22.4
2 changes: 1 addition & 1 deletion _examples/backend2/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.22.3-alpine
FROM golang:1.22.4-alpine

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion _examples/backend2/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/bmf-san/gondola/_examples/backend

go 1.22.3
go 1.22.4
2 changes: 1 addition & 1 deletion _examples/proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.22.3-alpine
FROM golang:1.22.4-alpine

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion _examples/proxy/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ upstreams:
target: http://backend1:8081 # backend1 is the name of the container
- host_name: backend2.local
target: http://backend2:8082 # backend2 is the name of the container
log_level: 0 # Debug:-4 Info:0 Warn:4 Error:8
log_level: 0 # Debug:-4 Info:0 Warn:4 Error:8
22 changes: 22 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package gondola

import (
"bytes"
"errors"
"reflect"
"strings"
"testing"
"testing/iotest"
)

func TestIsEnableTLS(t *testing.T) {
Expand Down Expand Up @@ -106,3 +109,22 @@ log_level: -4
}
}
}

func TestLoadReadAllError(t *testing.T) {
reader := iotest.ErrReader(errors.New("error"))
var c Config
_, err := c.Load(reader)
if err == nil {
t.Fatalf("Expected error, got nil")
}
}

func TestLoadUnmarshalError(t *testing.T) {
data := ":\n"
reader := bytes.NewBufferString(data)
var c Config
_, err := c.Load(reader)
if err == nil {
t.Fatalf("Expected error, got nil")
}
}
42 changes: 42 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package gondola

import (
"fmt"
"net/http"
)

// Gondola is a proxy server.
type Gondola struct {
config *Config
server *http.Server
}

// ConfigLoadError is an error that occurs when loading the configuration.
type ConfigLoadError struct {
Err error
}

// Error implements the error interface.
func (e *ConfigLoadError) Error() string {
return fmt.Sprintf("error loading config: %v", e.Err)
}

// Unwrap implements the errors.Wrapper interface.
func (e *ConfigLoadError) Unwrap() error {
return e.Err
}

// ProxyServerError is an error that occurs when creating the server.
type ProxyServerError struct {
Err error
}

// Error implements the error interface.
func (e *ProxyServerError) Error() string {
return fmt.Sprintf("error creating server: %v", e.Err)
}

// Unwrap implements the errors.Wrapper interface.
func (e *ProxyServerError) Unwrap() error {
return e.Err
}
23 changes: 23 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package gondola

import "testing"

func TestConfigLoadError(t *testing.T) {
err := &ConfigLoadError{}
if err.Error() != "error loading config: <nil>" {
t.Errorf("Expected error loading config: <nil>, got %v", err.Error())
}
if err.Unwrap() != nil {
t.Errorf("Expected nil, got %v", err.Unwrap())
}
}

func TestProxyServerError(t *testing.T) {
err := &ProxyServerError{}
if err.Error() != "error creating server: <nil>" {
t.Errorf("Expected error creating server: <nil>, got %v", err.Error())
}
if err.Unwrap() != nil {
t.Errorf("Expected nil, got %v", err.Unwrap())
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/bmf-san/gondola

go 1.22.3
go 1.22.4

require (
github.com/google/uuid v1.6.0
Expand Down
75 changes: 75 additions & 0 deletions gondola.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package gondola

import (
"context"
"fmt"
"io"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)

// NewGondola returns a new Gondola.
func NewGondola(r io.Reader) (*Gondola, error) {
cfg := &Config{}
c, err := cfg.Load(r)
if err != nil {
return nil, &ConfigLoadError{Err: err}
}

s, err := newServer(c)
if err != nil {
return nil, &ProxyServerError{Err: err}
}

return &Gondola{
config: c,
server: s,
}, nil
}

// TODO: Need to dynamically load a configuration file. For now, we will limit the implementation to just loading the file at startup.
// Run starts the proxy server.
func (g *Gondola) Run() error {
logger := NewLogger(g.config.LogLevel)
slog.SetDefault(logger.Logger)

// TODO: do health check for upstreams.

ch := make(chan error, 1)
go func() {
if g.config.Proxy.IsEnableTLS() {
slog.Info(fmt.Sprintf("Running server on port %s with TLS...", g.config.Proxy.Port))
if err := g.server.ListenAndServeTLS(g.config.Proxy.TLSCertPath, g.config.Proxy.TLSKeyPath); err != http.ErrServerClosed {
ch <- err
}
} else {
slog.Info("Running server on port " + g.config.Proxy.Port + "...")
if err := g.server.ListenAndServe(); err != http.ErrServerClosed {
ch <- err
}
}
}()
e := <-ch
if e != nil {
return e
}

q := make(chan os.Signal, 1)
signal.Notify(q, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
defer signal.Stop(q)
<-q

ctx, cancel := context.WithTimeout(context.Background(), time.Duration(g.config.Proxy.ShutdownTimeout)*time.Millisecond)
defer cancel()
if err := g.server.Shutdown(ctx); err != nil {
slog.Error(fmt.Sprintf("Shutdown failed: %v", err))
return err
}

slog.Info("Server stopped gracefully")
return nil
}
Loading

0 comments on commit 23effd8

Please sign in to comment.