-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make it easy to plugin other queues (#2208)
* Add unit tests for nats queue * Move nats related code to own client Renamed realtime.Realtime to realtime.Broker to make the import not stuttering * Implement healthy test as table test to support different brokers in the future Co-authored-by: Johann Böhler <[email protected]>
- Loading branch information
1 parent
e6f0476
commit f3e6e8b
Showing
16 changed files
with
686 additions
and
334 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package realtime_test | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/uuid" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"scrumlr.io/server/realtime" | ||
) | ||
|
||
func TestRealtime_GetBoardSessionRequestChannel(t *testing.T) { | ||
|
||
ctx, cancelFunc := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancelFunc() | ||
rt, err := realtime.NewNats(SetupNatsContainer(t)) | ||
assert.Nil(t, err) | ||
testBoard := uuid.New() | ||
testUser := uuid.New() | ||
|
||
testEvents := []realtime.BoardSessionRequestEventType{ | ||
realtime.RequestRejected, | ||
realtime.RequestAccepted, | ||
"some undefined event", | ||
} | ||
|
||
eventChannel := rt.GetBoardSessionRequestChannel(testBoard, testUser) | ||
readEvents := []realtime.BoardSessionRequestEventType{} | ||
wg := sync.WaitGroup{} | ||
go func() { | ||
for { | ||
select { | ||
case ev := <-eventChannel: | ||
assert.NotNil(t, ev) | ||
readEvents = append(readEvents, *ev) | ||
wg.Done() | ||
case <-ctx.Done(): | ||
return | ||
} | ||
} | ||
}() | ||
|
||
for _, ev := range testEvents { | ||
err := rt.BroadcastUpdateOnBoardSessionRequest(testBoard, testUser, ev) | ||
assert.Nil(t, err) | ||
wg.Add(1) | ||
} | ||
|
||
go func() { | ||
wg.Wait() | ||
cancelFunc() | ||
}() | ||
|
||
<-ctx.Done() | ||
assert.Equal(t, testEvents, readEvents) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package realtime_test | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/uuid" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"scrumlr.io/server/realtime" | ||
) | ||
|
||
func TestRealtime_GetBoardChannel(t *testing.T) { | ||
|
||
ctx, cancelFunc := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancelFunc() | ||
rt, err := realtime.NewNats(SetupNatsContainer(t)) | ||
assert.Nil(t, err) | ||
testBoard := uuid.New() | ||
|
||
testEvents := []realtime.BoardEvent{ | ||
{ | ||
Type: realtime.BoardEventInit, | ||
Data: nil, | ||
}, | ||
{ | ||
Type: realtime.BoardEventInit, | ||
Data: "not nil string data", | ||
}, | ||
{ | ||
Type: realtime.BoardEventNotesUpdated, | ||
Data: struct { | ||
More string | ||
Complex float64 | ||
Data map[int]bool | ||
}{ | ||
More: "foo", | ||
Complex: 2.0, | ||
Data: map[int]bool{1: false, 3: true}, | ||
}, | ||
}, | ||
} | ||
|
||
// TODO: The current datastructures doesn't respect the types, because | ||
// an empty interface can be anything. | ||
expectedEvents := []realtime.BoardEvent{ | ||
testEvents[0], | ||
testEvents[1], | ||
{ | ||
Type: realtime.BoardEventNotesUpdated, | ||
Data: map[string]interface{}{ | ||
"Complex": 2.0, | ||
"More": "foo", | ||
"Data": map[string]interface{}{ | ||
// Mapping int to string here, because JSON stuff. | ||
"1": false, | ||
"3": true, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
eventChannel := rt.GetBoardChannel(testBoard) | ||
readEvents := []realtime.BoardEvent{} | ||
wg := sync.WaitGroup{} | ||
go func() { | ||
for { | ||
select { | ||
case ev := <-eventChannel: | ||
assert.NotNil(t, ev) | ||
readEvents = append(readEvents, *ev) | ||
wg.Done() | ||
case <-ctx.Done(): | ||
return | ||
} | ||
} | ||
}() | ||
|
||
for _, ev := range testEvents { | ||
err := rt.BroadcastToBoard(testBoard, ev) | ||
assert.Nil(t, err) | ||
wg.Add(1) | ||
} | ||
|
||
go func() { | ||
wg.Wait() | ||
cancelFunc() | ||
}() | ||
|
||
<-ctx.Done() | ||
|
||
assert.Equal(t, expectedEvents, readEvents) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package realtime | ||
|
||
// Client can publish data to an external queue and receive events from | ||
// that external queue | ||
type Client interface { | ||
// Publish an event to the queue | ||
Publish(subject string, event interface{}) error | ||
|
||
// SubscribeToBoardSessionEvents subscribes to the given topic and return a channel | ||
// with the received BoardSessionRequestEventType | ||
SubscribeToBoardSessionEvents(subject string) (chan *BoardSessionRequestEventType, error) | ||
|
||
// SubscribeToBoardEvents subscribes to the given topic and return a channel | ||
// // with the received BoardEvent | ||
SubscribeToBoardEvents(subject string) (chan *BoardEvent, error) | ||
} | ||
|
||
// The Broker enables a user to broadcast and receive events | ||
type Broker struct { | ||
con Client | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package realtime_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
"scrumlr.io/server/realtime" | ||
) | ||
|
||
func TestBroker_IsHealthy(t *testing.T) { | ||
type testCase struct { | ||
name string | ||
setupBroker func(t *testing.T) *realtime.Broker | ||
expected bool | ||
} | ||
testcases := []testCase{ | ||
{ | ||
name: "nats client has has wrong url", | ||
setupBroker: func(t *testing.T) *realtime.Broker { | ||
rt, err := realtime.NewNats("foo") | ||
require.NotNil(t, err) | ||
return rt | ||
}, | ||
expected: false, | ||
}, | ||
{ | ||
name: "nats client is setup correctly", | ||
setupBroker: func(t *testing.T) *realtime.Broker { | ||
rt, err := realtime.NewNats(SetupNatsContainer(t)) | ||
require.Nil(t, err) | ||
return rt | ||
}, | ||
expected: true, | ||
}, | ||
} | ||
for _, tt := range testcases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
assert.Equal(t, tt.expected, tt.setupBroker(t).IsHealthy(), "healthy didn't return expected result") | ||
}) | ||
} | ||
} |
Oops, something went wrong.