Skip to content

Commit

Permalink
chore: add app test (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
freak12techno authored Jul 9, 2024
1 parent 0e8ab2b commit 6d0d642
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 10 deletions.
16 changes: 16 additions & 0 deletions assets/config-invalid-listen-address.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
listen-address = "invalid"

[log]
level = "debug"

[[chains]]
name = "sentinel"
lcd-endpoint = "https://api.sentinel.quokkastake.io"
denoms = [
{ denom = "udvpn", display-denom = "dvpn", coingecko-currency = "sentinel" }
]

[[chains.wallets]]
address = "sent1nuf0cf3y787y0caqfrf6qhsaz2uhf4nph4yegw"
group = "restake"
name = "sentinel-restake"
12 changes: 6 additions & 6 deletions assets/config-valid.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
level = "debug"

[[chains]]
name = "sentinel"
lcd-endpoint = "https://api.sentinel.quokkastake.io"
name = "chain"
lcd-endpoint = "https://example.com"
denoms = [
{ denom = "udvpn", display-denom = "dvpn", coingecko-currency = "sentinel" }
{ denom = "uatom", display-denom = "atom", coingecko-currency = "cosmos" }
]

[[chains.wallets]]
address = "sent1nuf0cf3y787y0caqfrf6qhsaz2uhf4nph4yegw"
group = "restake"
name = "sentinel-restake"
address = "address"
group = "group"
name = "name"
27 changes: 23 additions & 4 deletions pkg/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

"go.opentelemetry.io/otel/attribute"

"github.com/google/uuid"
Expand All @@ -27,8 +28,8 @@ type App struct {
Config *config.Config
Logger zerolog.Logger
Queriers []types.Querier

Tracer trace.Tracer
Server *http.Server
Tracer trace.Tracer
}

func NewApp(filesystem fs.FS, configPath string, version string) *App {
Expand All @@ -51,25 +52,39 @@ func NewApp(filesystem fs.FS, configPath string, version string) *App {
queriersPkg.NewUptimeQuerier(tracer),
}

server := &http.Server{Addr: appConfig.ListenAddress, Handler: nil}

return &App{
Config: appConfig,
Logger: log,
Queriers: queriers,
Tracer: tracer,
Server: server,
}
}

func (a *App) Start() {
otelHandler := otelhttp.NewHandler(http.HandlerFunc(a.Handler), "prometheus")
http.Handle("/metrics", otelHandler)
handler := http.NewServeMux()
handler.Handle("/metrics", otelHandler)
handler.HandleFunc("/healthcheck", a.Healthcheck)
a.Server.Handler = handler

a.Logger.Info().Str("addr", a.Config.ListenAddress).Msg("Listening")
err := http.ListenAndServe(a.Config.ListenAddress, nil)

err := a.Server.ListenAndServe()
if err != nil {
a.Logger.Panic().Err(err).Msg("Could not start application")
}
}

func (a *App) Stop() {
a.Logger.Info().Str("addr", a.Config.ListenAddress).Msg("Shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_ = a.Server.Shutdown(ctx)
}

func (a *App) Handler(w http.ResponseWriter, r *http.Request) {
requestStart := time.Now()
requestID := uuid.New().String()
Expand Down Expand Up @@ -119,3 +134,7 @@ func (a *App) Handler(w http.ResponseWriter, r *http.Request) {
Float64("request-time", time.Since(requestStart).Seconds()).
Msg("Request processed")
}

func (a *App) Healthcheck(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("ok"))
}
112 changes: 112 additions & 0 deletions pkg/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package pkg

import (
"io"
"main/assets"
"main/pkg/fs"
"net/http"
"testing"
"time"

"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

//nolint:paralleltest // disabled
func TestAppLoadConfigError(t *testing.T) {
defer func() {
if r := recover(); r == nil {
require.Fail(t, "Expected to have a panic here!")
}
}()

filesystem := &fs.TestFS{}

app := NewApp(filesystem, "not-found-config.toml", "1.2.3")
app.Start()
}

//nolint:paralleltest // disabled
func TestAppLoadConfigInvalid(t *testing.T) {
defer func() {
if r := recover(); r == nil {
require.Fail(t, "Expected to have a panic here!")
}
}()

filesystem := &fs.TestFS{}

app := NewApp(filesystem, "config-invalid.toml", "1.2.3")
app.Start()
}

//nolint:paralleltest // disabled
func TestAppFailToStart(t *testing.T) {
defer func() {
if r := recover(); r == nil {
require.Fail(t, "Expected to have a panic here!")
}
}()

filesystem := &fs.TestFS{}

app := NewApp(filesystem, "config-invalid-listen-address.toml", "1.2.3")
app.Start()
}

//nolint:paralleltest // disabled
func TestAppStopOperation(t *testing.T) {
filesystem := &fs.TestFS{}

app := NewApp(filesystem, "config-valid.toml", "1.2.3")
app.Stop()
assert.True(t, true)
}

//nolint:paralleltest // disabled
func TestAppLoadConfigOk(t *testing.T) {
filesystem := &fs.TestFS{}

app := NewApp(filesystem, "config-valid.toml", "1.2.3")
go app.Start()

for {
request, err := http.Get("http://localhost:9550/healthcheck")
_ = request.Body.Close()
if err == nil {
break
}

time.Sleep(time.Millisecond * 100)
}

httpmock.Activate()
defer httpmock.DeactivateAndReset()

httpmock.RegisterResponder(
"GET",
"https://example.com/cosmos/bank/v1beta1/balances/address",
httpmock.NewBytesResponder(200, assets.GetBytesOrPanic("balance.json")),
)

httpmock.RegisterResponder(
"GET",
"https://api.coingecko.com/api/v3/simple/price?ids=cosmos&vs_currencies=usd",
httpmock.NewBytesResponder(200, assets.GetBytesOrPanic("coingecko.json")),
)

httpmock.RegisterResponder("GET", "http://localhost:9550/healthcheck", httpmock.InitialTransport.RoundTrip)
httpmock.RegisterResponder("GET", "http://localhost:9550/metrics", httpmock.InitialTransport.RoundTrip)

response, err := http.Get("http://localhost:9550/metrics")
require.NoError(t, err)
require.NotEmpty(t, response)

body, err := io.ReadAll(response.Body)
require.NoError(t, err)
require.NotEmpty(t, body)

err = response.Body.Close()
require.NoError(t, err)
}

0 comments on commit 6d0d642

Please sign in to comment.