180 lines
4.8 KiB
Go
180 lines
4.8 KiB
Go
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"
|
|
"strings"
|
|
"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)
|
|
s.NotNil(rand.Read(s.hostKey))
|
|
}
|
|
|
|
func (suite *AdminTestSuite) TearDownTest() {
|
|
}
|
|
|
|
func TestAdminTestSuite(t *testing.T) {
|
|
suite.Run(t, &AdminTestSuite{})
|
|
}
|
|
|
|
type AddAgentResult struct {
|
|
agentConn *agentConnection
|
|
err error
|
|
}
|
|
|
|
type AgentRegisterResult struct {
|
|
registration comms.AgentRegistration
|
|
err error
|
|
}
|
|
|
|
func (s *AdminTestSuite) agentRegisters(requestedPublicId, assignedPublicId string) (AddAgentResult, AgentRegisterResult) {
|
|
agentRW, serverRW := s.createPipe()
|
|
res := testsupport.RunAndWait(
|
|
&s.Suite,
|
|
func() any {
|
|
agentConn, err := s.addAgent(requestedPublicId, assignedPublicId, serverRW)
|
|
return AddAgentResult{
|
|
agentConn: agentConn,
|
|
err: err,
|
|
}
|
|
},
|
|
func() any {
|
|
res := s.agentRegistration(assignedPublicId, agentRW)
|
|
if assignedPublicId != "" {
|
|
s.Nil(res.err)
|
|
s.True(res.registration.Ok)
|
|
s.Equal(s.hostKey, res.registration.HostPrivateKey)
|
|
}
|
|
return res
|
|
})
|
|
return res[0].(AddAgentResult), res[1].(AgentRegisterResult)
|
|
}
|
|
|
|
func (s *AdminTestSuite) Test_AgentRegisters() {
|
|
res, _ := s.agentRegisters("abc", "abc")
|
|
s.Nil(res.err)
|
|
agentConn := res.agentConn
|
|
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 {
|
|
res, _ := s.agentRegisters(publicId, publicId)
|
|
s.Nil(res.err)
|
|
return res.agentConn
|
|
}
|
|
}
|
|
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() {
|
|
res, _ := s.agentRegisters("abc", "abc")
|
|
s.Nil(res.err)
|
|
for i := range 100 {
|
|
res, _ = s.agentRegisters("abc", fmt.Sprintf("abc-%d", i))
|
|
s.Nil(res.err)
|
|
}
|
|
res, agentSideResult := s.agentRegisters("abc", "")
|
|
s.NotNil(res.err)
|
|
// verify it is the correct error an dnot an id mismatch.
|
|
s.True(strings.Contains(res.err.Error(), "could not allocate a new unique id"))
|
|
s.False(agentSideResult.registration.Ok)
|
|
}
|
|
|
|
func (s *AdminTestSuite) agentRegistration(expectedPublicId string, agentRW io.ReadWriteCloser) AgentRegisterResult {
|
|
// verify registration message received
|
|
agentRegistration, err := comms.ReceiveRegistrationMessage(agentRW)
|
|
if err != nil {
|
|
return AgentRegisterResult{err: err}
|
|
}
|
|
commChannel, err := comms.NewCommChannel(comms.Agent, agentRW)
|
|
if err != nil {
|
|
return AgentRegisterResult{registration: agentRegistration, err: err}
|
|
}
|
|
s.NotNil(commChannel)
|
|
return AgentRegisterResult{registration: agentRegistration, err: nil}
|
|
}
|
|
|
|
func (s *AdminTestSuite) addAgent(publicId string, assignedPublicId string, serverRW io.ReadWriteCloser) (*agentConnection, error) {
|
|
agentConn, err := s.admin.AddAgent(
|
|
s.hostKey, models.RendezVousId(publicId), comms.EnvironmentInfo{},
|
|
serverRW)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s.Equal(assignedPublicId, string(agentConn.Info.PublicId))
|
|
return agentConn, nil
|
|
}
|