From ba94afbd7184c80c32434f63b2f1ff50f9db0333 Mon Sep 17 00:00:00 2001 From: Injun Song Date: Fri, 22 Nov 2024 18:29:23 +0900 Subject: [PATCH] test: add missing tests for proto/snpb.(LogStreamUncommitReport) --- proto/snpb/log_stream_reporter.go | 23 +++++ proto/snpb/log_stream_reporter_test.go | 134 +++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 proto/snpb/log_stream_reporter_test.go diff --git a/proto/snpb/log_stream_reporter.go b/proto/snpb/log_stream_reporter.go index c4d633d29..174435614 100644 --- a/proto/snpb/log_stream_reporter.go +++ b/proto/snpb/log_stream_reporter.go @@ -6,6 +6,7 @@ import ( // InvalidLogStreamUncommitReport is empty report. Do **NOT** modify this. var InvalidLogStreamUncommitReport = LogStreamUncommitReport{} + var InvalidLogStreamCommitResult = LogStreamCommitResult{} // Invalid returns whether the LogStreamUncommitReport is acceptable. @@ -15,6 +16,13 @@ func (m *LogStreamUncommitReport) Invalid() bool { return m.GetLogStreamID().Invalid() || m.GetUncommittedLLSNOffset().Invalid() } +// UncommittedLLSNEnd returns the exclusive end of uncommitted LLSN spans. If +// the LogStreamUncommitReport is nil, it returns types.InvalidLLSN. Otherwise, +// it calculates the end by adding the UncommittedLLSNOffset and the +// UncommittedLLSNLength. +// +// Example: If UncommittedLLSNOffset is 10 and UncommittedLLSNLength is 5, the +// method will return 15 (10 + 5). func (m *LogStreamUncommitReport) UncommittedLLSNEnd() types.LLSN { if m == nil { return types.InvalidLLSN @@ -23,6 +31,21 @@ func (m *LogStreamUncommitReport) UncommittedLLSNEnd() types.LLSN { return m.UncommittedLLSNOffset + types.LLSN(m.UncommittedLLSNLength) } +// Seal finalizes the uncommitted LLSN spans in the LogStreamUncommitReport up +// to the specified end LLSN. The 'end' parameter specifies the LLSN up to +// which the uncommitted spans should be sealed. The method returns the new end +// LLSN if the operation is successful, or types.InvalidLLSN if the provided +// end LLSN is invalid. +// +// This method adjusts the internal state to reflect that the spans up to 'end' +// are now sealed. If the LogStreamUncommitReport is nil, or if the provided +// end LLSN is outside the valid range (less than the starting offset or beyond +// the current uncommitted end), the method returns types.InvalidLLSN and makes +// no changes. +// +// For example, given a report with a starting offset of 10 and an uncommitted +// length of 5 (covering spans 10 to 15), calling Seal(12) will mark spans up +// to 12 as sealed, set the uncommitted length to 2 (12 - 10), and return 12. func (m *LogStreamUncommitReport) Seal(end types.LLSN) types.LLSN { if m == nil { return types.InvalidLLSN diff --git a/proto/snpb/log_stream_reporter_test.go b/proto/snpb/log_stream_reporter_test.go new file mode 100644 index 000000000..ed1c96c15 --- /dev/null +++ b/proto/snpb/log_stream_reporter_test.go @@ -0,0 +1,134 @@ +package snpb_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/kakao/varlog/pkg/types" + "github.com/kakao/varlog/proto/snpb" +) + +func TestLogStreamUncommitReport_Invalid(t *testing.T) { + tcs := []struct { + report *snpb.LogStreamUncommitReport + name string + want bool + }{ + { + name: "ValidReport", + report: &snpb.LogStreamUncommitReport{ + LogStreamID: types.MinLogStreamID, + UncommittedLLSNOffset: types.MinLLSN, + }, + want: false, + }, + { + name: "InvalidLogStreamID", + report: &snpb.LogStreamUncommitReport{ + LogStreamID: types.LogStreamID(0), + UncommittedLLSNOffset: types.MinLLSN, + }, + want: true, + }, + { + name: "InvalidUncommittedLLSNOffset", + report: &snpb.LogStreamUncommitReport{ + LogStreamID: types.MinLogStreamID, + UncommittedLLSNOffset: types.InvalidLLSN, + }, + want: true, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.want, tc.report.Invalid()) + }) + } +} + +func TestLogStreamUncommitReport_UncommittedLLSNEnd(t *testing.T) { + tcs := []struct { + report *snpb.LogStreamUncommitReport + name string + want types.LLSN + }{ + { + name: "NilReport", + report: nil, + want: types.InvalidLLSN, + }, + { + name: "ValidReport", + report: &snpb.LogStreamUncommitReport{ + UncommittedLLSNOffset: types.LLSN(10), + UncommittedLLSNLength: 5, + }, + want: types.LLSN(15), + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.want, tc.report.UncommittedLLSNEnd()) + }) + } +} + +func TestLogStreamUncommitReport_Seal(t *testing.T) { + tcs := []struct { + report *snpb.LogStreamUncommitReport + name string + end types.LLSN + want types.LLSN + wantLength uint64 + }{ + { + name: "NilReport", + report: nil, + end: types.LLSN(10), + want: types.InvalidLLSN, + wantLength: 0, + }, + { + name: "EndLessThanUncommittedOffset", + report: &snpb.LogStreamUncommitReport{ + UncommittedLLSNOffset: types.LLSN(10), + }, + end: types.LLSN(5), + want: types.InvalidLLSN, + wantLength: 0, + }, + { + name: "EndGreaterThanUncommittedEnd", + report: &snpb.LogStreamUncommitReport{ + UncommittedLLSNOffset: types.LLSN(10), + UncommittedLLSNLength: 5, + }, + end: types.LLSN(20), + want: types.InvalidLLSN, + wantLength: 5, + }, + { + name: "ValidSeal", + report: &snpb.LogStreamUncommitReport{ + UncommittedLLSNOffset: types.LLSN(10), + UncommittedLLSNLength: 5, + }, + end: types.LLSN(12), + want: types.LLSN(12), + wantLength: 2, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + got := tc.report.Seal(tc.end) + assert.Equal(t, tc.want, got) + if tc.report != nil { + assert.Equal(t, tc.wantLength, tc.report.UncommittedLLSNLength) + } + }) + } +}