@@ -123,18 +123,18 @@ func TestReadGaps(t *testing.T) {
123123
124124 t .Run ("BasicGapReading" , func (t * testing.T ) {
125125 rl := state.RangeList {
126- state .NewRange (0 , 1 ),
127- state .NewRange (4 , 5 ),
126+ // Inverted range: 0-5, 10-15, 20-25, 30-inf
127+ state .NewRange (5 , 10 ),
128+ state .NewRange (15 , 20 ),
129+ state .NewRange (25 , 30 ),
128130 }
129131 elog , stateFileName := newTestEventLogWithState (t , NAME , LEVELS , rl )
130132 mockAPI := NewMockWindowsEventAPI ()
131133 winEventAPI = mockAPI
132134
133- // This is per EvtHandle hence the necessity to break up these calls
134- // 0, 1, 4 were "sent" previously (should be skipped)
135- mockAPI .AddMockEventsForQuery (createMockEventRecords (0 , 1 , 4 , 5 ))
136- // Gap records (should be read by gap reading)
137- mockAPI .AddMockEventsForQuery (createMockEventRecords (2 , 3 ))
135+ mockAPI .AddMockEventsForQuery (createMockEventRecordsRange (0 , 5 ))
136+ mockAPI .AddMockEventsForQuery (createMockEventRecordsRange (10 , 15 ))
137+ mockAPI .AddMockEventsForQuery (createMockEventRecordsRange (20 , 25 ))
138138
139139 elog .Init ()
140140
@@ -147,24 +147,33 @@ func TestReadGaps(t *testing.T) {
147147 time .Sleep (8 * time .Second )
148148 elog .Stop ()
149149
150+ expectedRecords := []int {
151+ 1 , 2 , 3 , 4 , 5 , 11 , 12 , 13 , 14 , 15 , 21 , 22 , 23 , 24 , 25 ,
152+ }
153+
150154 assert .Empty (t , elog .gapsToRead , "Gaps should be cleared after reading" )
151- assert .Len (t , records , 2 , "Should return 2 mock events" )
152- assert .Len (t , mockAPI .QueryCalls , 1 , "Should make one query call " )
155+ assert .Len (t , records , len ( expectedRecords ) , "Should return correct number of mock events" )
156+ assert .Len (t , mockAPI .QueryCalls , 3 , "Should make three query calls " )
153157 assert .Equal (t , NAME , mockAPI .QueryCalls [0 ].Path , "Should query correct path" )
154- assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID > 1" , "Query should contain start range" )
155- assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID < 4" , "Query should contain end range" )
158+ assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID > 0" , "Query should contain start range" )
159+ assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID <= 5" , "Query should contain end range" )
160+ assert .Contains (t , mockAPI .QueryCalls [1 ].Query , "EventRecordID > 10" , "Query should contain start range" )
161+ assert .Contains (t , mockAPI .QueryCalls [1 ].Query , "EventRecordID <= 15" , "Query should contain end range" )
162+ assert .Contains (t , mockAPI .QueryCalls [2 ].Query , "EventRecordID > 20" , "Query should contain start range" )
163+ assert .Contains (t , mockAPI .QueryCalls [2 ].Query , "EventRecordID <= 25" , "Query should contain end range" )
156164 assert .Greater (t , len (mockAPI .CloseCalls ), 0 , "Should make close calls" )
157165
158166 for i , record := range records {
159- assert .Contains (t , record .Message (), fmt .Sprintf ("Event %d" , 2 + i ))
167+ assert .Contains (t , record .Message (), fmt .Sprintf ("Event %d" , expectedRecords [ i ] ))
160168 }
161169
162170 assertStateFileRange (t , stateFileName , state.RangeList {
163- state .NewRange (0 , 5 ),
171+ state .NewRange (0 , 30 ),
164172 })
165173 })
166174 t .Run ("ReadGapThenSubscribe" , func (t * testing.T ) {
167175 rl := state.RangeList {
176+ // Inverted range: 2-4
168177 state .NewRange (0 , 2 ),
169178 state .NewRange (4 , 5 ),
170179 }
@@ -174,7 +183,7 @@ func TestReadGaps(t *testing.T) {
174183
175184 // This is per EvtHandle hence the necessity to break up these calls
176185 // 0, 1, 4 were "sent" previously (should be skipped)
177- mockAPI .AddMockEventsForQuery (createMockEventRecords (0 , 2 , 4 , 5 ))
186+ mockAPI .AddMockEventsForQuery (createMockEventRecords (0 , 2 , 5 ))
178187 // Gap records (should be read by gap reading)
179188 mockAPI .AddMockEventsForQuery (createMockEventRecords (3 , 4 ))
180189
@@ -192,18 +201,19 @@ func TestReadGaps(t *testing.T) {
192201 time .Sleep (5 * time .Second )
193202 elog .Stop ()
194203
204+ expectedRecords := []int {
205+ 3 , 4 , 5 , 6 , 7 , 8 ,
206+ }
207+
195208 assert .Empty (t , elog .gapsToRead , "Gaps should be cleared after reading" )
196- assert .Len (t , records , 5 , "Should return 5 mock events" )
209+ assert .Len (t , records , len ( expectedRecords ) , "Should return correct number of mock events" )
197210 assert .Len (t , mockAPI .QueryCalls , 1 , "Should make one query call" )
198211 assert .Equal (t , NAME , mockAPI .QueryCalls [0 ].Path , "Should query correct path" )
199212 assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID > 2" , "Query should contain start range" )
200- assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID < 4" , "Query should contain end range" )
213+ assert .Contains (t , mockAPI .QueryCalls [0 ].Query , "EventRecordID <= 4" , "Query should contain end range" )
201214 assert .Len (t , mockAPI .SubscribeCalls , 1 , "Should make one subscribe call" )
202215 assert .Greater (t , len (mockAPI .CloseCalls ), 0 , "Should make close calls" )
203216
204- expectedRecords := []int {
205- 3 , 5 , 6 , 7 , 8 ,
206- }
207217 for i , record := range records {
208218 assert .Contains (t , record .Message (), fmt .Sprintf ("Event %d" , expectedRecords [i ]))
209219 }
@@ -225,7 +235,7 @@ func TestReadGaps(t *testing.T) {
225235
226236 elog .Init ()
227237
228- mockAPI .SimulateSubscriptionEvents (createMockEventRecordsRange (5 , 9 ))
238+ mockAPI .SimulateSubscriptionEvents (createMockEventRecordsRange (6 , 9 ))
229239
230240 var records []logs.LogEvent
231241 // SetOutput calls run as well hence the omission of elog.run()
@@ -244,11 +254,11 @@ func TestReadGaps(t *testing.T) {
244254
245255 for i , record := range records {
246256 // Offset by 5 since we "already read" events 0-4
247- assert .Contains (t , record .Message (), fmt .Sprintf ("Event %d" , 5 + i ))
257+ assert .Contains (t , record .Message (), fmt .Sprintf ("Event %d" , 6 + i ))
248258 }
249259
250260 assertStateFileRange (t , stateFileName , state.RangeList {
251- state .NewRange (0 , 8 ),
261+ state .NewRange (0 , 9 ),
252262 })
253263 })
254264}
@@ -330,9 +340,10 @@ func assertStateFileRange(t *testing.T, fileName string, rl state.RangeList) {
330340 assert .Contains (t , string (content ), marshalRangeList (rl ))
331341}
332342
343+ // Start and end are both inclusive
333344func createMockEventRecordsRange (start , end int ) []* MockEventRecord {
334345 var records []* MockEventRecord
335- for i := start ; i < end ; i ++ {
346+ for i := start ; i <= end ; i ++ {
336347 records = append (records , & MockEventRecord {
337348 EventRecordID : fmt .Sprintf ("%d" , i ),
338349 TimeCreated : time .Now (),
@@ -903,13 +914,13 @@ func (m *MockWindowsEventAPI) EvtOpenPublisherMetadata(session EvtHandle, publis
903914// Helper methods
904915func (m * MockWindowsEventAPI ) extractRangeFromQuery (query string ) state.Range {
905916 // Parse the XML query to extract EventRecordID constraints using a single regex
906- // Look for pattern like "EventRecordID > 2 and EventRecordID < 4"
917+ // Look for pattern like "EventRecordID > 2 and EventRecordID <= 4"
907918
908919 var start , end uint64 = 0 , 1000 // Default range
909920
910921 if query != "" {
911922 // Extract both start and end in one regex
912- rangeRegex := regexp .MustCompile (`EventRecordID > (\d+) and EventRecordID < (\d+)` )
923+ rangeRegex := regexp .MustCompile (`EventRecordID > (\d+) and EventRecordID <= (\d+)` )
913924 if matches := rangeRegex .FindStringSubmatch (query ); len (matches ) > 2 {
914925 if parsedStart , err := strconv .ParseUint (matches [1 ], 10 , 64 ); err == nil {
915926 start = parsedStart
@@ -931,7 +942,7 @@ func (m *MockWindowsEventAPI) findOrCreateHandleForRange(r state.Range) EvtHandl
931942 filteredEvents := []* MockEventRecord {}
932943 for _ , event := range events {
933944 eventID , _ := strconv .ParseUint (event .EventRecordID , 10 , 64 )
934- inRange := eventID > r .StartOffset () && eventID < r .EndOffset ()
945+ inRange := eventID > r .StartOffset () && eventID <= r .EndOffset ()
935946 if inRange {
936947 filteredEvents = append (filteredEvents , event )
937948 }
0 commit comments