Repository: prometheus/alertmanager
File: silence/silence_test.go (Go)

Code before:
	// Expire sil2 and run the GC.
	require.NoError(t, s.Expire(sil2.Id))
	n, err = s.GC()
	require.NoError(t, err)
	require.Equal(t, 1, n)

	// Insert sil3 should fail because it exceeds maximum size.
	sil3 := &pb.Silence{
		Matchers: []*pb.Matcher{
			{
				Name:    strings.Repeat("e", 2<<9),
				Pattern: strings.Repeat("f", 2<<9),
			},
			{
				Name:    strings.Repeat("g", 2<<9),
				Pattern: strings.Repeat("h", 2<<9),
			},
		},
		CreatedBy: strings.Repeat("i", 2<<9),
		Comment:   strings.Repeat("j", 2<<9),
		StartsAt:  time.Now(),
		EndsAt:    time.Now().Add(5 * time.Minute),
	}
	require.EqualError(t, s.Set(sil3), fmt.Sprintf("silence exceeded maximum size: %d bytes (limit: 4096 bytes)", s.toMeshSilence(sil3).Size()))

	// Should be able to insert sil4.
	sil4 := &pb.Silence{
		Matchers: []*pb.Matcher{{Name: "k", Pattern: "l"}},
		StartsAt: time.Now(),
		EndsAt:   time.Now().Add(5 * time.Minute),
	}
	require.NoError(t, s.Set(sil4))

	// Should be able to update sil4 without modifications. It is expected to
	// keep the same ID.
	sil5 := cloneSilence(sil4)
	require.NoError(t, s.Set(sil5))
	require.Equal(t, sil4.Id, sil5.Id)

	// Should be able to update the comment. It is also expected to keep the
	// same ID.
	sil6 := cloneSilence(sil5)
	sil6.Comment = "m"
	require.NoError(t, s.Set(sil6))
	require.Equal(t, sil5.Id, sil6.Id)

	// Should not be able to update the start and end time as this requires
	// sil5 to be expired and a new silence to be created. However, this would
	// exceed the maximum number of silences, which counts both active and
	// expired silences.
	sil7 := cloneSilence(sil6)

Review comment (bug):
I added additional tests here to cover the following cases:

1. Updating an existing silence without modifications.
2. Adding a comment to an existing silence.
3. Failing to update an existing silence because the maximum number of silences has been exceeded should not expire the existing silence.

Code after:
	// Expire sil2 and run the GC.
	require.NoError(t, s.Expire(sil2.Id))
	n, err = s.GC()
	require.NoError(t, err)
	require.Equal(t, 1, n)

	// Insert sil3 should fail because it exceeds maximum size.
	sil3 := &pb.Silence{
		Matchers: []*pb.Matcher{
			{
				Name:    strings.Repeat("e", 2<<9),
				Pattern: strings.Repeat("f", 2<<9),
			},
			{
				Name:    strings.Repeat("g", 2<<9),
				Pattern: strings.Repeat("h", 2<<9),
			},
		},
		CreatedBy: strings.Repeat("i", 2<<9),
		Comment:   strings.Repeat("j", 2<<9),
		StartsAt:  time.Now(),
		EndsAt:    time.Now().Add(5 * time.Minute),
	}
	require.EqualError(t, s.Set(sil3), fmt.Sprintf("silence exceeded maximum size: %d bytes (limit: 4096 bytes)", s.toMeshSilence(sil3).Size()))

	// Should be able to insert sil4.
	sil4 := &pb.Silence{
		Matchers: []*pb.Matcher{{Name: "k", Pattern: "l"}},
		StartsAt: time.Now(),
		EndsAt:   time.Now().Add(5 * time.Minute),
	}
	require.NoError(t, s.Set(sil4))

	// Should be able to update sil4 without modifications. It is expected to
	// keep the same ID.
	sil5 := cloneSilence(sil4)
	require.NoError(t, s.Set(sil5))
	require.Equal(t, sil4.Id, sil5.Id)

	// Should be able to update the comment. It is also expected to keep the
	// same ID.
	sil6 := cloneSilence(sil5)
	sil6.Comment = "m"
	require.NoError(t, s.Set(sil6))
	require.Equal(t, sil5.Id, sil6.Id)

	// Should not be able to update the start and end time as this requires
	// sil6 to be expired and a new silence to be created. However, this would
	// exceed the maximum number of silences, which counts both active and
	// expired silences.
	sil7 := cloneSilence(sil6)