Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #29 from im-kulikov/test-coverage
Browse files Browse the repository at this point in the history
Increase test coverage and
  • Loading branch information
im-kulikov authored Nov 27, 2019
2 parents 8eb7c60 + f4856d0 commit ec0871c
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 9 deletions.
10 changes: 5 additions & 5 deletions web/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ type (
)

const (
// ErrEmptyGRPC is raised when called NewGRPCService
// ErrEmptyGRPCServer is raised when called NewGRPCService
// or gRPC methods with empty grpc.Server.
ErrEmptyGRPC = internal.Error("empty gRPC server")
ErrEmptyGRPCServer = internal.Error("empty gRPC server")

// ErrEmptyGRPCAddress is raised when passed empty address to NewGRPCService.
ErrEmptyGRPCAddress = internal.Error("empty gRPC address")
Expand Down Expand Up @@ -65,7 +65,7 @@ func GRPCShutdownTimeout(v time.Duration) GRPCOption {
// If something went wrong it returns an error.
func NewGRPCService(serve *grpc.Server, opts ...GRPCOption) (Service, error) {
if serve == nil {
return nil, ErrEmptyGRPC
return nil, ErrEmptyGRPCServer
}

s := &gRPC{
Expand Down Expand Up @@ -96,7 +96,7 @@ func (g *gRPC) Start() error {
)

if g.server == nil {
return g.catch(ErrEmptyHTTPServer)
return g.catch(ErrEmptyGRPCServer)
} else if lis, err = net.Listen(g.network, g.address); err != nil {
return g.catch(err)
}
Expand All @@ -113,7 +113,7 @@ func (g *gRPC) Start() error {
// Stop tries to stop gRPC service.
func (g *gRPC) Stop() error {
if g.server == nil {
return g.catch(ErrEmptyHTTPServer)
return g.catch(ErrEmptyGRPCServer)
}

g.server.GracefulStop()
Expand Down
59 changes: 59 additions & 0 deletions web/grpc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package web

import (
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"net"
"testing"
)

func TestGRPCService(t *testing.T) {
t.Run("should set network", func(t *testing.T) {
serve, err := NewGRPCService(
grpc.NewServer(),
GRPCSkipErrors(),
GRPCListenAddress(":8080"),
GRPCListenNetwork("test"))
require.NoError(t, err)

s, ok := serve.(*gRPC)
require.True(t, ok)
require.Equal(t, "test", s.network)
})

t.Run("should fail on empty address", func(t *testing.T) {
serve, err := NewGRPCService(grpc.NewServer())
require.Nil(t, serve)
require.EqualError(t, err, ErrEmptyGRPCAddress.Error())
})

t.Run("should fail on empty server", func(t *testing.T) {
serve, err := NewGRPCService(nil)
require.Nil(t, serve)
require.EqualError(t, err, ErrEmptyGRPCServer.Error())
})

t.Run("should fail on Start and Stop", func(t *testing.T) {
require.EqualError(t, (&gRPC{}).Start(), ErrEmptyGRPCServer.Error())
require.EqualError(t, (&gRPC{}).Stop(), ErrEmptyGRPCServer.Error())
})

t.Run("should fail on net.Listen", func(t *testing.T) {
require.EqualError(t, (&gRPC{server: grpc.NewServer()}).Start(), "listen: unknown network ")
})

t.Run("shoud ignore ErrServerStopped", func(t *testing.T) {
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
require.NoError(t, lis.Close())

serve, err := NewGRPCService(
grpc.NewServer(),
GRPCSkipErrors(),
GRPCListenAddress(lis.Addr().String()))
require.NoError(t, err)

require.NoError(t, serve.Stop())
require.NoError(t, serve.Start())
})
}
65 changes: 65 additions & 0 deletions web/http_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package web

import (
"crypto/tls"
"errors"
"github.com/stretchr/testify/require"
"net"
"net/http"
"testing"
)

func TestHTTPService(t *testing.T) {
t.Run("should set network", func(t *testing.T) {
serve, err := NewHTTPService(
&http.Server{},
HTTPSkipErrors(),
HTTPListenAddress(":8080"),
HTTPListenNetwork("test"))
require.NoError(t, err)

s, ok := serve.(*httpService)
require.True(t, ok)
require.Equal(t, "test", s.network)
})

t.Run("should fail on empty address", func(t *testing.T) {
serve, err := NewHTTPService(&http.Server{})
require.Nil(t, serve)
require.EqualError(t, err, ErrEmptyHTTPAddress.Error())
})

t.Run("should fail on empty server", func(t *testing.T) {
serve, err := NewHTTPService(nil)
require.Nil(t, serve)
require.EqualError(t, err, ErrEmptyHTTPServer.Error())
})

t.Run("should fail on Start and Stop", func(t *testing.T) {
require.EqualError(t, (&httpService{}).Start(), ErrEmptyHTTPServer.Error())
require.EqualError(t, (&httpService{}).Stop(), ErrEmptyHTTPServer.Error())
})

t.Run("should fail on net.Listen", func(t *testing.T) {
require.EqualError(t, (&httpService{server: &http.Server{}}).Start(), "listen: unknown network ")
})

t.Run("should not fail for tls", func(t *testing.T) {
lis, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
require.NoError(t, lis.Close())

s := &http.Server{
TLSConfig: &tls.Config{
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
return nil, errors.New("test")
},
},
}

serve, err := NewHTTPService(s, HTTPListenAddress(lis.Addr().String()))
require.NoError(t, err)

require.NoError(t, serve.Start())
})
}
69 changes: 69 additions & 0 deletions web/listener_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package web

import (
"context"
"errors"
"github.com/stretchr/testify/require"
"testing"
"time"
)

type fakeListener struct {
startError error
stopError error
}

func (f fakeListener) ListenAndServe() error {
return f.startError
}

func (f fakeListener) Shutdown(context.Context) error {
return f.stopError
}

func TestListenerService(t *testing.T) {
t.Run("should set network", func(t *testing.T) {
serve, err := NewListener(
&fakeListener{},
ListenerIgnoreError(ErrEmptyListener),
ListenerSkipErrors(),
ListenerShutdownTimeout(time.Second))
require.NoError(t, err)

s, ok := serve.(*listener)
require.True(t, ok)
require.True(t, s.skipErrors)
require.Equal(t, time.Second, s.shutdownTimeout)
require.Equal(t, ErrEmptyListener, s.ignoreErrors[0])
})

t.Run("should fail on empty server", func(t *testing.T) {
serve, err := NewListener(nil)
require.Nil(t, serve)
require.EqualError(t, err, ErrEmptyListener.Error())
})

t.Run("should fail on Start and Stop", func(t *testing.T) {
require.EqualError(t, (&listener{}).Start(), ErrEmptyListener.Error())
require.EqualError(t, (&listener{}).Stop(), ErrEmptyListener.Error())
})

t.Run("should successfully start and stop", func(t *testing.T) {
require.NoError(t, (&listener{server: &fakeListener{}}).Start())
require.NoError(t, (&listener{server: &fakeListener{}}).Stop())
})

t.Run("should skip errors", func(t *testing.T) {
s := &fakeListener{stopError: errors.New("stopping")}
serve, err := NewListener(s, ListenerSkipErrors())
require.NoError(t, err)
require.NoError(t, serve.Stop())
})

t.Run("should ignore errors", func(t *testing.T) {
s := &fakeListener{stopError: ErrEmptyListener}
serve, err := NewListener(s, ListenerIgnoreError(ErrEmptyListener))
require.NoError(t, err)
require.NoError(t, serve.Stop())
})
}
52 changes: 50 additions & 2 deletions web/servers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,33 @@ func TestServers(t *testing.T) {
v = viper.New()
)

t.Run("gRPC default server", func(t *testing.T) {
t.Run("should skip empty gRPC default server", func(t *testing.T) {
res, err := newDefaultGRPCServer(grpcParams{})
require.Empty(t, res)
require.NoError(t, err)
})

t.Run("should creates with passed config", func(t *testing.T) {
v.Set("test_grpc.address", ":0")
v.Set("test_grpc.network", "test")
v.Set("test_grpc.skip_errors", true)

res, err := newDefaultGRPCServer(grpcParams{
Viper: v,
Key: "test_grpc",
Server: grpc.NewServer(),
})
require.NoError(t, err)

serv, ok := res.Server.(*gRPC)
require.True(t, ok)
require.True(t, serv.skipErrors)
require.Equal(t, serv.address, ":0")
require.Equal(t, serv.network, "test")
})
})

t.Run("check pprof server", func(t *testing.T) {
t.Run("without config", func(t *testing.T) {
params := profileParams{
Expand Down Expand Up @@ -122,17 +149,38 @@ func TestServers(t *testing.T) {
is := require.New(t)

v.SetDefault("test-api.disabled", true)

z, err := zap.NewDevelopment()
is.NoError(err)

testHTTPHandler(is)

serve, err := NewHTTPServer(v, "test-api", testHTTPHandler(is), z)
require.NoError(t, err)
is.NoError(err)
is.Nil(serve.Server)
})

t.Run("api should be configured", func(t *testing.T) {
is := require.New(t)

v.SetDefault("another-api.address", "test")
v.SetDefault("another-api.network", "test")
v.SetDefault("another-api.skip_errors", true)

z, err := zap.NewDevelopment()
is.NoError(err)

testHTTPHandler(is)

serve, err := NewHTTPServer(v, "another-api", testHTTPHandler(is), z)
is.NoError(err)

s, ok := serve.Server.(*httpService)
is.True(ok)
is.True(s.skipErrors)
is.Equal("test", s.address)
is.Equal("test", s.network)
})

t.Run("check api server", func(t *testing.T) {
t.Run("without config", func(t *testing.T) {
serve, err := NewAPIServer(v, l, nil)
Expand Down
6 changes: 4 additions & 2 deletions web/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,16 @@ func (m *runner) Start() error {
// Stop tries to stop services, logs every error,
// and returns last error.
func (m *runner) Stop() error {
var err error
var lastErr error
for i := range m.services {
if err := m.services[i].Stop(); err != nil {
lastErr = err

m.logger.Error("could not stop server",
zap.Int("index", i),
zap.Error(err))
}
}

return err
return lastErr
}
53 changes: 53 additions & 0 deletions web/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package web

import (
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"testing"
)

type fakeService struct {
startError error
stopError error
}

func (f fakeService) Start() error {
return f.startError
}

func (f fakeService) Stop() error {
return f.stopError
}

func TestMultiService(t *testing.T) {
t.Run("fail on empty logger", func(t *testing.T) {
svc, err := New(nil)
require.Nil(t, svc)
require.EqualError(t, err, ErrEmptyLogger.Error())
})

t.Run("fail on empty services", func(t *testing.T) {
svc, err := New(zap.L(), nil, nil)
require.Nil(t, svc)
require.EqualError(t, err, ErrEmptyServices.Error())
})

t.Run("should fail on start and return first error", func(t *testing.T) {
svc, err := New(zap.L(),
&fakeService{startError: ErrEmptyServices},
&fakeService{startError: ErrEmptyLogger})
require.NoError(t, err)
require.EqualError(t, svc.Start(), ErrEmptyServices.Error())
})

t.Run("should fail on stop and return last error", func(t *testing.T) {
l, err := zap.NewDevelopment()
require.NoError(t, err)

svc, err := New(l,
&fakeService{stopError: ErrEmptyServices},
&fakeService{stopError: ErrEmptyLogger})
require.NoError(t, err)
require.EqualError(t, svc.Stop(), ErrEmptyLogger.Error())
})
}

0 comments on commit ec0871c

Please sign in to comment.