1+ /*
2+ Copyright (c) 2025, Oracle and/or its affiliates.
3+
4+ Licensed under the Apache License, Version 2.0 (the "License");
5+ you may not use this file except in compliance with the License.
6+ You may obtain a copy of the License at
7+
8+ https://www.apache.org/licenses/LICENSE-2.0
9+
10+ Unless required by applicable law or agreed to in writing, software
11+ distributed under the License is distributed on an "AS IS" BASIS,
12+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ See the License for the specific language governing permissions and
14+ limitations under the License.
15+ */
16+
17+ import { expect } from 'chai' ;
18+ import * as sinon from 'sinon' ;
19+ import { TelemetryEventQueue } from '../../../telemetry/impl/telemetryEventQueue' ;
20+ import { BaseEvent } from '../../../telemetry/events/baseEvent' ;
21+ import { LOGGER } from '../../../logger' ;
22+ import { describe , it , beforeEach , afterEach } from 'mocha' ;
23+
24+ describe ( 'TelemetryEventQueue' , ( ) => {
25+ let queue : TelemetryEventQueue ;
26+ let loggerStub : sinon . SinonStub ;
27+
28+ class MockEvent extends BaseEvent < any > {
29+ public static readonly NAME = "mock" ;
30+ public static readonly ENDPOINT = "/mock" ;
31+
32+
33+ constructor ( name ?: string , data ?: any ) {
34+ super ( name || MockEvent . NAME , MockEvent . ENDPOINT , data || { } ) ;
35+ }
36+ }
37+
38+ beforeEach ( ( ) => {
39+ queue = new TelemetryEventQueue ( ) ;
40+
41+ loggerStub = sinon . stub ( LOGGER , 'debug' ) ;
42+ } ) ;
43+
44+ afterEach ( ( ) => {
45+ sinon . restore ( ) ;
46+ } ) ;
47+
48+ describe ( 'enqueue' , ( ) => {
49+ it ( 'should add an event to the queue' , ( ) => {
50+ const event = new MockEvent ( ) ;
51+ queue . enqueue ( event ) ;
52+ expect ( queue . size ( ) ) . to . equal ( 1 ) ;
53+ } ) ;
54+
55+ it ( 'should add multiple events in order' , ( ) => {
56+ const event1 = new MockEvent ( 'event1' ) ;
57+ const event2 = new MockEvent ( 'event2' ) ;
58+
59+ queue . enqueue ( event1 ) ;
60+ queue . enqueue ( event2 ) ;
61+
62+ const firstEvent = queue . dequeue ( ) ;
63+ expect ( firstEvent ) . to . equal ( event1 ) ;
64+ expect ( queue . size ( ) ) . to . equal ( 1 ) ;
65+ } ) ;
66+ } ) ;
67+
68+ describe ( 'dequeue' , ( ) => {
69+ it ( 'should remove and return the first event from the queue' , ( ) => {
70+ const event = new MockEvent ( ) ;
71+ queue . enqueue ( event ) ;
72+
73+ const dequeuedEvent = queue . dequeue ( ) ;
74+ expect ( dequeuedEvent ) . to . equal ( event ) ;
75+ expect ( queue . size ( ) ) . to . equal ( 0 ) ;
76+ } ) ;
77+
78+ it ( 'should return undefined if queue is empty' , ( ) => {
79+ const dequeuedEvent = queue . dequeue ( ) ;
80+ expect ( dequeuedEvent ) . to . be . undefined ;
81+ } ) ;
82+ } ) ;
83+
84+ describe ( 'concatQueue' , ( ) => {
85+ it ( 'should append events to the end of the queue by default' , ( ) => {
86+ const event1 = new MockEvent ( 'event1' ) ;
87+ const event2 = new MockEvent ( 'event2' ) ;
88+ const event3 = new MockEvent ( 'event3' ) ;
89+
90+ queue . enqueue ( event1 ) ;
91+ queue . concatQueue ( [ event2 , event3 ] ) ;
92+
93+ expect ( queue . size ( ) ) . to . equal ( 3 ) ;
94+ expect ( queue . dequeue ( ) ) . to . equal ( event1 ) ;
95+ expect ( queue . dequeue ( ) ) . to . equal ( event2 ) ;
96+ expect ( queue . dequeue ( ) ) . to . equal ( event3 ) ;
97+ } ) ;
98+
99+ it ( 'should prepend events to the start of the queue when mergeAtStarting is true' , ( ) => {
100+ const event1 = new MockEvent ( 'event1' ) ;
101+ const event2 = new MockEvent ( 'event2' ) ;
102+ const event3 = new MockEvent ( 'event3' ) ;
103+
104+ queue . enqueue ( event1 ) ;
105+ queue . concatQueue ( [ event2 , event3 ] , true ) ;
106+
107+ expect ( queue . size ( ) ) . to . equal ( 3 ) ;
108+ expect ( queue . dequeue ( ) ) . to . equal ( event2 ) ;
109+ expect ( queue . dequeue ( ) ) . to . equal ( event3 ) ;
110+ expect ( queue . dequeue ( ) ) . to . equal ( event1 ) ;
111+ } ) ;
112+ } ) ;
113+
114+ describe ( 'size' , ( ) => {
115+ it ( 'should return the number of events in the queue' , ( ) => {
116+ expect ( queue . size ( ) ) . to . equal ( 0 ) ;
117+
118+ queue . enqueue ( new MockEvent ( 'event1' ) ) ;
119+ expect ( queue . size ( ) ) . to . equal ( 1 ) ;
120+
121+ queue . enqueue ( new MockEvent ( 'event2' ) ) ;
122+ expect ( queue . size ( ) ) . to . equal ( 2 ) ;
123+
124+ queue . dequeue ( ) ;
125+ expect ( queue . size ( ) ) . to . equal ( 1 ) ;
126+ } ) ;
127+ } ) ;
128+
129+ describe ( 'flush' , ( ) => {
130+ it ( 'should return all events and empty the queue' , ( ) => {
131+ const event1 = new MockEvent ( 'event1' ) ;
132+ const event2 = new MockEvent ( 'event2' ) ;
133+
134+ queue . enqueue ( event1 ) ;
135+ queue . enqueue ( event2 ) ;
136+
137+ const flushedEvents = queue . flush ( ) ;
138+
139+ expect ( flushedEvents ) . to . deep . equal ( [ event1 , event2 ] ) ;
140+ expect ( queue . size ( ) ) . to . equal ( 0 ) ;
141+ } ) ;
142+ } ) ;
143+
144+ describe ( 'decreaseSizeOnMaxOverflow' , ( ) => {
145+ it ( 'should do nothing if queue size is below the max' , ( ) => {
146+ const event1 = new MockEvent ( 'event1' ) ;
147+ const event2 = new MockEvent ( 'event2' ) ;
148+
149+ queue . enqueue ( event1 ) ;
150+ queue . enqueue ( event2 ) ;
151+
152+ queue . adjustQueueSize ( 5 ) ;
153+
154+ expect ( queue . size ( ) ) . to . equal ( 2 ) ;
155+ expect ( loggerStub . called ) . to . be . false ;
156+ } ) ;
157+
158+ it ( 'should log and deduplicate events when queue exceeds max size' , ( ) => {
159+ const event1 = new MockEvent ( 'event1' ) ;
160+ const event2 = new MockEvent ( 'event2' ) ;
161+ const event3 = new MockEvent ( 'event1' ) ;
162+ const event4 = new MockEvent ( 'event3' ) ;
163+ const event5 = new MockEvent ( 'event4' ) ;
164+ const event6 = new MockEvent ( 'event5' ) ;
165+
166+ queue . enqueue ( event1 ) ;
167+ queue . enqueue ( event2 ) ;
168+ queue . enqueue ( event3 ) ;
169+ queue . enqueue ( event4 ) ;
170+ queue . enqueue ( event5 ) ;
171+ queue . enqueue ( event6 ) ;
172+
173+ queue . adjustQueueSize ( 3 ) ;
174+
175+ expect ( queue . size ( ) ) . to . equal ( 5 ) ;
176+ expect ( loggerStub . calledOnce ) . to . be . true ;
177+
178+ const remainingEvents = queue . flush ( ) ;
179+ const eventNames = remainingEvents . map ( e => e . NAME ) ;
180+ expect ( eventNames ) . to . deep . equal ( [ 'event1' , 'event2' , 'event3' , 'event4' , 'event5' ] ) ;
181+ } ) ;
182+ } ) ;
183+
184+ } ) ;
0 commit comments