1313package silence
1414
1515import (
16+ "bufio"
17+ "bytes"
1618 "testing"
1719 "time"
1820
1921 "github.com/stretchr/testify/require"
22+ "google.golang.org/protobuf/encoding/protodelim"
23+ "google.golang.org/protobuf/proto"
24+ "google.golang.org/protobuf/types/known/timestamppb"
25+
26+ pb "github.com/prometheus/alertmanager/silence/silencepb"
2027)
2128
2229func TestCurrentState (t * testing.T ) {
@@ -37,3 +44,44 @@ func TestCurrentState(t *testing.T) {
3744 expected = CurrentState (pastStartTime , pastEndTime )
3845 require .Equal (t , SilenceStateExpired , expected )
3946}
47+
48+ // TestStateMarshalBinaryPopulatesLegacyMatchers asserts that snapshots and
49+ // cluster local-state payloads written by state.MarshalBinary include the
50+ // deprecated Silence.Matchers field, so that older Alertmanagers that don't
51+ // understand MatcherSets still see the silence's first matcher set.
52+ func TestStateMarshalBinaryPopulatesLegacyMatchers (t * testing.T ) {
53+ now := time .Now ()
54+ matchers := []* pb.Matcher {
55+ {Name : "alertname" , Pattern : "Foo" , Type : pb .Matcher_EQUAL },
56+ {Name : "severity" , Pattern : "warn|crit" , Type : pb .Matcher_REGEXP },
57+ }
58+ sil := & pb.Silence {
59+ Id : "abc" ,
60+ MatcherSets : []* pb.MatcherSet {{Matchers : matchers }},
61+ StartsAt : timestamppb .New (now ),
62+ EndsAt : timestamppb .New (now .Add (time .Hour )),
63+ }
64+ st := state {sil .Id : & pb.MeshSilence {
65+ Silence : sil ,
66+ ExpiresAt : timestamppb .New (now .Add (2 * time .Hour )),
67+ }}
68+
69+ b , err := st .MarshalBinary ()
70+ require .NoError (t , err )
71+
72+ require .Nil (t , sil .Matchers , "MarshalBinary must not mutate in-memory silences" )
73+
74+ // Decode directly via protodelim, bypassing decodeState — decodeState
75+ // strips the legacy field, but we want to observe the on-the-wire shape.
76+ var got pb.MeshSilence
77+ require .NoError (t , protodelim .UnmarshalFrom (bufio .NewReader (bytes .NewReader (b )), & got ))
78+
79+ require .Len (t , got .Silence .MatcherSets , 1 )
80+ require .Len (t , got .Silence .Matchers , len (matchers ))
81+ for i , m := range matchers {
82+ require .True (t , proto .Equal (m , got .Silence .Matchers [i ]),
83+ "legacy Matchers[%d] mismatch" , i )
84+ require .True (t , proto .Equal (m , got .Silence .MatcherSets [0 ].Matchers [i ]),
85+ "MatcherSets[0].Matchers[%d] mismatch" , i )
86+ }
87+ }
0 commit comments