Skip to content

Commit

Permalink
tests: add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas committed Nov 11, 2020
1 parent 8a9a8b1 commit 6032444
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 11 deletions.
3 changes: 2 additions & 1 deletion hub/hub.go
@@ -1,6 +1,7 @@
package hub

import (
"fmt"
"log"
"net/http"

Expand Down Expand Up @@ -41,7 +42,7 @@ func NewHub(v *viper.Viper) (*Hub, error) {
logger, err = zap.NewProduction()
}
if err != nil {
panic(err)
return nil, fmt.Errorf("can't initialize zap logger: %w", err)
}

t, err := NewTransport(v, logger)
Expand Down
13 changes: 7 additions & 6 deletions hub/log.go
Expand Up @@ -12,13 +12,14 @@ func (ss stringArray) MarshalLogArray(arr zapcore.ArrayEncoder) error {
return nil
}

type Field = zapcore.Field
// LogField is an alias of zapcore.Field, it could be replaced by a custom contract when Go will support generics.
type LogField = zapcore.Field

type Logger interface {
Debug(msg string, fields ...Field)
Info(msg string, fields ...Field)
Warn(msg string, fields ...Field)
Error(msg string, fields ...Field)
Fatal(msg string, fields ...Field)
Debug(msg string, fields ...LogField)
Info(msg string, fields ...LogField)
Warn(msg string, fields ...LogField)
Error(msg string, fields ...LogField)
Fatal(msg string, fields ...LogField)
Sync() error
}
43 changes: 43 additions & 0 deletions hub/log_test.go
@@ -0,0 +1,43 @@
package hub

import (
"bytes"
"net/url"
"testing"

"go.uber.org/zap"
)

// MemorySink implements zap.Sink by writing all messages to a buffer.
type MemorySink struct {
*bytes.Buffer
}

// Implement Close and Sync as no-ops to satisfy the interface. The Write
// method is provided by the embedded buffer.

func (s *MemorySink) Close() error { return nil }
func (s *MemorySink) Sync() error { return nil }

var sink *MemorySink

func newTestLogger(t *testing.T) (*MemorySink, Logger) {
if sink == nil {
sink = &MemorySink{new(bytes.Buffer)}
if err := zap.RegisterSink("memory", func(*url.URL) (zap.Sink, error) {
return sink, nil
}); err != nil {
t.Fatal(err)
}
}

conf := zap.NewProductionConfig()
conf.OutputPaths = []string{"memory://"}

logger, err := conf.Build()
if err != nil {
t.Fatal(err)
}

return sink, logger
}
1 change: 1 addition & 0 deletions hub/publish.go
Expand Up @@ -52,6 +52,7 @@ func (h *Hub) PublishHandler(w http.ResponseWriter, r *http.Request) {
u := &Update{
Topics: topics,
Private: private,
Debug: h.config.GetBool("debug"),
Event: Event{
r.PostForm.Get("data"),
r.PostForm.Get("id"),
Expand Down
2 changes: 1 addition & 1 deletion hub/server_test.go
Expand Up @@ -56,7 +56,7 @@ func TestForwardedHeaders(t *testing.T) {
require.Nil(t, err)
defer resp2.Body.Close()

assert.Equal(t, 1, logs.FilterField(zap.String("remote_addr", "192.0.2.1")).Len())
assert.True(t, logs.FilterField(zap.String("remote_addr", "192.0.2.1")).Len() == 1)

h.server.Shutdown(context.Background())
}
Expand Down
4 changes: 3 additions & 1 deletion hub/subscribe.go
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

// SubscribeHandler creates a keep alive connection and sends the events to the subscribers.
Expand Down Expand Up @@ -155,7 +156,7 @@ func retrieveLastEventID(r *http.Request) string {
// Write sends the given string to the client.
// It returns false if the dispatch timed out.
// The current write cannot be cancelled because of https://github.com/golang/go/issues/16100
func (h *Hub) write(w io.Writer, s *Subscriber, data string, d time.Duration) bool {
func (h *Hub) write(w io.Writer, s zapcore.ObjectMarshaler, data string, d time.Duration) bool {
if d == time.Duration(0) {
fmt.Fprint(w, data)
w.(http.Flusher).Flush()
Expand Down Expand Up @@ -204,6 +205,7 @@ func (h *Hub) dispatchSubscriptionUpdate(s *Subscriber, active bool) {
u := &Update{
Topics: []string{subscription.ID},
Private: true,
Debug: h.config.GetBool("debug"),
Event: Event{Data: string(json)},
}
h.transport.Dispatch(u)
Expand Down
19 changes: 19 additions & 0 deletions hub/subscriber_test.go
Expand Up @@ -36,3 +36,22 @@ func TestDisconnect(t *testing.T) {

assert.False(t, s.Dispatch(&Update{}, false))
}

func TestLogSubscriber(t *testing.T) {
sink, logger := newTestLogger(t)
defer sink.Reset()

s := NewSubscriber("123", logger, NewTopicSelectorStore())
s.RemoteAddr = "127.0.0.1"
s.TopicSelectors = []string{"https://example.com/foo"}
s.Topics = []string{"https://example.com/bar"}

f := zap.Object("subscriber", s)
logger.Info("test", f)

log := sink.String()
assert.Contains(t, log, `"last_event_id":"123"`)
assert.Contains(t, log, `"remote_addr":"127.0.0.1"`)
assert.Contains(t, log, `"topic_selectors":["https://example.com/foo"]`)
assert.Contains(t, log, `"topics":["https://example.com/bar"]`)
}
8 changes: 6 additions & 2 deletions hub/update.go
Expand Up @@ -14,6 +14,9 @@ type Update struct {
// Private updates can only be dispatched to subscribers authorized to receive them.
Private bool

// To print debug informations
Debug bool

// The Server-Sent Event to send.
Event
}
Expand All @@ -25,8 +28,9 @@ func (u *Update) MarshalLogObject(enc zapcore.ObjectEncoder) error {
enc.AddArray("topics", stringArray(u.Topics))
enc.AddBool("private", u.Private)

// TODO: only in debug mode
enc.AddString("data", u.Data)
if u.Debug {
enc.AddString("data", u.Data)
}

return nil
}
Expand Down
24 changes: 24 additions & 0 deletions hub/update_test.go
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/gofrs/uuid"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
)

func TestAssingUUID(t *testing.T) {
Expand All @@ -24,3 +25,26 @@ func TestAssingUUID(t *testing.T) {
_, err := uuid.FromString(strings.TrimPrefix(u.ID, "urn:uuid:"))
assert.Nil(t, err)
}

func TestLogUpdate(t *testing.T) {
sink, logger := newTestLogger(t)
defer sink.Reset()

u := &Update{
Topics: []string{"https://example.com/foo"},
Private: true,
Debug: true,
Event: Event{ID: "a", Retry: 3, Data: "bar", Type: "baz"},
}

f := zap.Object("update", u)
logger.Info("test", f)

log := sink.String()
assert.Contains(t, log, `"id":"a"`)
assert.Contains(t, log, `"type":"baz"`)
assert.Contains(t, log, `"retry":3`)
assert.Contains(t, log, `"topics":["https://example.com/foo"]`)
assert.Contains(t, log, `"private":true`)
assert.Contains(t, log, `"data":"bar"`)
}

0 comments on commit 6032444

Please sign in to comment.