Skip to content

Commit

Permalink
GOCBC-941: Add waituntilready http ready check for management service
Browse files Browse the repository at this point in the history
Motivation
----------
In cluster agent we request that the diagnostics component check
the management service for WaitUntilReady. The diagnostics
component adds a wait for the service but never checks if it's
ready.

Changes
-------
Add checkHTTPReady call for the management service.
Add tests for WaitUntilReady against agent and agent group.

Change-Id: I425b83e1424d9b1a689f84d2ea1f0e6a0375d59b
Reviewed-on: http://review.couchbase.org/c/gocbcore/+/131524
Reviewed-by: Brett Lawson <brett19@gmail.com>
Tested-by: Charles Dixon <chvckd@gmail.com>
  • Loading branch information
chvck committed Jun 30, 2020
1 parent 6512bd1 commit 50ee256
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 0 deletions.
172 changes: 172 additions & 0 deletions agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,178 @@ func (suite *StandardTestSuite) TestAlternateAddressesInvalidConfig() {
}
}

func (suite *StandardTestSuite) TestAgentWaitUntilReadyGCCCP() {
suite.EnsureSupportsFeature(TestFeatureGCCCP)

cfg := suite.makeAgentConfig(globalTestConfig)
agent, err := CreateAgent(&cfg)
suite.Require().Nil(err, err)
defer agent.Close()
s := suite.GetHarness()

s.PushOp(agent.WaitUntilReady(time.Now().Add(5*time.Second), WaitUntilReadyOptions{}, func(result *WaitUntilReadyResult, err error) {
s.Wrap(func() {
if err != nil {
s.Fatalf("WaitUntilReady failed with error: %v", err)
}
})
}))
s.Wait(6)

report, err := agent.Diagnostics(DiagnosticsOptions{})
suite.Require().Nil(err, err)

suite.Assert().Greater(report.ConfigRev, int64(0))
suite.Assert().Equal(ClusterStateOnline, report.State)

if len(report.MemdConns) == 0 {
suite.T().Fatalf("Diagnostics report contained no results")
}

for _, conn := range report.MemdConns {
suite.Assert().NotEmpty(conn.RemoteAddr)
suite.Assert().Equal(EndpointStateConnected, conn.State)
}

// We can't run a set on a gcccp connection
}

func (suite *StandardTestSuite) TestAgentWaitUntilReadyBucket() {
cfg := suite.makeAgentConfig(globalTestConfig)
cfg.BucketName = globalTestConfig.BucketName
agent, err := CreateAgent(&cfg)
suite.Require().Nil(err, err)
defer agent.Close()
s := suite.GetHarness()

s.PushOp(agent.WaitUntilReady(time.Now().Add(5*time.Second), WaitUntilReadyOptions{}, func(result *WaitUntilReadyResult, err error) {
s.Wrap(func() {
if err != nil {
s.Fatalf("WaitUntilReady failed with error: %v", err)
}
})
}))
s.Wait(6)

report, err := agent.Diagnostics(DiagnosticsOptions{})
suite.Require().Nil(err, err)

suite.Assert().Greater(report.ConfigRev, int64(0))
suite.Assert().Equal(ClusterStateOnline, report.State)

if len(report.MemdConns) == 0 {
suite.T().Fatalf("Diagnostics report contained no results")
}

for _, conn := range report.MemdConns {
suite.Assert().NotEmpty(conn.RemoteAddr)
suite.Assert().Equal(EndpointStateConnected, conn.State)
}

s.PushOp(agent.Set(SetOptions{
Key: []byte("TestAgentWaitUntilReadyBucket"),
Value: []byte(""),
CollectionName: suite.CollectionName,
ScopeName: suite.ScopeName,
}, func(res *StoreResult, err error) {
s.Wrap(func() {
if err != nil {
s.Fatalf("Got error for Set: %v", err)
}
})
}))
s.Wait(0)
}

func (suite *StandardTestSuite) TestAgentGroupWaitUntilReadyGCCCP() {
suite.EnsureSupportsFeature(TestFeatureGCCCP)

cfg := suite.makeAgentGroupConfig(globalTestConfig)
ag, err := CreateAgentGroup(&cfg)
suite.Require().Nil(err, err)
defer ag.Close()
s := suite.GetHarness()

s.PushOp(ag.WaitUntilReady(time.Now().Add(5*time.Second), WaitUntilReadyOptions{}, func(result *WaitUntilReadyResult, err error) {
s.Wrap(func() {
if err != nil {
s.Fatalf("WaitUntilReady failed with error: %v", err)
}
})
}))
s.Wait(6)

report, err := ag.Diagnostics(DiagnosticsOptions{})
suite.Require().Nil(err, err)

suite.Assert().Greater(report.ConfigRev, int64(0))
suite.Assert().Equal(ClusterStateOnline, report.State)

if len(report.MemdConns) == 0 {
suite.T().Fatalf("Diagnostics report contained no results")
}

for _, conn := range report.MemdConns {
suite.Assert().NotEmpty(conn.RemoteAddr)
suite.Assert().Equal(EndpointStateConnected, conn.State)
}
}

// This test cannot run against mock as the mock does not respond with 200 status code for all of the endpoints.
func (suite *StandardTestSuite) TestAgentGroupWaitUntilReadyBucket() {
suite.EnsureSupportsFeature(TestFeaturePingServices)

cfg := suite.makeAgentGroupConfig(globalTestConfig)
ag, err := CreateAgentGroup(&cfg)
suite.Require().Nil(err, err)
defer ag.Close()
s := suite.GetHarness()

err = ag.OpenBucket(globalTestConfig.BucketName)
suite.Require().Nil(err, err)

s.PushOp(ag.WaitUntilReady(time.Now().Add(5*time.Second), WaitUntilReadyOptions{}, func(result *WaitUntilReadyResult, err error) {
s.Wrap(func() {
if err != nil {
s.Fatalf("WaitUntilReady failed with error: %v", err)
}
})
}))
s.Wait(6)

agent := ag.GetAgent("default")
suite.Require().NotNil(agent)

report, err := agent.Diagnostics(DiagnosticsOptions{})
suite.Require().Nil(err, err)

suite.Assert().Greater(report.ConfigRev, int64(0))
suite.Assert().Equal(ClusterStateOnline, report.State)

if len(report.MemdConns) == 0 {
suite.T().Fatalf("Diagnostics report contained no results")
}

for _, conn := range report.MemdConns {
suite.Assert().NotEmpty(conn.RemoteAddr)
suite.Assert().Equal(EndpointStateConnected, conn.State)
}

s.PushOp(agent.Set(SetOptions{
Key: []byte("TestAgentGroupWaitUntilReadyBucket"),
Value: []byte(""),
CollectionName: suite.CollectionName,
ScopeName: suite.ScopeName,
}, func(res *StoreResult, err error) {
s.Wrap(func() {
if err != nil {
s.Fatalf("Got error for Set: %v", err)
}
})
}))
s.Wait(0)
}

// These functions are likely temporary.

type testManifestWithError struct {
Expand Down
6 changes: 6 additions & 0 deletions diagnosticscomponent.go
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,8 @@ func (dc *diagnosticsComponent) checkHTTPReady(ctx context.Context, service Serv
path = "/api/ping"
case CapiService:
path = "/"
case MgmtService:
path = ""
}

for {
Expand All @@ -565,6 +567,8 @@ func (dc *diagnosticsComponent) checkHTTPReady(ctx context.Context, service Serv
epList = clientMux.ftsEpList
case CapiService:
epList = dc.endpointsFromCapiList(clientMux.capiEpList)
case MgmtService:
epList = clientMux.mgmtEpList
}

connected := uint32(0)
Expand Down Expand Up @@ -693,6 +697,8 @@ func (dc *diagnosticsComponent) WaitUntilReady(deadline time.Time, opts WaitUnti
go dc.checkHTTPReady(ctx, FtsService, interval, desiredState, op)
case CbasService:
go dc.checkHTTPReady(ctx, CbasService, interval, desiredState, op)
case MgmtService:
go dc.checkHTTPReady(ctx, MgmtService, interval, desiredState, op)
}
}

Expand Down
2 changes: 2 additions & 0 deletions testharness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ var (
TestFeatureDCPDeleteTimes = TestFeatureCode("dcpdeletetimes")
TestFeatureMemd = TestFeatureCode("memd")
TestFeatureGetMeta = TestFeatureCode("getmeta")
TestFeatureGCCCP = TestFeatureCode("gcccp")
TestFeaturePingServices = TestFeatureCode("pingservices")
)

type TestFeatureFlag struct {
Expand Down
21 changes: 21 additions & 0 deletions teststandardsuite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ func (suite *StandardTestSuite) SupportsFeature(feature TestFeatureCode) bool {
return !suite.IsMockServer() && (suite.ClusterVersion.Equal(srvVer650DP) || !suite.ClusterVersion.Lower(srvVer700))
case TestFeatureGetMeta:
return !suite.IsMockServer()
case TestFeatureGCCCP:
return !suite.IsMockServer() && !suite.ClusterVersion.Lower(srvVer650)
case TestFeaturePingServices:
return !suite.IsMockServer()
}

panic("found unsupported feature code")
Expand Down Expand Up @@ -162,6 +166,23 @@ func (suite *StandardTestSuite) LoadConfigFromFile(filename string) (cfg *cfgBuc
return
}

func (suite *StandardTestSuite) makeAgentConfig(testConfig *TestConfig) AgentConfig {
config := AgentConfig{}
config.FromConnStr(testConfig.ConnStr)

config.UseMutationTokens = true
config.UseCollections = true
config.UseOutOfOrderResponses = true

config.Auth = testConfig.Authenticator

if testConfig.CAProvider != nil {
config.TLSRootCAProvider = testConfig.CAProvider
}

return config
}

func (suite *StandardTestSuite) makeAgentGroupConfig(testConfig *TestConfig) AgentGroupConfig {
config := AgentGroupConfig{}
config.FromConnStr(testConfig.ConnStr)
Expand Down

0 comments on commit 50ee256

Please sign in to comment.