amqplib 1.0.6 → 1.1.0

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.
@@ -0,0 +1,194 @@
1
+
2
+
3
+ const { describe, it } = require('node:test');
4
+ const assert = require('node:assert');
5
+ const EventEmitter = require('node:events');
6
+ const recovery = require('../lib/recovery');
7
+
8
+ class FakePromiseModel extends EventEmitter {
9
+ constructor(id) {
10
+ super();
11
+ this.id = id;
12
+ }
13
+
14
+ close() {
15
+ return Promise.resolve();
16
+ }
17
+
18
+ createChannel(options) {
19
+ return Promise.resolve({kind: 'channel', id: this.id, options});
20
+ }
21
+
22
+ createConfirmChannel(options) {
23
+ return Promise.resolve({kind: 'confirm', id: this.id, options});
24
+ }
25
+
26
+ updateSecret(_newSecret, _reason) {
27
+ return Promise.resolve();
28
+ }
29
+ }
30
+
31
+ class FakeCallbackModel extends EventEmitter {
32
+ constructor(id) {
33
+ super();
34
+ this.id = id;
35
+ }
36
+
37
+ close(cb) {
38
+ cb && cb(null);
39
+ }
40
+
41
+ createChannel(options, cb) {
42
+ if (typeof options === 'function') {
43
+ cb = options;
44
+ options = undefined;
45
+ }
46
+ cb && cb(null, {kind: 'channel', id: this.id, options});
47
+ }
48
+
49
+ createConfirmChannel(options, cb) {
50
+ if (typeof options === 'function') {
51
+ cb = options;
52
+ options = undefined;
53
+ }
54
+ cb && cb(null, {kind: 'confirm', id: this.id, options});
55
+ }
56
+
57
+ updateSecret(_newSecret, _reason, cb) {
58
+ cb && cb(null);
59
+ }
60
+ }
61
+
62
+ describe('recovery', () => {
63
+ it('promise recovery reconnects after close', async () => {
64
+ const models = [];
65
+ let opened = 0;
66
+
67
+ function openModel() {
68
+ const model = new FakePromiseModel(++opened);
69
+ models.push(model);
70
+ return Promise.resolve(model);
71
+ }
72
+
73
+ const client = await recovery.connectWithRecoveryPromise(openModel, {
74
+ initialDelay: 1,
75
+ maxDelay: 1,
76
+ jitter: 0,
77
+ maxRetries: 3,
78
+ });
79
+
80
+ assert.equal(1, opened);
81
+
82
+ await new Promise((resolve) => {
83
+ client.once('connect', () => {
84
+ assert.equal(2, opened);
85
+ resolve();
86
+ });
87
+
88
+ models[0].emit('close', new Error('socket closed'));
89
+ });
90
+
91
+ await client.close();
92
+ });
93
+
94
+ it('promise recovery runs setup on every connect', async () => {
95
+ const models = [];
96
+ let setupCalls = 0;
97
+ let opened = 0;
98
+
99
+ function openModel() {
100
+ const model = new FakePromiseModel(++opened);
101
+ models.push(model);
102
+ return Promise.resolve(model);
103
+ }
104
+
105
+ const client = await recovery.connectWithRecoveryPromise(openModel, {
106
+ initialDelay: 1,
107
+ maxDelay: 1,
108
+ jitter: 0,
109
+ maxRetries: 3,
110
+ setup() {
111
+ setupCalls++;
112
+ },
113
+ });
114
+
115
+ assert.equal(1, setupCalls);
116
+
117
+ await new Promise((resolve) => {
118
+ client.once('connect', () => {
119
+ assert.equal(2, setupCalls);
120
+ resolve();
121
+ });
122
+
123
+ models[0].emit('close', new Error('socket closed'));
124
+ });
125
+
126
+ await client.close();
127
+ });
128
+
129
+ it('callback recovery reconnects and creates channels after reconnect', (done) => {
130
+ const models = [];
131
+ let opened = 0;
132
+
133
+ function openModel() {
134
+ const model = new FakeCallbackModel(++opened);
135
+ models.push(model);
136
+ return Promise.resolve(model);
137
+ }
138
+
139
+ const client = recovery.connectWithRecoveryCallback(
140
+ openModel,
141
+ {
142
+ initialDelay: 1,
143
+ maxDelay: 1,
144
+ jitter: 0,
145
+ maxRetries: 3,
146
+ },
147
+ (err, c) => {
148
+ if (err) return done(err);
149
+
150
+ c.createChannel((createErr, ch) => {
151
+ if (createErr) return done(createErr);
152
+ assert.equal(1, ch.id);
153
+
154
+ c.once('connect', () => {
155
+ c.createChannel((reconnectErr, reconnectedChannel) => {
156
+ if (reconnectErr) return done(reconnectErr);
157
+ assert.equal(2, reconnectedChannel.id);
158
+ c.close(done);
159
+ });
160
+ });
161
+
162
+ models[0].emit('close', new Error('socket closed'));
163
+ });
164
+ },
165
+ );
166
+
167
+ assert(client);
168
+ });
169
+
170
+ it('promise recovery fails after max retries', async () => {
171
+ let attempts = 0;
172
+
173
+ function openModel() {
174
+ attempts++;
175
+ return Promise.reject(new Error('connect failed'));
176
+ }
177
+
178
+ let failed = false;
179
+ try {
180
+ await recovery.connectWithRecoveryPromise(openModel, {
181
+ initialDelay: 1,
182
+ maxDelay: 1,
183
+ jitter: 0,
184
+ maxRetries: 1,
185
+ });
186
+ } catch (err) {
187
+ failed = true;
188
+ assert.equal('connect failed', err.message);
189
+ }
190
+
191
+ assert(failed);
192
+ assert.equal(2, attempts);
193
+ });
194
+ });