queen-mq 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,206 +0,0 @@
1
- /**
2
- * Lease Renewal Tests
3
- * Tests manual lease extension functionality
4
- */
5
-
6
- export async function testManualLeaseRenewal(client) {
7
- const queue = await client.queue('test-queue-v2-manual-renewal')
8
- .config({ leaseTime: 2 })
9
- .create()
10
-
11
- if (!queue.configured) {
12
- return { success: false, message: 'Queue not created' }
13
- }
14
-
15
- await client.queue('test-queue-v2-manual-renewal')
16
- .push([{ data: { test: 'renewal' } }])
17
-
18
- const messages = await client.queue('test-queue-v2-manual-renewal')
19
- .batch(1)
20
- .wait(false)
21
- .pop()
22
-
23
- if (messages.length === 0) {
24
- return { success: false, message: 'No message to test' }
25
- }
26
-
27
- const message = messages[0]
28
-
29
- // Wait 1 second
30
- await new Promise(resolve => setTimeout(resolve, 1000))
31
-
32
- // Renew the lease
33
- const renewResult = await client.renew(message)
34
-
35
- if (!renewResult.success) {
36
- return { success: false, message: 'Lease renewal failed' }
37
- }
38
-
39
- // Wait another 2 seconds (total 3 seconds, original lease was 2 seconds)
40
- await new Promise(resolve => setTimeout(resolve, 2000))
41
-
42
- // Try to ack - should succeed because we renewed
43
- const ackResult = await client.ack(message, true)
44
-
45
- return {
46
- success: ackResult.success === true,
47
- message: 'Manual lease renewal works correctly'
48
- }
49
- }
50
-
51
- export async function testBatchLeaseRenewal(client) {
52
- const queue = await client.queue('test-queue-v2-batch-renewal')
53
- .config({ leaseTime: 2 })
54
- .create()
55
-
56
- if (!queue.configured) {
57
- return { success: false, message: 'Queue not created' }
58
- }
59
-
60
- await client.queue('test-queue-v2-batch-renewal').push([
61
- { data: { id: 1 } },
62
- { data: { id: 2 } },
63
- { data: { id: 3 } }
64
- ])
65
-
66
- const messages = await client.queue('test-queue-v2-batch-renewal')
67
- .batch(3)
68
- .wait(false)
69
- .pop()
70
-
71
- if (messages.length !== 3) {
72
- return { success: false, message: 'Expected 3 messages' }
73
- }
74
-
75
- // Wait 1 second
76
- await new Promise(resolve => setTimeout(resolve, 1000))
77
-
78
- // Renew all leases
79
- const renewResults = await client.renew(messages)
80
-
81
- const allSuccess = renewResults.every(r => r.success === true)
82
-
83
- if (!allSuccess) {
84
- return { success: false, message: 'Batch renewal failed' }
85
- }
86
-
87
- // Wait another 2 seconds
88
- await new Promise(resolve => setTimeout(resolve, 2000))
89
-
90
- // Try to ack all - should succeed
91
- const ackResult = await client.ack(messages, true)
92
-
93
- return {
94
- success: ackResult.success === true,
95
- message: 'Batch lease renewal works correctly'
96
- }
97
- }
98
-
99
- export async function testRenewalWithLeaseId(client) {
100
- const queue = await client.queue('test-queue-v2-renewal-leaseid')
101
- .config({ leaseTime: 2 })
102
- .create()
103
-
104
- if (!queue.configured) {
105
- return { success: false, message: 'Queue not created' }
106
- }
107
-
108
- await client.queue('test-queue-v2-renewal-leaseid')
109
- .push([{ data: { test: 'data' } }])
110
-
111
- const messages = await client.queue('test-queue-v2-renewal-leaseid')
112
- .batch(1)
113
- .wait(false)
114
- .pop()
115
-
116
- if (messages.length === 0 || !messages[0].leaseId) {
117
- return { success: false, message: 'No message or leaseId' }
118
- }
119
-
120
- const leaseId = messages[0].leaseId
121
-
122
- // Renew using just the leaseId string
123
- const renewResult = await client.renew(leaseId)
124
-
125
- return {
126
- success: renewResult.success === true,
127
- message: 'Lease renewal with leaseId string works'
128
- }
129
- }
130
-
131
- export async function testRenewalOfExpiredLease(client) {
132
- const queue = await client.queue('test-queue-v2-renewal-expired')
133
- .config({ leaseTime: 1 })
134
- .create()
135
-
136
- if (!queue.configured) {
137
- return { success: false, message: 'Queue not created' }
138
- }
139
-
140
- await client.queue('test-queue-v2-renewal-expired')
141
- .push([{ data: { test: 'data' } }])
142
-
143
- const messages = await client.queue('test-queue-v2-renewal-expired')
144
- .batch(1)
145
- .wait(false)
146
- .pop()
147
-
148
- if (messages.length === 0) {
149
- return { success: false, message: 'No message to test' }
150
- }
151
-
152
- // Wait for lease to expire
153
- await new Promise(resolve => setTimeout(resolve, 2000))
154
-
155
- // Try to renew expired lease
156
- const renewResult = await client.renew(messages[0])
157
-
158
- // Should fail
159
- return {
160
- success: renewResult.success === false,
161
- message: 'Expired lease renewal correctly rejected'
162
- }
163
- }
164
-
165
- export async function testMultipleRenewals(client) {
166
- const queue = await client.queue('test-queue-v2-multiple-renewals')
167
- .config({ leaseTime: 2 })
168
- .create()
169
-
170
- if (!queue.configured) {
171
- return { success: false, message: 'Queue not created' }
172
- }
173
-
174
- await client.queue('test-queue-v2-multiple-renewals')
175
- .push([{ data: { test: 'data' } }])
176
-
177
- const messages = await client.queue('test-queue-v2-multiple-renewals')
178
- .batch(1)
179
- .wait(false)
180
- .pop()
181
-
182
- if (messages.length === 0) {
183
- return { success: false, message: 'No message to test' }
184
- }
185
-
186
- const message = messages[0]
187
-
188
- // Renew multiple times
189
- await new Promise(resolve => setTimeout(resolve, 1000))
190
- const renew1 = await client.renew(message)
191
-
192
- await new Promise(resolve => setTimeout(resolve, 1000))
193
- const renew2 = await client.renew(message)
194
-
195
- await new Promise(resolve => setTimeout(resolve, 1000))
196
- const renew3 = await client.renew(message)
197
-
198
- // After 3 seconds, ack should still work
199
- const ackResult = await client.ack(message, true)
200
-
201
- return {
202
- success: renew1.success && renew2.success && renew3.success && ackResult.success,
203
- message: 'Multiple lease renewals work correctly'
204
- }
205
- }
206
-
@@ -1,278 +0,0 @@
1
- /**
2
- * Mixed Scenario Tests
3
- * Complex tests combining multiple features
4
- */
5
-
6
- export async function testMultipleQueuesSimultaneous(client) {
7
- // Create multiple queues with different configurations
8
- await client.queue('test-queue-v2-mixed-1')
9
- .config({ priority: 1, leaseTime: 60 })
10
- .create()
11
-
12
- await client.queue('test-queue-v2-mixed-2')
13
- .config({ priority: 5, retryLimit: 5 })
14
- .create()
15
-
16
- await client.queue('test-queue-v2-mixed-3')
17
- .config({ priority: 10, delayedProcessing: 1 })
18
- .create()
19
-
20
- // Push to all queues
21
- await Promise.all([
22
- client.queue('test-queue-v2-mixed-1').push([{ data: { queue: 1 } }]),
23
- client.queue('test-queue-v2-mixed-2').push([{ data: { queue: 2 } }]),
24
- client.queue('test-queue-v2-mixed-3').push([{ data: { queue: 3 } }])
25
- ])
26
-
27
- // Wait for delayed queue
28
- await new Promise(resolve => setTimeout(resolve, 1500))
29
-
30
- // Pop from all
31
- const results = await Promise.all([
32
- client.queue('test-queue-v2-mixed-1').batch(1).wait(false).pop(),
33
- client.queue('test-queue-v2-mixed-2').batch(1).wait(false).pop(),
34
- client.queue('test-queue-v2-mixed-3').batch(1).wait(false).pop()
35
- ])
36
-
37
- const totalMessages = results.reduce((sum, msgs) => sum + msgs.length, 0)
38
-
39
- return {
40
- success: totalMessages === 3,
41
- message: `Multiple queues working: ${totalMessages} messages`
42
- }
43
- }
44
-
45
- export async function testCrossQueueWorkflow(client) {
46
- // Setup: 3-stage processing pipeline
47
- await client.queue('test-queue-v2-workflow-stage1').create()
48
- await client.queue('test-queue-v2-workflow-stage2').create()
49
- await client.queue('test-queue-v2-workflow-stage3').create()
50
-
51
- // Stage 1: Initial message
52
- await client.queue('test-queue-v2-workflow-stage1')
53
- .push([{ data: { stage: 1, value: 10 } }])
54
-
55
- // Process stage 1 -> stage 2
56
- const msg1 = await client.queue('test-queue-v2-workflow-stage1')
57
- .batch(1).wait(false).pop()
58
-
59
- if (msg1.length === 0) {
60
- return { success: false, message: 'Stage 1 failed' }
61
- }
62
-
63
- await client.transaction()
64
- .queue('test-queue-v2-workflow-stage2')
65
- .push([{ data: { stage: 2, value: msg1[0].data.value * 2 } }])
66
- .ack(msg1[0])
67
- .commit()
68
-
69
- // Process stage 2 -> stage 3
70
- const msg2 = await client.queue('test-queue-v2-workflow-stage2')
71
- .batch(1).wait(false).pop()
72
-
73
- if (msg2.length === 0) {
74
- return { success: false, message: 'Stage 2 failed' }
75
- }
76
-
77
- await client.transaction()
78
- .queue('test-queue-v2-workflow-stage3')
79
- .push([{ data: { stage: 3, value: msg2[0].data.value + 5 } }])
80
- .ack(msg2[0])
81
- .commit()
82
-
83
- // Verify final result
84
- const msg3 = await client.queue('test-queue-v2-workflow-stage3')
85
- .batch(1).wait(false).pop()
86
-
87
- return {
88
- success: msg3.length === 1 && msg3[0].data.value === 25,
89
- message: `Cross-queue workflow completed: final value ${msg3[0]?.data.value}`
90
- }
91
- }
92
-
93
- export async function testPartitionWithConsumerGroupAndRetries(client) {
94
- const queue = await client.queue('test-queue-v2-complex-partition')
95
- .config({ retryLimit: 2 })
96
- .create()
97
-
98
- if (!queue.configured) {
99
- return { success: false, message: 'Queue not created' }
100
- }
101
-
102
- // Push to specific partition
103
- await client.queue('test-queue-v2-complex-partition')
104
- .partition('complex-partition-1')
105
- .push([{ data: { test: 'complex' } }])
106
-
107
- let attemptCount = 0
108
-
109
- // Consume with consumer group, fail first time
110
- await client.queue('test-queue-v2-complex-partition')
111
- .partition('complex-partition-1')
112
- .group('complex-group')
113
- .batch(1)
114
- .wait(false)
115
- .limit(2)
116
- .each()
117
- .consume(async (msg) => {
118
- attemptCount++
119
- if (attemptCount === 1) {
120
- throw new Error('First attempt fails')
121
- }
122
- // Second attempt succeeds
123
- })
124
-
125
- return {
126
- success: attemptCount === 2,
127
- message: 'Complex partition/group/retry scenario works'
128
- }
129
- }
130
-
131
- export async function testBufferedPushWithTransactionConsume(client) {
132
- await client.queue('test-queue-v2-buf-txn-source').create()
133
- await client.queue('test-queue-v2-buf-txn-dest').create()
134
-
135
- // Buffered push to source
136
- for (let i = 0; i < 10; i++) {
137
- await client.queue('test-queue-v2-buf-txn-source')
138
- .buffer({ messageCount: 10, timeMillis: 2000 })
139
- .push([{ data: { id: i } }])
140
- }
141
-
142
- // Wait for flush
143
- await new Promise(resolve => setTimeout(resolve, 2500))
144
-
145
- // Consume with transaction to move to destination
146
- let processed = 0
147
- await client.queue('test-queue-v2-buf-txn-source')
148
- .batch(10)
149
- .wait(false)
150
- .limit(1)
151
- .autoAck(false)
152
- .consume(async (msgs) => {
153
- for (const msg of msgs) {
154
- await client.transaction()
155
- .queue('test-queue-v2-buf-txn-dest')
156
- .push([{ data: { processed: true, originalId: msg.data.id } }])
157
- .ack(msg)
158
- .commit()
159
- processed++
160
- }
161
- })
162
-
163
- // Verify destination
164
- const destMsgs = await client.queue('test-queue-v2-buf-txn-dest')
165
- .batch(20).wait(false).pop()
166
-
167
- return {
168
- success: processed === 10 && destMsgs.length === 10,
169
- message: `Buffered push + transaction consume: ${destMsgs.length} messages`
170
- }
171
- }
172
-
173
- export async function testNamespaceWithMultipleQueues(client) {
174
- const namespace = 'test-mixed-namespace'
175
-
176
- // Create multiple queues in same namespace
177
- await client.queue('test-queue-v2-ns-multi-a')
178
- .namespace(namespace)
179
- .config({ priority: 10 })
180
- .create()
181
-
182
- await client.queue('test-queue-v2-ns-multi-b')
183
- .namespace(namespace)
184
- .config({ priority: 5 })
185
- .create()
186
-
187
- await client.queue('test-queue-v2-ns-multi-c')
188
- .namespace(namespace)
189
- .config({ priority: 1 })
190
- .create()
191
-
192
- // Push to all
193
- await client.queue('test-queue-v2-ns-multi-a').push([{ data: { from: 'a' } }])
194
- await client.queue('test-queue-v2-ns-multi-b').push([{ data: { from: 'b' } }])
195
- await client.queue('test-queue-v2-ns-multi-c').push([{ data: { from: 'c' } }])
196
-
197
- // Consume from namespace (should get all 3)
198
- const messages = []
199
- await client.queue()
200
- .namespace(namespace)
201
- .batch(10)
202
- .wait(false)
203
- .limit(1)
204
- .consume(async (msgs) => {
205
- messages.push(...msgs)
206
- })
207
-
208
- return {
209
- success: messages.length === 3,
210
- message: `Namespace multi-queue: ${messages.length} messages`
211
- }
212
- }
213
-
214
- export async function testEncryptedWithPartitionAndGroup(client) {
215
- const queue = await client.queue('test-queue-v2-encrypted-complex')
216
- .config({ encryptionEnabled: true })
217
- .create()
218
-
219
- if (!queue.configured) {
220
- return { success: false, message: 'Queue not created' }
221
- }
222
-
223
- // Push encrypted to partition
224
- await client.queue('test-queue-v2-encrypted-complex')
225
- .partition('secure-partition')
226
- .push([{ data: { secret: 'sensitive-data', id: 123 } }])
227
-
228
- // Consume with group
229
- let receivedData = null
230
- await client.queue('test-queue-v2-encrypted-complex')
231
- .partition('secure-partition')
232
- .group('secure-group')
233
- .batch(1)
234
- .wait(false)
235
- .limit(1)
236
- .each()
237
- .consume(async (msg) => {
238
- receivedData = msg.data
239
- })
240
-
241
- return {
242
- success: receivedData && receivedData.secret === 'sensitive-data',
243
- message: 'Encrypted + partition + group works'
244
- }
245
- }
246
-
247
- export async function testHighConcurrencyMixedOperations(client) {
248
- await client.queue('test-queue-v2-concurrency-mixed').create()
249
-
250
- // Push many messages
251
- const pushPromises = []
252
- for (let i = 0; i < 50; i++) {
253
- pushPromises.push(
254
- client.queue('test-queue-v2-concurrency-mixed')
255
- .push([{ data: { id: i } }])
256
- )
257
- }
258
- await Promise.all(pushPromises)
259
-
260
- // Consume with high concurrency
261
- let processedCount = 0
262
- await client.queue('test-queue-v2-concurrency-mixed')
263
- .concurrency(10)
264
- .batch(5)
265
- .wait(false)
266
- .limit(10)
267
- .each()
268
- .consume(async (msg) => {
269
- processedCount++
270
- await new Promise(resolve => setTimeout(resolve, 10))
271
- })
272
-
273
- return {
274
- success: processedCount === 50,
275
- message: `High concurrency mixed ops: ${processedCount} messages`
276
- }
277
- }
278
-
@@ -1,169 +0,0 @@
1
- /**
2
- * Priority Queue Tests
3
- * Tests for message priority handling
4
- */
5
-
6
- export async function testBasicPriority(client) {
7
- // Create queues with different priorities
8
- const highPriorityQueue = await client.queue('test-queue-v2-priority-high')
9
- .config({ priority: 10 })
10
- .create()
11
-
12
- const lowPriorityQueue = await client.queue('test-queue-v2-priority-low')
13
- .config({ priority: 1 })
14
- .create()
15
-
16
- if (!highPriorityQueue.configured || !lowPriorityQueue.configured) {
17
- return { success: false, message: 'Queues not created' }
18
- }
19
-
20
- // Push to low priority first
21
- await client.queue('test-queue-v2-priority-low')
22
- .push([{ data: { priority: 'low', message: 'Should process second' } }])
23
-
24
- // Then push to high priority
25
- await client.queue('test-queue-v2-priority-high')
26
- .push([{ data: { priority: 'high', message: 'Should process first' } }])
27
-
28
- // Note: Testing actual priority processing order requires namespace/task filtering
29
- // as pop() from specific queue will only get that queue's messages
30
-
31
- return {
32
- success: true,
33
- message: 'Priority queues configured successfully'
34
- }
35
- }
36
-
37
- export async function testPriorityWithNamespace(client) {
38
- const namespace = 'test-priority-namespace'
39
-
40
- // Create multiple queues in same namespace with different priorities
41
- await client.queue('test-queue-v2-pri-ns-high')
42
- .namespace(namespace)
43
- .config({ priority: 10 })
44
- .create()
45
-
46
- await client.queue('test-queue-v2-pri-ns-medium')
47
- .namespace(namespace)
48
- .config({ priority: 5 })
49
- .create()
50
-
51
- await client.queue('test-queue-v2-pri-ns-low')
52
- .namespace(namespace)
53
- .config({ priority: 1 })
54
- .create()
55
-
56
- // Push messages in reverse priority order
57
- await client.queue('test-queue-v2-pri-ns-low')
58
- .push([{ data: { order: 'third', value: 1 } }])
59
-
60
- await client.queue('test-queue-v2-pri-ns-medium')
61
- .push([{ data: { order: 'second', value: 5 } }])
62
-
63
- await client.queue('test-queue-v2-pri-ns-high')
64
- .push([{ data: { order: 'first', value: 10 } }])
65
-
66
- // Pop from namespace (should respect priority)
67
- const messages = []
68
- await client.queue()
69
- .namespace(namespace)
70
- .batch(3)
71
- .wait(false)
72
- .limit(1)
73
- .consume(async (msgs) => {
74
- messages.push(...msgs)
75
- })
76
-
77
- // Messages should be in priority order
78
- if (messages.length !== 3) {
79
- return { success: false, message: `Expected 3 messages, got ${messages.length}` }
80
- }
81
-
82
- // High priority should come first
83
- const firstIsHighPriority = messages[0].data.value === 10
84
-
85
- return {
86
- success: firstIsHighPriority,
87
- message: `Priority ordering: ${messages.map(m => m.data.order).join(', ')}`
88
- }
89
- }
90
-
91
- export async function testPriorityWithTask(client) {
92
- const task = 'test-priority-task'
93
-
94
- // Create queues with same task but different priorities
95
- await client.queue('test-queue-v2-pri-task-urgent')
96
- .task(task)
97
- .config({ priority: 100 })
98
- .create()
99
-
100
- await client.queue('test-queue-v2-pri-task-normal')
101
- .task(task)
102
- .config({ priority: 50 })
103
- .create()
104
-
105
- // Push to normal first
106
- await client.queue('test-queue-v2-pri-task-normal')
107
- .push([{ data: { urgency: 'normal' } }])
108
-
109
- // Then urgent
110
- await client.queue('test-queue-v2-pri-task-urgent')
111
- .push([{ data: { urgency: 'urgent' } }])
112
-
113
- // Pop from task
114
- const messages = []
115
- await client.queue()
116
- .task(task)
117
- .batch(2)
118
- .wait(false)
119
- .limit(1)
120
- .consume(async (msgs) => {
121
- messages.push(...msgs)
122
- })
123
-
124
- if (messages.length !== 2) {
125
- return { success: false, message: `Expected 2 messages, got ${messages.length}` }
126
- }
127
-
128
- // Urgent should come first
129
- const urgentFirst = messages[0].data.urgency === 'urgent'
130
-
131
- return {
132
- success: urgentFirst,
133
- message: 'Task-based priority ordering works'
134
- }
135
- }
136
-
137
- export async function testDynamicPriorityChange(client) {
138
- const queueName = 'test-queue-v2-priority-dynamic'
139
-
140
- // Create with low priority
141
- await client.queue(queueName)
142
- .config({ priority: 1 })
143
- .create()
144
-
145
- // Push a message
146
- await client.queue(queueName)
147
- .push([{ data: { phase: 'low-priority' } }])
148
-
149
- // Reconfigure with high priority
150
- await client.queue(queueName)
151
- .config({ priority: 10 })
152
- .create()
153
-
154
- // Push another message
155
- await client.queue(queueName)
156
- .push([{ data: { phase: 'high-priority' } }])
157
-
158
- // Pop messages
159
- const messages = await client.queue(queueName)
160
- .batch(2)
161
- .wait(false)
162
- .pop()
163
-
164
- return {
165
- success: messages.length === 2,
166
- message: 'Dynamic priority change handled'
167
- }
168
- }
169
-