Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating broker tests to cover some implicit cases #38

Merged
merged 5 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions internal/brokers/broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ func TestNewBroker(t *testing.T) {
func TestGetAuthenticationModes(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "", "")

tests := map[string]struct {
sessionID string
supportedUILayouts []string
Expand All @@ -115,8 +117,6 @@ func TestGetAuthenticationModes(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "")

if tc.supportedUILayouts == nil {
tc.supportedUILayouts = []string{"required-entry"}
}
Expand All @@ -126,7 +126,7 @@ func TestGetAuthenticationModes(t *testing.T) {
supportedUILayouts = append(supportedUILayouts, supportedLayouts[layout])
}

gotModes, err := b.GetAuthenticationModes(context.Background(), tc.sessionID, supportedUILayouts)
gotModes, err := b.GetAuthenticationModes(context.Background(), prefixID(t, tc.sessionID), supportedUILayouts)
if tc.wantErr {
require.Error(t, err, "GetAuthenticationModes should return an error, but did not")
return
Expand All @@ -136,7 +136,7 @@ func TestGetAuthenticationModes(t *testing.T) {
modesStr, err := json.Marshal(gotModes)
require.NoError(t, err, "Post: error when marshaling result")

got := "MODES:\n" + string(modesStr) + "\n\nVALIDATORS:\n" + b.LayoutValidatorsString(tc.sessionID)
got := "MODES:\n" + string(modesStr) + "\n\nVALIDATORS:\n" + b.LayoutValidatorsString(prefixID(t, tc.sessionID))
want := testutils.LoadWithUpdateFromGolden(t, got)
require.Equal(t, want, got, "GetAuthenticationModes should return the expected modes, but did not")
})
Expand All @@ -146,6 +146,8 @@ func TestGetAuthenticationModes(t *testing.T) {
func TestSelectAuthenticationMode(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "", "")

tests := map[string]struct {
sessionID string
supportedUILayouts []string
Expand Down Expand Up @@ -173,8 +175,6 @@ func TestSelectAuthenticationMode(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "")

if tc.supportedUILayouts == nil {
tc.supportedUILayouts = []string{"required-entry"}
}
Expand All @@ -184,9 +184,9 @@ func TestSelectAuthenticationMode(t *testing.T) {
supportedUILayouts = append(supportedUILayouts, supportedLayouts[layout])
}
// This is normally done in the broker's GetAuthenticationModes method, but we need to do it here to test the SelectAuthenticationMode method.
brokers.GenerateLayoutValidators(&b, tc.sessionID, supportedUILayouts)
brokers.GenerateLayoutValidators(&b, prefixID(t, tc.sessionID), supportedUILayouts)

gotUI, err := b.SelectAuthenticationMode(context.Background(), tc.sessionID, "mode1")
gotUI, err := b.SelectAuthenticationMode(context.Background(), prefixID(t, tc.sessionID), "mode1")
if tc.wantErr {
require.Error(t, err, "SelectAuthenticationMode should return an error, but did not")
return
Expand All @@ -202,6 +202,8 @@ func TestSelectAuthenticationMode(t *testing.T) {
func TestIsAuthenticated(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "", "")

tests := map[string]struct {
sessionID string
secondCall bool
Expand All @@ -226,8 +228,6 @@ func TestIsAuthenticated(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "")

// Stores the combined output of both calls to IsAuthenticated
var firstCallReturn, secondCallReturn string

Expand All @@ -237,8 +237,8 @@ func TestIsAuthenticated(t *testing.T) {
done := make(chan struct{})
go func() {
defer close(done)
access, gotData, err := b.IsAuthenticated(ctx, tc.sessionID, "password")
firstCallReturn = fmt.Sprintf("FIRST CALL:\n\taccess: %s\n\tdata: %+v\n\terr: %v\n", access, gotData, err)
access, gotData, err := b.IsAuthenticated(ctx, prefixID(t, tc.sessionID), "password")
firstCallReturn = fmt.Sprintf("FIRST CALL:\n\taccess: %s\n\tdata: %s\n\terr: %v\n", access, gotData, err)
}()

// Give some time for the first call to block
Expand All @@ -249,8 +249,8 @@ func TestIsAuthenticated(t *testing.T) {
cancel()
<-done
}
access, gotData, err := b.IsAuthenticated(context.Background(), tc.sessionID, "password")
secondCallReturn = fmt.Sprintf("SECOND CALL:\n\taccess: %s\n\tdata: %+v\n\terr: %v\n", access, gotData, err)
access, gotData, err := b.IsAuthenticated(context.Background(), prefixID(t, tc.sessionID), "password")
secondCallReturn = fmt.Sprintf("SECOND CALL:\n\taccess: %s\n\tdata: %s\n\terr: %v\n", access, gotData, err)
}

<-done
Expand All @@ -264,6 +264,8 @@ func TestIsAuthenticated(t *testing.T) {
func TestCancelIsAuthenticated(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "", "")

tests := map[string]struct {
sessionID string

Expand All @@ -277,13 +279,11 @@ func TestCancelIsAuthenticated(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()

b := newBrokerForTests(t, "")

var access string
ctx, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
access, _, _ = b.IsAuthenticated(ctx, tc.sessionID, "password")
access, _, _ = b.IsAuthenticated(ctx, prefixID(t, tc.sessionID), "password")
close(done)
}()
defer cancel()
Expand All @@ -299,23 +299,32 @@ func TestCancelIsAuthenticated(t *testing.T) {
}
}

func newBrokerForTests(t *testing.T, cfgDir string) (b brokers.Broker) {
func newBrokerForTests(t *testing.T, cfgDir, brokerName string) (b brokers.Broker) {
t.Helper()

if cfgDir == "" {
cfgDir = t.TempDir()
}
if brokerName == "" {
brokerName = strings.ReplaceAll(t.Name(), "/", "_")
}

cfgPath, cleanup, err := testutils.StartBusBrokerMock(cfgDir, strings.ReplaceAll(t.Name(), "/", "_"))
cfgPath, cleanup, err := testutils.StartBusBrokerMock(cfgDir, brokerName)
require.NoError(t, err, "Setup: could not start bus broker mock")
t.Cleanup(cleanup)

conn, err := testutils.GetSystemBusConnection(t)
require.NoError(t, err, "Setup: could not connect to system bus")
t.Cleanup(func() { require.NoError(t, conn.Close(), "Teardown: Failed to close the connection") })

b, err = brokers.NewBroker(context.Background(), strings.ReplaceAll(t.Name(), "/", "_"), cfgPath, conn)
b, err = brokers.NewBroker(context.Background(), brokerName, cfgPath, conn)
require.NoError(t, err, "Setup: could not create broker")

return b
}

// prefixID is a helper function that prefixes the given ID with the test name to avoid conflicts.
func prefixID(t *testing.T, id string) string {
t.Helper()
return t.Name() + testutils.IDSeparator + id
}
126 changes: 115 additions & 11 deletions internal/brokers/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -20,12 +21,14 @@ var (

func TestNewManager(t *testing.T) {
tests := map[string]struct {
cfgDir string
noBus bool
cfgDir string
configuredBrokers []string
noBus bool

wantErr bool
}{
"Creates all brokers when config dir has only valid brokers": {cfgDir: "valid_brokers"},
"Creates without autodiscovery when configuredBrokers is set": {cfgDir: "valid_brokers", configuredBrokers: []string{"valid_2"}},
"Creates only correct brokers when config dir has valid and invalid brokers": {cfgDir: "mixed_brokers"},
"Creates only local broker when config dir has only invalid ones": {cfgDir: "invalid_brokers"},
"Creates only local broker when config dir does not exist": {cfgDir: "does/not/exist"},
Expand All @@ -41,7 +44,7 @@ func TestNewManager(t *testing.T) {
t.Setenv("DBUS_SYSTEM_BUS_ADDRESS", "/dev/null")
}

got, err := brokers.NewManager(context.Background(), nil, brokers.WithRootDir(brokerCfgs), brokers.WithCfgDir(tc.cfgDir))
got, err := brokers.NewManager(context.Background(), tc.configuredBrokers, brokers.WithRootDir(brokerCfgs), brokers.WithCfgDir(tc.cfgDir))
if tc.wantErr {
require.Error(t, err, "NewManager should return an error, but did not")
return
Expand Down Expand Up @@ -136,7 +139,7 @@ func TestBrokerFromSessionID(t *testing.T) {
t.Parallel()

cfgDir := t.TempDir()
b := newBrokerForTests(t, cfgDir)
b := newBrokerForTests(t, cfgDir, "")
m, err := brokers.NewManager(context.Background(), nil, brokers.WithCfgDir(cfgDir))
require.NoError(t, err, "Setup: could not create manager")

Expand Down Expand Up @@ -171,9 +174,12 @@ func TestNewSession(t *testing.T) {
brokerID string
username string

configuredBrokers []string

wantErr bool
}{
"Successfully start a new session": {username: "success"},
"Successfully start a new session": {username: "success"},
"Successfully start a new session with the correct broker": {username: "success", configuredBrokers: []string{t.Name() + "_Broker1", t.Name() + "_Broker2"}},

"Error when broker does not exist": {brokerID: "does_not_exist", wantErr: true},
"Error when broker does not provide an ID": {username: "NS_no_id", wantErr: true},
Expand All @@ -185,8 +191,18 @@ func TestNewSession(t *testing.T) {
t.Parallel()

cfgDir := t.TempDir()
wantBroker := newBrokerForTests(t, cfgDir)
m, err := brokers.NewManager(context.Background(), nil, brokers.WithCfgDir(cfgDir))
if tc.configuredBrokers == nil {
tc.configuredBrokers = []string{strings.ReplaceAll(t.Name(), "/", "_")}
}

wantBroker := newBrokerForTests(t, cfgDir, tc.configuredBrokers[0])
if len(tc.configuredBrokers) > 1 {
for _, name := range tc.configuredBrokers[1:] {
newBrokerForTests(t, cfgDir, name)
}
}

m, err := brokers.NewManager(context.Background(), tc.configuredBrokers, brokers.WithCfgDir(cfgDir))
require.NoError(t, err, "Setup: could not create manager")

if tc.brokerID == "" {
Expand Down Expand Up @@ -226,9 +242,12 @@ func TestEndSession(t *testing.T) {
brokerID string
sessionID string

configuredBrokers []string

wantErr bool
}{
"Successfully end session": {sessionID: "success"},
"Successfully end session": {sessionID: "success"},
"Successfully end session on the correct broker": {sessionID: "success", configuredBrokers: []string{t.Name() + "_Broker1", t.Name() + "_Broker2"}},

"Error when broker does not exist": {brokerID: "does not exist", sessionID: "dont matter", wantErr: true},
"Error when ending session": {sessionID: "ES_error", wantErr: true},
Expand All @@ -239,12 +258,22 @@ func TestEndSession(t *testing.T) {
t.Parallel()

cfgDir := t.TempDir()
b := newBrokerForTests(t, cfgDir)
m, err := brokers.NewManager(context.Background(), nil, brokers.WithCfgDir(cfgDir))
if tc.configuredBrokers == nil {
tc.configuredBrokers = []string{strings.ReplaceAll(t.Name(), "/", "_")}
}

wantBroker := newBrokerForTests(t, cfgDir, tc.configuredBrokers[0])
if len(tc.configuredBrokers) > 1 {
for _, name := range tc.configuredBrokers[1:] {
newBrokerForTests(t, cfgDir, name)
}
}

m, err := brokers.NewManager(context.Background(), tc.configuredBrokers, brokers.WithCfgDir(cfgDir))
require.NoError(t, err, "Setup: could not create manager")

if tc.brokerID != "does not exist" {
m.SetBrokerForSession(&b, tc.sessionID)
m.SetBrokerForSession(&wantBroker, tc.sessionID)
}

err = m.EndSession(tc.sessionID)
Expand All @@ -259,6 +288,81 @@ func TestEndSession(t *testing.T) {
}
}

func TestStartAndEndSession(t *testing.T) {
t.Parallel()

cfgDir := t.TempDir()
b1 := newBrokerForTests(t, cfgDir, t.Name()+"_Broker1")
b2 := newBrokerForTests(t, cfgDir, t.Name()+"_Broker2")

m, err := brokers.NewManager(context.Background(), []string{b1.Name, b2.Name}, brokers.WithCfgDir(cfgDir))
require.NoError(t, err, "Setup: could not create manager")

// Fetches the broker IDs
for _, broker := range m.AvailableBrokers() {
if broker.Name == b1.Name {
b1.ID = broker.ID
} else if broker.Name == b2.Name {
b2.ID = broker.ID
}
}

/* Starting the sessions */
var firstID, firstKey, secondID, secondKey *string
var firstErr, secondErr *error
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
id, key, err := m.NewSession(b1.ID, "user1", "some_lang")
firstID, firstKey, firstErr = &id, &key, &err
}()
wg.Add(1)
go func() {
defer wg.Done()
id, key, err := m.NewSession(b2.ID, "user2", "some_lang")
secondID, secondKey, secondErr = &id, &key, &err
}()
wg.Wait()

require.NoError(t, *firstErr, "First NewSession should not return an error, but did")
require.NoError(t, *secondErr, "Second NewSession should not return an error, but did")

require.Equal(t, b1.ID+"-"+testutils.GenerateSessionID("user1"), *firstID, "First NewSession should return the expected session ID, but did not")
require.Equal(t, testutils.GenerateEncryptionKey(b1.Name), *firstKey, "First NewSession should return the expected encryption key, but did not")
require.Equal(t, b2.ID+"-"+testutils.GenerateSessionID("user2"), *secondID, "Second NewSession should return the expected session ID, but did not")
require.Equal(t, testutils.GenerateEncryptionKey(b2.Name), *secondKey, "Second NewSession should return the expected encryption key, but did not")

assignedBroker, err := m.BrokerFromSessionID(*firstID)
require.NoError(t, err, "First NewSession should have assigned a broker for the session, but did not")
require.Equal(t, b1.Name, assignedBroker.Name, "First NewSession should have assigned the expected broker for the session, but did not")
assignedBroker, err = m.BrokerFromSessionID(*secondID)
require.NoError(t, err, "Second NewSession should have assigned a broker for the session, but did not")
require.Equal(t, b2.Name, assignedBroker.Name, "Second NewSession should have assigned the expected broker for the session, but did not")

/* Ending the sessions */
wg.Add(1)
go func() {
defer wg.Done()
*firstErr = m.EndSession(*firstID)
}()
wg.Add(1)
go func() {
defer wg.Done()
*secondErr = m.EndSession(*secondID)
}()
wg.Wait()

require.NoError(t, *firstErr, "First EndSession should not return an error, but did")
require.NoError(t, *secondErr, "Second EndSession should not return an error, but did")

_, err = m.BrokerFromSessionID(*firstID)
require.Error(t, err, "First EndSession should have removed the broker for the session, but did not")

_, err = m.BrokerFromSessionID(*secondID)
require.Error(t, err, "Second EndSession should have removed the broker for the session, but did not")
}

func TestMain(m *testing.M) {
testutils.InstallUpdateFlag()
flag.Parse()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FIRST CALL:
access:
data:
err: Broker "TestIsAuthenticated_Error_when_authenticating": IsAuthenticated errored out
err: Broker "TestIsAuthenticated": IsAuthenticated errored out
didrocks marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ FIRST CALL:
SECOND CALL:
access:
data:
err: Broker "TestIsAuthenticated_Error_when_calling_IsAuthenticated_a_second_time_without_cancelling": IsAuthenticated already running for session "IA_second_call"
err: Broker "TestIsAuthenticated": IsAuthenticated already running for session "TestIsAuthenticated/Error_when_calling_IsAuthenticated_a_second_time_without_cancelling_separator_IA_second_call"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- local
- Broker2
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ID: BROKER_ID-success-session_id
Encryption Key: TestNewSession_Successfully_start_a_new_session_key
Encryption Key: TestNewSession_Successfully_start_a_new_session-key
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ID: BROKER_ID-success-session_id
Encryption Key: TestNewSession_Broker1-key
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ID: BROKER_ID-TestSelectBroker/Successfully_select_a_broker_and_creates_the_session_separator_success-session_id
Encryption Key: BrokerMock_key
Encryption Key: BrokerMock-key
Loading