Alerting: Add lifecycle methods to the forked Alertmanager (#77741)

* Alerting: Add an empty Forked Alertmanager

* Alerting: Add methods for silences to the forked Alertmanager

* check for errors in tests

* make linter happy

* Alerting: Add methods for alerts to the forked Alertmanager

* Alerting: Add methods for receivers to the forked Alertmanager

* Alerting: Add TestTemplate method to the forked Alertmanager

* make linter happy

* separate into both forked AMs

* fix tests

* Alerting: Add lifecycle methods to the forked Alertmanager
pull/78109/head
Santiago 2 years ago committed by GitHub
parent b6d6375e2b
commit 4a152a0e35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 86
      pkg/services/ngalert/remote/forked_alertmanager_test.go
  2. 18
      pkg/services/ngalert/remote/remote_primary_forked_alertmanager.go
  3. 18
      pkg/services/ngalert/remote/remote_secondary_forked_alertmanager.go

@ -21,6 +21,14 @@ func TestForkedAlertmanager_ModeRemoteSecondary(t *testing.T) {
ctx := context.Background()
expErr := errors.New("test error")
t.Run("GetStatus", func(tt *testing.T) {
// We care about the status of the internal Alertmanager.
internal, _, forked := genTestAlertmanagers(tt, modeRemoteSecondary)
status := apimodels.GettableStatus{}
internal.EXPECT().GetStatus().Return(status).Once()
require.Equal(tt, status, forked.GetStatus())
})
t.Run("CreateSilence", func(tt *testing.T) {
// We should create the silence in the internal Alertmanager.
internal, _, forked := genTestAlertmanagers(tt, modeRemoteSecondary)
@ -207,12 +215,55 @@ func TestForkedAlertmanager_ModeRemoteSecondary(t *testing.T) {
_, err = forked.TestTemplate(ctx, apimodels.TestTemplatesConfigBodyParams{})
require.ErrorIs(tt, expErr, err)
})
t.Run("CleanUp", func(tt *testing.T) {
// CleanUp() should be called only in the internal Alertmanager,
// there's no cleanup to do in the remote one.
internal, _, forked := genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().CleanUp().Once()
forked.CleanUp()
})
t.Run("StopAndWait", func(tt *testing.T) {
// StopAndWait should be called in both Alertmanagers.
internal, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().StopAndWait().Once()
remote.EXPECT().StopAndWait().Once()
forked.StopAndWait()
})
t.Run("Ready", func(tt *testing.T) {
// Ready should be called on both Alertmanagers
internal, remote, forked := genTestAlertmanagers(tt, modeRemoteSecondary)
internal.EXPECT().Ready().Return(true).Once()
remote.EXPECT().Ready().Return(true).Once()
require.True(tt, forked.Ready())
// If one of the two Alertmanagers is not ready, it returns false.
internal, remote, forked = genTestAlertmanagers(tt, modeRemoteSecondary)
internal.EXPECT().Ready().Return(false).Maybe()
remote.EXPECT().Ready().Return(true).Maybe()
require.False(tt, forked.Ready())
internal, remote, forked = genTestAlertmanagers(tt, modeRemoteSecondary)
internal.EXPECT().Ready().Return(true).Maybe()
remote.EXPECT().Ready().Return(false).Maybe()
require.False(tt, forked.Ready())
})
}
func TestForkedAlertmanager_ModeRemotePrimary(t *testing.T) {
ctx := context.Background()
expErr := errors.New("test error")
t.Run("GetStatus", func(tt *testing.T) {
// We care about the status of the remote Alertmanager.
_, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
status := apimodels.GettableStatus{}
remote.EXPECT().GetStatus().Return(status).Once()
require.Equal(tt, status, forked.GetStatus())
})
t.Run("CreateSilence", func(tt *testing.T) {
// We should create the silence in the remote Alertmanager.
_, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
@ -396,6 +447,41 @@ func TestForkedAlertmanager_ModeRemotePrimary(t *testing.T) {
_, err = forked.TestTemplate(ctx, apimodels.TestTemplatesConfigBodyParams{})
require.ErrorIs(tt, expErr, err)
})
t.Run("CleanUp", func(tt *testing.T) {
// CleanUp() should be called only in the internal Alertmanager,
// there's no cleanup to do in the remote one.
internal, _, forked := genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().CleanUp().Once()
forked.CleanUp()
})
t.Run("StopAndWait", func(tt *testing.T) {
// StopAndWait should be called in both Alertmanagers.
internal, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().StopAndWait().Once()
remote.EXPECT().StopAndWait().Once()
forked.StopAndWait()
})
t.Run("Ready", func(tt *testing.T) {
// Ready should be called on both Alertmanagers
internal, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().Ready().Return(true).Once()
remote.EXPECT().Ready().Return(true).Once()
require.True(tt, forked.Ready())
// If one of the two Alertmanagers is not ready, it returns false.
internal, remote, forked = genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().Ready().Return(false).Maybe()
remote.EXPECT().Ready().Return(true).Maybe()
require.False(tt, forked.Ready())
internal, remote, forked = genTestAlertmanagers(tt, modeRemotePrimary)
internal.EXPECT().Ready().Return(true).Maybe()
remote.EXPECT().Ready().Return(false).Maybe()
require.False(tt, forked.Ready())
})
}
func genTestAlertmanagers(t *testing.T, mode int) (*alertmanager_mock.AlertmanagerMock, *alertmanager_mock.AlertmanagerMock, notifier.Alertmanager) {
t.Helper()

@ -33,7 +33,7 @@ func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyDefaultConfig(ctx contex
}
func (fam *RemotePrimaryForkedAlertmanager) GetStatus() apimodels.GettableStatus {
return apimodels.GettableStatus{}
return fam.remote.GetStatus()
}
func (fam *RemotePrimaryForkedAlertmanager) CreateSilence(ctx context.Context, silence *apimodels.PostableSilence) (string, error) {
@ -76,10 +76,20 @@ func (fam *RemotePrimaryForkedAlertmanager) TestTemplate(ctx context.Context, c
return fam.remote.TestTemplate(ctx, c)
}
func (fam *RemotePrimaryForkedAlertmanager) CleanUp() {}
func (fam *RemotePrimaryForkedAlertmanager) CleanUp() {
// No cleanup to do in the remote Alertmanager.
fam.internal.CleanUp()
}
func (fam *RemotePrimaryForkedAlertmanager) StopAndWait() {}
func (fam *RemotePrimaryForkedAlertmanager) StopAndWait() {
fam.internal.StopAndWait()
fam.remote.StopAndWait()
}
func (fam *RemotePrimaryForkedAlertmanager) Ready() bool {
return false
// Both Alertmanagers must be ready.
if ready := fam.remote.Ready(); !ready {
return false
}
return fam.internal.Ready()
}

@ -33,7 +33,7 @@ func (fam *RemoteSecondaryForkedAlertmanager) SaveAndApplyDefaultConfig(ctx cont
}
func (fam *RemoteSecondaryForkedAlertmanager) GetStatus() apimodels.GettableStatus {
return apimodels.GettableStatus{}
return fam.internal.GetStatus()
}
func (fam *RemoteSecondaryForkedAlertmanager) CreateSilence(ctx context.Context, silence *apimodels.PostableSilence) (string, error) {
@ -76,10 +76,20 @@ func (fam *RemoteSecondaryForkedAlertmanager) TestTemplate(ctx context.Context,
return fam.internal.TestTemplate(ctx, c)
}
func (fam *RemoteSecondaryForkedAlertmanager) CleanUp() {}
func (fam *RemoteSecondaryForkedAlertmanager) CleanUp() {
// No cleanup to do in the remote Alertmanager.
fam.internal.CleanUp()
}
func (fam *RemoteSecondaryForkedAlertmanager) StopAndWait() {}
func (fam *RemoteSecondaryForkedAlertmanager) StopAndWait() {
fam.internal.StopAndWait()
fam.remote.StopAndWait()
}
func (fam *RemoteSecondaryForkedAlertmanager) Ready() bool {
return false
// Both Alertmanagers must be ready.
if ready := fam.remote.Ready(); !ready {
return false
}
return fam.internal.Ready()
}

Loading…
Cancel
Save