diff --git a/internal/hcp/internal/controllers/telemetrystate/controller_test.go b/internal/hcp/internal/controllers/telemetrystate/controller_test.go index 84df8a27c4..e11c1e3063 100644 --- a/internal/hcp/internal/controllers/telemetrystate/controller_test.go +++ b/internal/hcp/internal/controllers/telemetrystate/controller_test.go @@ -33,8 +33,10 @@ type controllerSuite struct { client *rtest.Client rt controller.Runtime - ctl telemetryStateReconciler + ctl *controller.TestController tenancies []*pbresource.Tenancy + + hcpMock *hcpclient.MockClient } func mockHcpClientFn(t *testing.T) (*hcpclient.MockClient, link.HCPClientFn) { @@ -55,10 +57,12 @@ func (suite *controllerSuite) SetupTest() { WithTenancies(suite.tenancies...). Run(suite.T()) - suite.rt = controller.Runtime{ - Client: client, - Logger: testutil.Logger(suite.T()), - } + hcpMock, hcpClientFn := mockHcpClientFn(suite.T()) + suite.hcpMock = hcpMock + suite.ctl = controller.NewTestController(TelemetryStateController(hcpClientFn), client). + WithLogger(testutil.Logger(suite.T())) + + suite.rt = suite.ctl.Runtime() suite.client = rtest.NewClient(client) } @@ -93,23 +97,12 @@ func (suite *controllerSuite) TestController_Ok() { mgr.SetRaftLeader(true) go mgr.Run(suite.ctx) - linkData := &pbhcp.Link{ - ClientId: "abc", - ClientSecret: "abc", - ResourceId: types.GenerateTestResourceID(suite.T()), - } - - link := rtest.Resource(pbhcp.LinkType, "global"). - WithData(suite.T(), linkData). - WithStatus(link.StatusKey, &pbresource.Status{Conditions: []*pbresource.Condition{link.ConditionLinked(linkData.ResourceId)}}). - Write(suite.T(), suite.client) - - suite.T().Cleanup(suite.deleteResourceFunc(link.Id)) + link := suite.writeLinkResource() tsRes := suite.client.WaitForResourceExists(suite.T(), &pbresource.ID{Name: "global", Type: pbhcp.TelemetryStateType}) decodedState, err := resource.Decode[*pbhcp.TelemetryState](tsRes) require.NoError(suite.T(), err) - require.Equal(suite.T(), linkData.ResourceId, decodedState.GetData().ResourceId) + require.Equal(suite.T(), link.GetData().GetResourceId(), decodedState.GetData().ResourceId) require.Equal(suite.T(), "xxx", decodedState.GetData().ClientId) require.Equal(suite.T(), "http://localhost/test", decodedState.GetData().Metrics.Endpoint) @@ -117,6 +110,27 @@ func (suite *controllerSuite) TestController_Ok() { suite.client.WaitForDeletion(suite.T(), tsRes.Id) } +func (suite *controllerSuite) TestReconcile_AvoidReconciliationWriteLoop() { + suite.hcpMock.EXPECT().FetchTelemetryConfig(mock.Anything).Return(&hcpclient.TelemetryConfig{ + MetricsConfig: &hcpclient.MetricsConfig{ + Endpoint: &url.URL{ + Scheme: "http", + Host: "localhost", + Path: "/test", + }, + Labels: map[string]string{"foo": "bar"}, + Filters: regexp.MustCompile(".*"), + }, + RefreshConfig: &hcpclient.RefreshConfig{}, + }, nil) + link := suite.writeLinkResource() + suite.hcpMock.EXPECT().GetObservabilitySecret(mock.Anything).Return("xxx", "yyy", nil) + suite.NoError(suite.ctl.Reconcile(context.Background(), controller.Request{ID: link.Id})) + tsRes := suite.client.WaitForResourceExists(suite.T(), &pbresource.ID{Name: "global", Type: pbhcp.TelemetryStateType}) + suite.NoError(suite.ctl.Reconcile(context.Background(), controller.Request{ID: tsRes.Id})) + suite.client.RequireVersionUnchanged(suite.T(), tsRes.Id, tsRes.Version) +} + func (suite *controllerSuite) TestController_LinkingDisabled() { // Run the controller manager mgr := controller.NewManager(suite.client, suite.rt.Logger) @@ -138,3 +152,23 @@ func (suite *controllerSuite) TestController_LinkingDisabled() { suite.client.WaitForDeletion(suite.T(), &pbresource.ID{Name: "global", Type: pbhcp.TelemetryStateType}) } + +func (suite *controllerSuite) writeLinkResource() *types.DecodedLink { + suite.T().Helper() + + linkData := &pbhcp.Link{ + ClientId: "abc", + ClientSecret: "abc", + ResourceId: types.GenerateTestResourceID(suite.T()), + } + + res := rtest.Resource(pbhcp.LinkType, "global"). + WithData(suite.T(), linkData). + WithStatus(link.StatusKey, &pbresource.Status{Conditions: []*pbresource.Condition{link.ConditionLinked(linkData.ResourceId)}}). + Write(suite.T(), suite.client) + + suite.T().Cleanup(suite.deleteResourceFunc(res.Id)) + link, err := resource.Decode[*pbhcp.Link](res) + require.NoError(suite.T(), err) + return link +}