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.
- package/client-v2/Queen.js +5 -3
- package/client-v2/builders/TransactionBuilder.js +11 -4
- package/client-v2/http/HttpClient.js +7 -2
- package/client-v2/utils/defaults.js +2 -1
- package/package.json +1 -1
- package/test-v2/bootstrap.js +316 -0
- package/test-v2/run.js +4 -15
- package/test-v2/transaction.js +66 -0
- package/test-v2/AI_TEST_SUMMARY.md +0 -226
- package/test-v2/GETTING_STARTED.md +0 -181
- package/test-v2/MAINTENANCE_TEST.md +0 -148
- package/test-v2/README_SUBSCRIPTION_TESTS.md +0 -201
- package/test-v2/ai_buffering.js +0 -194
- package/test-v2/ai_error_handling.js +0 -223
- package/test-v2/ai_lease_renewal.js +0 -206
- package/test-v2/ai_mixed_scenarios.js +0 -278
- package/test-v2/ai_priority.js +0 -169
- package/test-v2/ai_resources.js +0 -217
- package/test-v2/ai_ttl_retention.js +0 -170
package/test-v2/ai_resources.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resource & Status API Tests
|
|
3
|
-
* Tests for querying system resources and status
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Helper to make direct HTTP calls
|
|
7
|
-
async function httpGet(url) {
|
|
8
|
-
const response = await fetch(url)
|
|
9
|
-
if (!response.ok) {
|
|
10
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
11
|
-
}
|
|
12
|
-
return await response.json()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function testListQueues(client) {
|
|
16
|
-
// Create some test queues
|
|
17
|
-
await client.queue('test-queue-v2-list-1').create()
|
|
18
|
-
await client.queue('test-queue-v2-list-2').create()
|
|
19
|
-
await client.queue('test-queue-v2-list-3').create()
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
const result = await httpGet('http://localhost:6632/api/v1/resources/queues')
|
|
23
|
-
|
|
24
|
-
if (!result || !Array.isArray(result)) {
|
|
25
|
-
return { success: false, message: 'Invalid queue list response' }
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const testQueues = result.filter(q => q.name && q.name.startsWith('test-queue-v2-list'))
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
success: testQueues.length >= 3,
|
|
32
|
-
message: `Found ${testQueues.length} test queues`
|
|
33
|
-
}
|
|
34
|
-
} catch (error) {
|
|
35
|
-
return { success: false, message: `Error listing queues: ${error.message}` }
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function testGetQueueDetails(client) {
|
|
40
|
-
const queueName = 'test-queue-v2-details'
|
|
41
|
-
await client.queue(queueName)
|
|
42
|
-
.config({
|
|
43
|
-
leaseTime: 123,
|
|
44
|
-
maxSize: 5000,
|
|
45
|
-
retryLimit: 5
|
|
46
|
-
})
|
|
47
|
-
.create()
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
const result = await httpGet(`http://localhost:6632/api/v1/resources/queues/${queueName}`)
|
|
51
|
-
|
|
52
|
-
if (!result || !result.name) {
|
|
53
|
-
return { success: false, message: 'Invalid queue details response' }
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const hasCorrectConfig = result.name === queueName
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
success: hasCorrectConfig,
|
|
60
|
-
message: 'Queue details retrieved successfully'
|
|
61
|
-
}
|
|
62
|
-
} catch (error) {
|
|
63
|
-
return { success: false, message: `Error getting queue details: ${error.message}` }
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function testGetNamespaces(client) {
|
|
68
|
-
// Create queues with different namespaces
|
|
69
|
-
await client.queue('test-queue-v2-ns-1')
|
|
70
|
-
.namespace('test-namespace-alpha')
|
|
71
|
-
.create()
|
|
72
|
-
|
|
73
|
-
await client.queue('test-queue-v2-ns-2')
|
|
74
|
-
.namespace('test-namespace-beta')
|
|
75
|
-
.create()
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
const result = await httpGet('http://localhost:6632/api/v1/resources/namespaces')
|
|
79
|
-
|
|
80
|
-
if (!result || !Array.isArray(result)) {
|
|
81
|
-
return { success: false, message: 'Invalid namespaces response' }
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const testNamespaces = result.filter(ns =>
|
|
85
|
-
typeof ns === 'string' && ns.startsWith('test-namespace')
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
success: testNamespaces.length >= 2,
|
|
90
|
-
message: `Found ${testNamespaces.length} test namespaces`
|
|
91
|
-
}
|
|
92
|
-
} catch (error) {
|
|
93
|
-
return { success: false, message: `Error listing namespaces: ${error.message}` }
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export async function testGetTasks(client) {
|
|
98
|
-
// Create queues with different tasks
|
|
99
|
-
await client.queue('test-queue-v2-task-1')
|
|
100
|
-
.task('test-task-one')
|
|
101
|
-
.create()
|
|
102
|
-
|
|
103
|
-
await client.queue('test-queue-v2-task-2')
|
|
104
|
-
.task('test-task-two')
|
|
105
|
-
.create()
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
const result = await httpGet('http://localhost:6632/api/v1/resources/tasks')
|
|
109
|
-
|
|
110
|
-
if (!result || !Array.isArray(result)) {
|
|
111
|
-
return { success: false, message: 'Invalid tasks response' }
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const testTasks = result.filter(task =>
|
|
115
|
-
typeof task === 'string' && task.startsWith('test-task')
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
success: testTasks.length >= 2,
|
|
120
|
-
message: `Found ${testTasks.length} test tasks`
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
return { success: false, message: `Error listing tasks: ${error.message}` }
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export async function testGetMessages(client) {
|
|
128
|
-
const queueName = 'test-queue-v2-get-messages'
|
|
129
|
-
await client.queue(queueName).create()
|
|
130
|
-
|
|
131
|
-
// Push some messages
|
|
132
|
-
await client.queue(queueName).push([
|
|
133
|
-
{ data: { id: 1 } },
|
|
134
|
-
{ data: { id: 2 } },
|
|
135
|
-
{ data: { id: 3 } }
|
|
136
|
-
])
|
|
137
|
-
|
|
138
|
-
try {
|
|
139
|
-
const result = await httpGet(
|
|
140
|
-
`http://localhost:6632/api/v1/messages?queue=${queueName}&status=pending&limit=10`
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
if (!result || !result.messages) {
|
|
144
|
-
return { success: false, message: 'Invalid messages response' }
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return {
|
|
148
|
-
success: result.messages.length >= 3,
|
|
149
|
-
message: `Found ${result.messages.length} pending messages`
|
|
150
|
-
}
|
|
151
|
-
} catch (error) {
|
|
152
|
-
return { success: false, message: `Error getting messages: ${error.message}` }
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export async function testSystemOverview(client) {
|
|
157
|
-
try {
|
|
158
|
-
const result = await httpGet('http://localhost:6632/api/v1/resources/overview')
|
|
159
|
-
|
|
160
|
-
if (!result) {
|
|
161
|
-
return { success: false, message: 'Invalid overview response' }
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Check for expected overview fields
|
|
165
|
-
const hasExpectedFields = 'totalQueues' in result || 'queues' in result
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
success: hasExpectedFields,
|
|
169
|
-
message: 'System overview retrieved successfully'
|
|
170
|
-
}
|
|
171
|
-
} catch (error) {
|
|
172
|
-
return { success: false, message: `Error getting overview: ${error.message}` }
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export async function testHealthCheck(client) {
|
|
177
|
-
try {
|
|
178
|
-
const result = await httpGet('http://localhost:6632/health')
|
|
179
|
-
|
|
180
|
-
if (!result || result.status !== 'healthy') {
|
|
181
|
-
return { success: false, message: 'Health check failed' }
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
success: true,
|
|
186
|
-
message: 'Health check passed'
|
|
187
|
-
}
|
|
188
|
-
} catch (error) {
|
|
189
|
-
return { success: false, message: `Health check error: ${error.message}` }
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export async function testDeleteQueue(client) {
|
|
194
|
-
const queueName = 'test-queue-v2-to-delete'
|
|
195
|
-
await client.queue(queueName).create()
|
|
196
|
-
|
|
197
|
-
// Verify it exists
|
|
198
|
-
const queues1 = await httpGet('http://localhost:6632/api/v1/resources/queues')
|
|
199
|
-
const existsBefore = queues1.some(q => q.name === queueName)
|
|
200
|
-
|
|
201
|
-
if (!existsBefore) {
|
|
202
|
-
return { success: false, message: 'Queue not created' }
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Delete it
|
|
206
|
-
const deleteResult = await client.queue(queueName).delete()
|
|
207
|
-
|
|
208
|
-
if (!deleteResult.deleted) {
|
|
209
|
-
return { success: false, message: 'Queue deletion failed' }
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return {
|
|
213
|
-
success: true,
|
|
214
|
-
message: 'Queue deleted successfully'
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TTL and Retention Tests
|
|
3
|
-
* Tests for message TTL, retention policies
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export async function testMessageTTL(client) {
|
|
7
|
-
const queue = await client.queue('test-queue-v2-ttl')
|
|
8
|
-
.config({
|
|
9
|
-
ttl: 2 // 2 seconds TTL
|
|
10
|
-
})
|
|
11
|
-
.create()
|
|
12
|
-
|
|
13
|
-
if (!queue.configured) {
|
|
14
|
-
return { success: false, message: 'Queue not created' }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Push a message
|
|
18
|
-
await client.queue('test-queue-v2-ttl')
|
|
19
|
-
.push([{ data: { test: 'ttl-message' } }])
|
|
20
|
-
|
|
21
|
-
// Wait for TTL to expire
|
|
22
|
-
await new Promise(resolve => setTimeout(resolve, 3000))
|
|
23
|
-
|
|
24
|
-
// Try to pop - message should be expired
|
|
25
|
-
const messages = await client.queue('test-queue-v2-ttl')
|
|
26
|
-
.batch(1)
|
|
27
|
-
.wait(false)
|
|
28
|
-
.pop()
|
|
29
|
-
|
|
30
|
-
// Note: TTL behavior may vary - message might be deleted or marked as expired
|
|
31
|
-
return {
|
|
32
|
-
success: true,
|
|
33
|
-
message: `TTL test completed: ${messages.length} messages found (expired messages may be auto-deleted)`
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function testRetentionEnabled(client) {
|
|
38
|
-
const queue = await client.queue('test-queue-v2-retention')
|
|
39
|
-
.config({
|
|
40
|
-
retentionEnabled: true,
|
|
41
|
-
retentionSeconds: 3600 // 1 hour
|
|
42
|
-
})
|
|
43
|
-
.create()
|
|
44
|
-
|
|
45
|
-
if (!queue.configured) {
|
|
46
|
-
return { success: false, message: 'Queue not created' }
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Push and process a message
|
|
50
|
-
await client.queue('test-queue-v2-retention')
|
|
51
|
-
.push([{ data: { test: 'retention' } }])
|
|
52
|
-
|
|
53
|
-
const messages = await client.queue('test-queue-v2-retention')
|
|
54
|
-
.batch(1)
|
|
55
|
-
.wait(false)
|
|
56
|
-
.pop()
|
|
57
|
-
|
|
58
|
-
if (messages.length === 0) {
|
|
59
|
-
return { success: false, message: 'No message to process' }
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
await client.ack(messages[0], true)
|
|
63
|
-
|
|
64
|
-
// With retention enabled, we should be able to query completed messages
|
|
65
|
-
// This would require accessing the messages API
|
|
66
|
-
return {
|
|
67
|
-
success: true,
|
|
68
|
-
message: 'Retention policy configured'
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export async function testCompletedRetention(client) {
|
|
73
|
-
const queue = await client.queue('test-queue-v2-completed-retention')
|
|
74
|
-
.config({
|
|
75
|
-
completedRetentionSeconds: 60 // 1 minute
|
|
76
|
-
})
|
|
77
|
-
.create()
|
|
78
|
-
|
|
79
|
-
if (!queue.configured) {
|
|
80
|
-
return { success: false, message: 'Queue not created' }
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Push, pop, and ack a message
|
|
84
|
-
await client.queue('test-queue-v2-completed-retention')
|
|
85
|
-
.push([{ data: { test: 'completed' } }])
|
|
86
|
-
|
|
87
|
-
const messages = await client.queue('test-queue-v2-completed-retention')
|
|
88
|
-
.batch(1)
|
|
89
|
-
.wait(false)
|
|
90
|
-
.pop()
|
|
91
|
-
|
|
92
|
-
if (messages.length === 0) {
|
|
93
|
-
return { success: false, message: 'No message to process' }
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
await client.ack(messages[0], true)
|
|
97
|
-
|
|
98
|
-
// Message should be retained for the specified time
|
|
99
|
-
return {
|
|
100
|
-
success: true,
|
|
101
|
-
message: 'Completed retention configured'
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export async function testNoRetention(client) {
|
|
106
|
-
const queue = await client.queue('test-queue-v2-no-retention')
|
|
107
|
-
.config({
|
|
108
|
-
retentionEnabled: false,
|
|
109
|
-
retentionSeconds: 0,
|
|
110
|
-
completedRetentionSeconds: 0
|
|
111
|
-
})
|
|
112
|
-
.create()
|
|
113
|
-
|
|
114
|
-
if (!queue.configured) {
|
|
115
|
-
return { success: false, message: 'Queue not created' }
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Push, pop, and ack
|
|
119
|
-
await client.queue('test-queue-v2-no-retention')
|
|
120
|
-
.push([{ data: { test: 'no-retention' } }])
|
|
121
|
-
|
|
122
|
-
const messages = await client.queue('test-queue-v2-no-retention')
|
|
123
|
-
.batch(1)
|
|
124
|
-
.wait(false)
|
|
125
|
-
.pop()
|
|
126
|
-
|
|
127
|
-
if (messages.length > 0) {
|
|
128
|
-
await client.ack(messages[0], true)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Without retention, completed messages should be deleted immediately
|
|
132
|
-
return {
|
|
133
|
-
success: true,
|
|
134
|
-
message: 'No retention mode configured'
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export async function testMaxWaitTimeDLQ(client) {
|
|
139
|
-
const queue = await client.queue('test-queue-v2-max-wait')
|
|
140
|
-
.config({
|
|
141
|
-
maxWaitTimeSeconds: 2, // 2 seconds max wait
|
|
142
|
-
dlqAfterMaxRetries: true,
|
|
143
|
-
deadLetterQueue: true
|
|
144
|
-
})
|
|
145
|
-
.create()
|
|
146
|
-
|
|
147
|
-
if (!queue.configured) {
|
|
148
|
-
return { success: false, message: 'Queue not created' }
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Push a message
|
|
152
|
-
await client.queue('test-queue-v2-max-wait')
|
|
153
|
-
.push([{ data: { test: 'max-wait' } }])
|
|
154
|
-
|
|
155
|
-
// Wait longer than maxWaitTimeSeconds without consuming
|
|
156
|
-
await new Promise(resolve => setTimeout(resolve, 3000))
|
|
157
|
-
|
|
158
|
-
// Check if message moved to DLQ
|
|
159
|
-
const dlqResult = await client.queue('test-queue-v2-max-wait')
|
|
160
|
-
.dlq()
|
|
161
|
-
.limit(10)
|
|
162
|
-
.get()
|
|
163
|
-
|
|
164
|
-
// Note: maxWaitTimeSeconds behavior may vary by implementation
|
|
165
|
-
return {
|
|
166
|
-
success: true,
|
|
167
|
-
message: `Max wait time test completed: ${dlqResult?.messages?.length || 0} in DLQ`
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|