queen-mq 0.12.1 → 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,194 +0,0 @@
1
- /**
2
- * Client-Side Buffering Tests
3
- * Tests for buffer management and statistics
4
- */
5
-
6
- export async function testBufferStatistics(client) {
7
- const queue = await client.queue('test-queue-v2-buffer-stats').create()
8
- if (!queue.configured) {
9
- return { success: false, message: 'Queue not created' }
10
- }
11
-
12
- // Get initial stats
13
- const statsBefore = client.getBufferStats()
14
-
15
- if (!statsBefore || typeof statsBefore !== 'object') {
16
- return { success: false, message: 'Buffer stats not available' }
17
- }
18
-
19
- // Push some buffered messages
20
- for (let i = 0; i < 5; i++) {
21
- await client.queue('test-queue-v2-buffer-stats')
22
- .buffer({ messageCount: 10, timeMillis: 5000 })
23
- .push([{ data: { id: i } }])
24
- }
25
-
26
- // Get stats after buffering
27
- const statsAfter = client.getBufferStats()
28
-
29
- // Stats should show buffer activity
30
- return {
31
- success: statsAfter !== null,
32
- message: `Buffer stats retrieved: ${JSON.stringify(statsAfter)}`
33
- }
34
- }
35
-
36
- export async function testManualBufferFlush(client) {
37
- const queue = await client.queue('test-queue-v2-manual-flush').create()
38
- if (!queue.configured) {
39
- return { success: false, message: 'Queue not created' }
40
- }
41
-
42
- // Push buffered messages (with high threshold so they don't auto-flush)
43
- for (let i = 0; i < 5; i++) {
44
- await client.queue('test-queue-v2-manual-flush')
45
- .buffer({ messageCount: 100, timeMillis: 30000 })
46
- .push([{ data: { id: i } }])
47
- }
48
-
49
- // Check that messages are not in queue yet
50
- const beforeFlush = await client.queue('test-queue-v2-manual-flush')
51
- .batch(10)
52
- .wait(false)
53
- .pop()
54
-
55
- if (beforeFlush.length > 0) {
56
- return { success: false, message: 'Messages not buffered (flushed too early)' }
57
- }
58
-
59
- // Manually flush all buffers
60
- await client.flushAllBuffers()
61
-
62
- // Now messages should be in the queue
63
- const afterFlush = await client.queue('test-queue-v2-manual-flush')
64
- .batch(10)
65
- .wait(false)
66
- .pop()
67
-
68
- return {
69
- success: afterFlush.length === 5,
70
- message: `Manual flush successful: ${afterFlush.length} messages`
71
- }
72
- }
73
-
74
- export async function testBufferTimeThreshold(client) {
75
- const queue = await client.queue('test-queue-v2-buffer-time').create()
76
- if (!queue.configured) {
77
- return { success: false, message: 'Queue not created' }
78
- }
79
-
80
- // Push with time-based buffer (1 second)
81
- await client.queue('test-queue-v2-buffer-time')
82
- .buffer({ messageCount: 1000, timeMillis: 1000 })
83
- .push([{ data: { test: 'data' } }])
84
-
85
- // Wait for time threshold
86
- await new Promise(resolve => setTimeout(resolve, 1500))
87
-
88
- // Message should be auto-flushed by time
89
- const messages = await client.queue('test-queue-v2-buffer-time')
90
- .batch(1)
91
- .wait(false)
92
- .pop()
93
-
94
- return {
95
- success: messages.length === 1,
96
- message: 'Time-based buffer flush works'
97
- }
98
- }
99
-
100
- export async function testBufferCountThreshold(client) {
101
- const queue = await client.queue('test-queue-v2-buffer-count').create()
102
- if (!queue.configured) {
103
- return { success: false, message: 'Queue not created' }
104
- }
105
-
106
- // Push exactly 5 messages with count threshold of 5
107
- for (let i = 0; i < 5; i++) {
108
- await client.queue('test-queue-v2-buffer-count')
109
- .buffer({ messageCount: 5, timeMillis: 30000 })
110
- .push([{ data: { id: i } }])
111
- }
112
-
113
- // Small delay for flush to process
114
- await new Promise(resolve => setTimeout(resolve, 200))
115
-
116
- // All 5 should be flushed when threshold reached
117
- const messages = await client.queue('test-queue-v2-buffer-count')
118
- .batch(10)
119
- .wait(false)
120
- .pop()
121
-
122
- return {
123
- success: messages.length === 5,
124
- message: `Count-based buffer flush: ${messages.length} messages`
125
- }
126
- }
127
-
128
- export async function testMultipleBuffers(client) {
129
- // Create multiple queues with buffering
130
- await client.queue('test-queue-v2-multi-buf-1').create()
131
- await client.queue('test-queue-v2-multi-buf-2').create()
132
- await client.queue('test-queue-v2-multi-buf-3').create()
133
-
134
- // Buffer messages to different queues
135
- for (let i = 0; i < 3; i++) {
136
- await client.queue('test-queue-v2-multi-buf-1')
137
- .buffer({ messageCount: 100, timeMillis: 10000 })
138
- .push([{ data: { queue: 1, id: i } }])
139
-
140
- await client.queue('test-queue-v2-multi-buf-2')
141
- .buffer({ messageCount: 100, timeMillis: 10000 })
142
- .push([{ data: { queue: 2, id: i } }])
143
-
144
- await client.queue('test-queue-v2-multi-buf-3')
145
- .buffer({ messageCount: 100, timeMillis: 10000 })
146
- .push([{ data: { queue: 3, id: i } }])
147
- }
148
-
149
- // Get stats to see multiple buffers
150
- const stats = client.getBufferStats()
151
-
152
- // Flush all buffers
153
- await client.flushAllBuffers()
154
-
155
- // Verify all queues received messages
156
- const msgs1 = await client.queue('test-queue-v2-multi-buf-1').batch(10).wait(false).pop()
157
- const msgs2 = await client.queue('test-queue-v2-multi-buf-2').batch(10).wait(false).pop()
158
- const msgs3 = await client.queue('test-queue-v2-multi-buf-3').batch(10).wait(false).pop()
159
-
160
- return {
161
- success: msgs1.length === 3 && msgs2.length === 3 && msgs3.length === 3,
162
- message: `Multiple buffers flushed: ${msgs1.length + msgs2.length + msgs3.length} total`
163
- }
164
- }
165
-
166
- export async function testBufferWithPartition(client) {
167
- const queue = await client.queue('test-queue-v2-buffer-partition').create()
168
- if (!queue.configured) {
169
- return { success: false, message: 'Queue not created' }
170
- }
171
-
172
- // Buffer messages to specific partition
173
- for (let i = 0; i < 5; i++) {
174
- await client.queue('test-queue-v2-buffer-partition')
175
- .partition('test-partition-buf')
176
- .buffer({ messageCount: 100, timeMillis: 10000 })
177
- .push([{ data: { id: i } }])
178
- }
179
-
180
- await client.flushAllBuffers()
181
-
182
- // Pop from that partition
183
- const messages = await client.queue('test-queue-v2-buffer-partition')
184
- .partition('test-partition-buf')
185
- .batch(10)
186
- .wait(false)
187
- .pop()
188
-
189
- return {
190
- success: messages.length === 5,
191
- message: 'Buffering with partition works'
192
- }
193
- }
194
-
@@ -1,223 +0,0 @@
1
- /**
2
- * Error Handling & Edge Cases Tests
3
- * Tests various error conditions and edge cases
4
- */
5
-
6
- export async function testInvalidQueueName(client) {
7
- try {
8
- await client.queue('').create()
9
- return { success: false, message: 'Empty queue name should fail' }
10
- } catch (error) {
11
- return { success: true, message: 'Empty queue name correctly rejected' }
12
- }
13
- }
14
-
15
- export async function testInvalidConfiguration(client) {
16
- try {
17
- await client.queue('test-queue-invalid-config')
18
- .config({ leaseTime: -1 })
19
- .create()
20
- return { success: false, message: 'Negative leaseTime should fail' }
21
- } catch (error) {
22
- return { success: true, message: 'Invalid config correctly rejected' }
23
- }
24
- }
25
-
26
- export async function testInvalidMessageFormat(client) {
27
- const queue = await client.queue('test-queue-v2-invalid-msg').create()
28
- if (!queue.configured) {
29
- return { success: false, message: 'Queue not created' }
30
- }
31
-
32
- try {
33
- // Push without data property
34
- await client.queue('test-queue-v2-invalid-msg').push([{ invalid: 'structure' }])
35
- // If it doesn't throw, check if it still works
36
- return { success: true, message: 'Client handles flexible message format' }
37
- } catch (error) {
38
- return { success: true, message: 'Invalid message format correctly handled' }
39
- }
40
- }
41
-
42
- export async function testPushEmptyArray(client) {
43
- const queue = await client.queue('test-queue-v2-empty-array').create()
44
- if (!queue.configured) {
45
- return { success: false, message: 'Queue not created' }
46
- }
47
-
48
- const result = await client.queue('test-queue-v2-empty-array').push([])
49
- return { success: result.length === 0, message: 'Empty array push handled correctly' }
50
- }
51
-
52
- export async function testAckWithoutPartitionId(client) {
53
- const queue = await client.queue('test-queue-v2-ack-no-partition').create()
54
- if (!queue.configured) {
55
- return { success: false, message: 'Queue not created' }
56
- }
57
-
58
- await client.queue('test-queue-v2-ack-no-partition')
59
- .push([{ data: { test: 'data' } }])
60
-
61
- const messages = await client.queue('test-queue-v2-ack-no-partition')
62
- .batch(1)
63
- .wait(false)
64
- .pop()
65
-
66
- if (messages.length === 0) {
67
- return { success: false, message: 'No message to test' }
68
- }
69
-
70
- // Try to ack without partitionId (should fail)
71
- const messageWithoutPartition = { transactionId: messages[0].transactionId }
72
- const result = await client.ack(messageWithoutPartition)
73
-
74
- return {
75
- success: result.success === false && result.error.includes('partitionId'),
76
- message: 'Ack without partitionId correctly rejected'
77
- }
78
- }
79
-
80
- export async function testPopFromNonExistentQueue(client) {
81
- try {
82
- const result = await client
83
- .queue('non-existent-queue-xyz')
84
- .batch(1)
85
- .wait(false)
86
- .pop()
87
-
88
- // It's okay if it returns empty or throws
89
- return { success: true, message: 'Non-existent queue handled gracefully' }
90
- } catch (error) {
91
- return { success: true, message: 'Non-existent queue error handled' }
92
- }
93
- }
94
-
95
- export async function testMultiplePushesWithSameTransactionId(client) {
96
- const queue = await client.queue('test-queue-v2-same-txid').create()
97
- if (!queue.configured) {
98
- return { success: false, message: 'Queue not created' }
99
- }
100
-
101
- const txId = 'duplicate-transaction-id-test'
102
-
103
- const result1 = await client.queue('test-queue-v2-same-txid')
104
- .push([{ transactionId: txId, data: { first: true } }])
105
-
106
- const result2 = await client.queue('test-queue-v2-same-txid')
107
- .push([{ transactionId: txId, data: { second: true } }])
108
-
109
- const result3 = await client.queue('test-queue-v2-same-txid')
110
- .push([{ transactionId: txId, data: { third: true } }])
111
-
112
- const duplicates = [result1[0], result2[0], result3[0]].filter(r => r.status === 'duplicate').length
113
-
114
- return {
115
- success: duplicates >= 2,
116
- message: `Duplicate detection working (${duplicates} duplicates found)`
117
- }
118
- }
119
-
120
- export async function testAckExpiredLease(client) {
121
- const queue = await client.queue('test-queue-v2-expired-lease')
122
- .config({ leaseTime: 1 })
123
- .create()
124
-
125
- if (!queue.configured) {
126
- return { success: false, message: 'Queue not created' }
127
- }
128
-
129
- await client.queue('test-queue-v2-expired-lease')
130
- .push([{ data: { test: 'data' } }])
131
-
132
- const messages = await client.queue('test-queue-v2-expired-lease')
133
- .batch(1)
134
- .wait(false)
135
- .pop()
136
-
137
- if (messages.length === 0) {
138
- return { success: false, message: 'No message to test' }
139
- }
140
-
141
- // Wait for lease to expire
142
- await new Promise(resolve => setTimeout(resolve, 2000))
143
-
144
- // Try to ack expired lease
145
- const result = await client.ack(messages[0], true)
146
-
147
- return {
148
- success: result.success === false,
149
- message: 'Expired lease ack correctly rejected'
150
- }
151
- }
152
-
153
- export async function testBatchAckMixedResults(client) {
154
- const queue = await client.queue('test-queue-v2-batch-ack-mixed')
155
- .config({ leaseTime: 2 })
156
- .create()
157
-
158
- if (!queue.configured) {
159
- return { success: false, message: 'Queue not created' }
160
- }
161
-
162
- await client.queue('test-queue-v2-batch-ack-mixed').push([
163
- { data: { id: 1 } },
164
- { data: { id: 2 } },
165
- { data: { id: 3 } }
166
- ])
167
-
168
- const messages = await client.queue('test-queue-v2-batch-ack-mixed')
169
- .batch(3)
170
- .wait(false)
171
- .pop()
172
-
173
- if (messages.length !== 3) {
174
- return { success: false, message: 'Expected 3 messages' }
175
- }
176
-
177
- // Wait for one lease to expire
178
- await new Promise(resolve => setTimeout(resolve, 2500))
179
-
180
- // Try to ack all three (one should fail due to expired lease)
181
- const result = await client.ack(messages, true)
182
-
183
- // Should indicate some failures
184
- return {
185
- success: result.success === true, // Batch ack returns overall success
186
- message: 'Batch ack with expired lease handled'
187
- }
188
- }
189
-
190
- export async function testVeryLargePayload(client) {
191
- const queue = await client.queue('test-queue-v2-very-large').create()
192
- if (!queue.configured) {
193
- return { success: false, message: 'Queue not created' }
194
- }
195
-
196
- // Create a very large payload (attempt to push near limits)
197
- const hugeArray = new Array(50000).fill({
198
- id: Math.random().toString(36),
199
- data: 'x'.repeat(100)
200
- })
201
-
202
- try {
203
- const result = await client.queue('test-queue-v2-very-large')
204
- .push([{ data: hugeArray }])
205
-
206
- const received = await client.queue('test-queue-v2-very-large')
207
- .batch(1)
208
- .wait(false)
209
- .pop()
210
-
211
- return {
212
- success: received.length === 1 && received[0].data.length === 50000,
213
- message: 'Very large payload handled correctly'
214
- }
215
- } catch (error) {
216
- // It's okay if it fails - system has limits
217
- return {
218
- success: true,
219
- message: `Large payload limit enforced: ${error.message}`
220
- }
221
- }
222
- }
223
-
@@ -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
-