From 25ba2cf4645cb5aa8979f2af022040f7562cb50b Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Thu, 22 Aug 2024 10:28:54 +0200 Subject: [PATCH] test case for single agent registration. --- pkg/comms/agentserver_test.go | 38 ++++++------ pkg/server/admin/admin.go | 5 +- pkg/server/admin/admin_test.go | 108 +++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 pkg/server/admin/admin_test.go diff --git a/pkg/comms/agentserver_test.go b/pkg/comms/agentserver_test.go index 52d13b9..dc22798 100644 --- a/pkg/comms/agentserver_test.go +++ b/pkg/comms/agentserver_test.go @@ -20,8 +20,8 @@ type AgentServerTestSuite struct { cancelFunc context.CancelFunc pprofServer *http.Server - agentConnection io.ReadWriteCloser - serverConnection io.ReadWriteCloser + agentReadWriter io.ReadWriteCloser + serverReadWriter io.ReadWriteCloser } func (s *AgentServerTestSuite) SetupSuite() { @@ -42,10 +42,10 @@ func (s *AgentServerTestSuite) SetupTest() { // a channels ize > 0 is passed in. Also the test utility respects the context // so also deals with cancellation much better than net.Pipe. bitpipe := testsupport.NewInmemoryConnection(s.ctx, "inmemory", 10) - agentConnection := bitpipe.Front() - serverConnection := bitpipe.Back() - s.agentConnection = agentConnection - s.serverConnection = serverConnection + agentReadWriter := bitpipe.Front() + serverReadWriter := bitpipe.Back() + s.agentReadWriter = agentReadWriter + s.serverReadWriter = serverReadWriter } func (suite *AgentServerTestSuite) TearDownTest() { @@ -62,13 +62,13 @@ func (s *AgentServerTestSuite) createCommChannel() (CommChannel, CommChannel) { &s.Suite, func() any { log.Println("Agent initializing") - commChannel, err := NewCommChannel(Agent, s.agentConnection) + commChannel, err := NewCommChannel(Agent, s.agentReadWriter) s.Nil(err) return commChannel }, func() any { log.Println("Server initializing") - commChannel, err := NewCommChannel(ConvergeServer, s.serverConnection) + commChannel, err := NewCommChannel(ConvergeServer, s.serverReadWriter) s.Nil(err) return commChannel }, @@ -151,7 +151,7 @@ func (s *AgentServerTestSuite) Test_Initialization() { testsupport.RunAndWait( &s.Suite, func() any { - serverInfo, err := AgentInitialization(s.agentConnection, + serverInfo, err := AgentInitialization(s.agentReadWriter, NewEnvironmentInfo(agentShell)) s.Nil(err) s.Equal(serverTestId, serverInfo.TestId) @@ -159,7 +159,7 @@ func (s *AgentServerTestSuite) Test_Initialization() { }, func() any { serverInfo := ServerInfo{TestId: serverTestId} - environmentInfo, err := ServerInitialization(s.serverConnection, serverInfo) + environmentInfo, err := ServerInitialization(s.serverReadWriter, serverInfo) s.Nil(err) s.Equal(agentShell, environmentInfo.Shell) return nil @@ -171,7 +171,7 @@ func (s *AgentServerTestSuite) Test_InitializationProtocolVersionMismatch() { testsupport.RunAndWait( &s.Suite, func() any { - serverInfo, err := AgentInitialization(s.agentConnection, + serverInfo, err := AgentInitialization(s.agentReadWriter, NewEnvironmentInfo("myshell")) s.NotNil(err) s.True(strings.Contains(strings.ToLower(err.Error()), "protocol")) @@ -180,7 +180,7 @@ func (s *AgentServerTestSuite) Test_InitializationProtocolVersionMismatch() { }, func() any { serverInfo := ServerInfo{TestId: 1000} - environmentInfo, err := ServerInitialization(s.serverConnection, serverInfo) + environmentInfo, err := ServerInitialization(s.serverReadWriter, serverInfo) s.NotNil(err) s.True(strings.Contains(strings.ToLower(err.Error()), "protocol")) s.Equal(EnvironmentInfo{}, environmentInfo) @@ -189,12 +189,12 @@ func (s *AgentServerTestSuite) Test_InitializationProtocolVersionMismatch() { } func (s *AgentServerTestSuite) Test_InitializationAgentConnectionClosed() { - s.agentConnection.Close() + s.agentReadWriter.Close() s.checkInitializationFailure() } func (s *AgentServerTestSuite) Test_InitializationServerConnectionClosed() { - s.serverConnection.Close() + s.serverReadWriter.Close() s.checkInitializationFailure() } @@ -202,7 +202,7 @@ func (s *AgentServerTestSuite) checkInitializationFailure() []any { return testsupport.RunAndWait( &s.Suite, func() any { - serverInfo, err := AgentInitialization(s.agentConnection, + serverInfo, err := AgentInitialization(s.agentReadWriter, NewEnvironmentInfo("myshell")) s.NotNil(err) s.Equal(ServerInfo{}, serverInfo) @@ -210,7 +210,7 @@ func (s *AgentServerTestSuite) checkInitializationFailure() []any { }, func() any { serverInfo := ServerInfo{TestId: 1000} - environmentInfo, err := ServerInitialization(s.serverConnection, serverInfo) + environmentInfo, err := ServerInitialization(s.serverReadWriter, serverInfo) s.NotNil(err) s.Equal(EnvironmentInfo{}, environmentInfo) return nil @@ -233,7 +233,7 @@ func (s *AgentServerTestSuite) Test_ListenForAgentEvents() { testsupport.RunAndWait( &s.Suite, func() any { - channel := NewGOBChannel(s.agentConnection) + channel := NewGOBChannel(s.agentReadWriter) for i := range nevents { ievent := rand.Int() % len(agentEvents) eventTypesSent[i] = ievent @@ -244,12 +244,12 @@ func (s *AgentServerTestSuite) Test_ListenForAgentEvents() { s.Nil(err) } // pending events will still be sent. - s.agentConnection.Close() + s.agentReadWriter.Close() return nil }, func() any { eventTypesReceived := make([]int, nevents, nevents) - channel := NewGOBChannel(s.serverConnection) + channel := NewGOBChannel(s.serverReadWriter) i := 0 ListenForAgentEvents(channel, func(agent EnvironmentInfo) { diff --git a/pkg/server/admin/admin.go b/pkg/server/admin/admin.go index 4461ed9..db0c78a 100644 --- a/pkg/server/admin/admin.go +++ b/pkg/server/admin/admin.go @@ -116,12 +116,15 @@ func (admin *Admin) AddAgent(hostKey []byte, publicId models.RendezVousId, agent message = "The server allocated a new id." } publicId = newPublicId - comms.SendRegistrationMessage(conn, comms.AgentRegistration{ + err := comms.SendRegistrationMessage(conn, comms.AgentRegistration{ Ok: true, Message: message, Id: string(publicId), HostPrivateKey: hostKey, }) + if err != nil { + return nil, err + } } else { comms.SendRegistrationMessage(conn, comms.AgentRegistration{ Ok: false, diff --git a/pkg/server/admin/admin_test.go b/pkg/server/admin/admin_test.go new file mode 100644 index 0000000..5392e54 --- /dev/null +++ b/pkg/server/admin/admin_test.go @@ -0,0 +1,108 @@ +package admin + +import ( + "context" + "crypto/rand" + "git.wamblee.org/converge/pkg/comms" + "git.wamblee.org/converge/pkg/models" + "git.wamblee.org/converge/pkg/testsupport" + "github.com/stretchr/testify/suite" + "io" + "net/http" + "testing" + "time" +) + +// test cases +// +// Agent only: verify state, verify agentregistration message +// - Connect single agent +// - Connect agent, connect second agent with duplicate id +// -> new id taken out +// - Connect more than 100 agents with the same id +// -> 101th agents gets error +// +// Client connected to agent: Verify clientConnection and agentCOnnection, verify state, verify clientInfo message. +// - Connect agent + connect client with mmtching id +// - Connect agent + connect client with wrong id +// +// Overall: +// - Connect agent, connect 2 clients +// - Connect multiple agents and clients + +type AdminTestSuite struct { + suite.Suite + + ctx context.Context + cancelFunc context.CancelFunc + pprofServer *http.Server + + agentReadWriter io.ReadWriteCloser + serverReadWriter io.ReadWriteCloser + + admin *Admin + hostKey []byte +} + +func (s *AdminTestSuite) SetupSuite() { + s.pprofServer = testsupport.StartPprof("") +} + +func (s *AdminTestSuite) TearDownSuite() { + testsupport.StopPprof(s.ctx, s.pprofServer) +} + +func (s *AdminTestSuite) SetupTest() { + ctx, cancelFunc := testsupport.CreateTestContext(context.Background(), 10*time.Second) + s.ctx = ctx + s.cancelFunc = cancelFunc + + // Could have also used net.Pipe but net.Pipe uses synchronous communication + // by default and the bitpipe implementation can become asynchronous when + // a channels ize > 0 is passed in. Also the test utility respects the context + // so also deals with cancellation much better than net.Pipe. + bitpipe := testsupport.NewInmemoryConnection(s.ctx, "inmemory", 10) + agentReadWriter := bitpipe.Front() + serverReadWriter := bitpipe.Back() + s.agentReadWriter = agentReadWriter + s.serverReadWriter = serverReadWriter + + s.admin = NewAdmin() + s.hostKey = make([]byte, 100) + rand.Read(s.hostKey) +} + +func (suite *AdminTestSuite) TearDownTest() { +} + +func TestAdminTestSuite(t *testing.T) { + suite.Run(t, &AdminTestSuite{}) +} + +func (s *AdminTestSuite) Test_AgentRegisters() { + publicId := "abc" + testsupport.RunAndWait( + &s.Suite, + func() any { + agentConn, err := s.admin.AddAgent(s.hostKey, models.RendezVousId(publicId), comms.EnvironmentInfo{}, s.serverReadWriter) + s.Nil(err) + s.Equal(publicId, string(agentConn.Info.PublicId)) + state := s.admin.CreateNotifification() + s.Equal(1, len(state.Agents)) + s.Equal(0, len(state.Clients)) + s.Equal(agentConn.Info, state.Agents[agentConn.Info.Guid]) + return nil + }, + func() any { + // verify registration message received + agentRegistration, err := comms.ReceiveRegistrationMessage(s.agentReadWriter) + s.Nil(err) + s.True(agentRegistration.Ok) + s.Equal(s.hostKey, agentRegistration.HostPrivateKey) + + commChannel, err := comms.NewCommChannel(comms.Agent, s.agentReadWriter) + s.Nil(err) + s.NotNil(commChannel) + return nil + }) +}