package admin import ( "context" "crypto/rand" "fmt" "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 admin *Admin hostKey []byte } func (s *AdminTestSuite) createPipe() (io.ReadWriteCloser, io.ReadWriteCloser) { bitpipe := testsupport.NewInmemoryConnection(s.ctx, "inmemory", 10) return bitpipe.Front(), bitpipe.Back() } 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 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) agentRegisters(requestedPublicId, assignedPublicId string) *agentConnection { agentRW, serverRW := s.createPipe() res := testsupport.RunAndWait( &s.Suite, func() any { return s.addAgent(requestedPublicId, assignedPublicId, serverRW) }, func() any { return s.agentRegistration(assignedPublicId, agentRW) }) return res[0].(*agentConnection) } func (s *AdminTestSuite) Test_AgentRegisters() { agentConn := s.agentRegisters("abc", "abc") 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]) } func (s *AdminTestSuite) Test_ManyAgentsRegister() { N := 10 agentRegistrations := make([]testsupport.TestFunction, N) for i := range N { publicId := fmt.Sprintf("abc%d", i) agentRegistrations[i] = func() any { return s.agentRegisters(publicId, publicId) } } res := testsupport.RunAndWait( &s.Suite, agentRegistrations...) state := s.admin.CreateNotifification() s.Equal(len(res), len(state.Agents)) s.Equal(0, len(state.Clients)) for _, entry := range res { agentConn := entry.(*agentConnection) s.Equal(agentConn.Info, state.Agents[agentConn.Info.Guid]) } } func (s *AdminTestSuite) Test_agentDuplicateId() { s.agentRegisters("abc", "abc") s.agentRegisters("abc", "abc-0") } func (s *AdminTestSuite) agentRegistration(expectedPublicId string, agentRW io.ReadWriteCloser) any { // verify registration message received agentRegistration, err := comms.ReceiveRegistrationMessage(agentRW) s.Nil(err) s.True(agentRegistration.Ok) s.Equal(expectedPublicId, agentRegistration.Id) s.Equal(s.hostKey, agentRegistration.HostPrivateKey) commChannel, err := comms.NewCommChannel(comms.Agent, agentRW) s.Nil(err) s.NotNil(commChannel) return nil } func (s *AdminTestSuite) addAgent(publicId string, assignedPublicId string, serverRW io.ReadWriteCloser) any { agentConn, err := s.admin.AddAgent( s.hostKey, models.RendezVousId(publicId), comms.EnvironmentInfo{}, serverRW) s.Nil(err) s.Equal(assignedPublicId, string(agentConn.Info.PublicId)) return agentConn }