diff --git a/proto/snpb/replicator.go b/proto/snpb/replicator.go index 6d9800cf8..f146355f0 100644 --- a/proto/snpb/replicator.go +++ b/proto/snpb/replicator.go @@ -6,26 +6,42 @@ import ( "github.com/kakao/varlog/pkg/types" ) +// InvalidSyncPosition returns a SyncPosition with both LLSN and GLSN set to +// types.InvalidGLSN. func InvalidSyncPosition() SyncPosition { return SyncPosition{LLSN: types.InvalidLLSN, GLSN: types.InvalidGLSN} } +// Invalid checks if the SyncPosition is invalid. A SyncPosition is considered +// invalid if either LLSN or GLSN is invalid. func (sp SyncPosition) Invalid() bool { return sp.LLSN.Invalid() || sp.GLSN.Invalid() } +// LessThan checks if the current SyncPosition "sp" is less than another +// SyncPosition "other". It returns true if both LLSN and GLSN of the current +// SyncPosition are less than those of the other SyncPosition. func (sp SyncPosition) LessThan(other SyncPosition) bool { return sp.LLSN < other.LLSN && sp.GLSN < other.GLSN } +// InvalidSyncRange returns a SyncRange with both FirstLLSN and LastLLSN set to +// types.InvalidLLSN. func InvalidSyncRange() SyncRange { return SyncRange{FirstLLSN: types.InvalidLLSN, LastLLSN: types.InvalidLLSN} } +// Invalid determines if the SyncRange is invalid. A SyncRange is considered +// invalid if either FirstLLSN or LastLLSN is invalid, or if FirstLLSN is +// greater than LastLLSN. func (sr SyncRange) Invalid() bool { return sr.FirstLLSN.Invalid() || sr.LastLLSN.Invalid() || sr.FirstLLSN > sr.LastLLSN } +// Validate checks the validity of the SyncRange. It returns an error if +// FirstLLSN is greater than LastLLSN, or if FirstLLSN is invalid while +// LastLLSN is valid. If both FirstLLSN and LastLLSN are invalid, it returns +// nil, indicating that the entire log range is considered trimmed. func (sr SyncRange) Validate() error { if sr.FirstLLSN > sr.LastLLSN { return fmt.Errorf("invalid sync range: first %d, last %d", sr.FirstLLSN, sr.LastLLSN) diff --git a/proto/snpb/replicator_test.go b/proto/snpb/replicator_test.go index 437c06d5d..5915e3876 100644 --- a/proto/snpb/replicator_test.go +++ b/proto/snpb/replicator_test.go @@ -4,6 +4,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/kakao/varlog/pkg/types" ) func TestSyncPositionInvalid(t *testing.T) { @@ -80,3 +82,73 @@ func TestSyncPositionLessThan(t *testing.T) { }) } } + +func TestInvalidSyncRange(t *testing.T) { + sr := InvalidSyncRange() + require.True(t, sr.Invalid()) +} + +func TestSyncRangeInvalid(t *testing.T) { + tcs := []struct { + sr SyncRange + expected bool + }{ + { + sr: SyncRange{FirstLLSN: types.InvalidLLSN, LastLLSN: types.InvalidLLSN}, + expected: true, + }, + { + sr: SyncRange{FirstLLSN: types.LLSN(1), LastLLSN: types.InvalidLLSN}, + expected: true, + }, + { + sr: SyncRange{FirstLLSN: types.InvalidLLSN, LastLLSN: types.LLSN(1)}, + expected: true, + }, + { + sr: SyncRange{FirstLLSN: types.LLSN(2), LastLLSN: types.LLSN(1)}, + expected: true, + }, + { + sr: SyncRange{FirstLLSN: types.LLSN(1), LastLLSN: types.LLSN(2)}, + expected: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.sr.String(), func(t *testing.T) { + require.Equal(t, tc.expected, tc.sr.Invalid()) + }) + } +} + +func TestSyncRangeValidate(t *testing.T) { + tcs := []struct { + sr SyncRange + wantErr bool + }{ + { + sr: SyncRange{FirstLLSN: types.LLSN(2), LastLLSN: types.LLSN(1)}, + wantErr: true, + }, + { + sr: SyncRange{FirstLLSN: types.InvalidLLSN, LastLLSN: types.LLSN(1)}, + wantErr: true, + }, + { + sr: SyncRange{FirstLLSN: types.LLSN(1), LastLLSN: types.LLSN(2)}, + wantErr: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.sr.String(), func(t *testing.T) { + err := tc.sr.Validate() + if tc.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + }) + } +}