Haraka 3.0.3 → 3.0.4
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/.eslintrc.yaml +5 -9
- package/.prettierrc.yml +1 -0
- package/CONTRIBUTORS.md +11 -0
- package/Changes.md +1365 -1214
- package/Plugins.md +117 -105
- package/README.md +4 -13
- package/bin/haraka +197 -298
- package/config/auth_flat_file.ini +1 -0
- package/config/dhparams.pem +8 -0
- package/config/mail_from.is_resolvable.ini +4 -2
- package/config/me +1 -0
- package/config/outbound.ini +0 -2
- package/config/plugins +36 -35
- package/config/smtp.ini +0 -1
- package/config/smtp.json +17 -0
- package/config/tls_cert.pem +23 -0
- package/config/tls_key.pem +28 -0
- package/connection.js +46 -73
- package/contrib/bsd-rc.d/haraka +3 -1
- package/contrib/plugin2npm.sh +6 -36
- package/docs/CoreConfig.md +2 -2
- package/docs/Logging.md +7 -21
- package/docs/Outbound.md +104 -201
- package/docs/Plugins.md +2 -2
- package/docs/Transaction.md +59 -82
- package/docs/plugins/queue/smtp_proxy.md +5 -10
- package/docs/plugins/tls.md +29 -9
- package/endpoint.js +16 -13
- package/haraka.js +10 -14
- package/host_pool.js +5 -5
- package/line_socket.js +3 -4
- package/logger.js +44 -28
- package/outbound/client_pool.js +27 -23
- package/outbound/config.js +4 -6
- package/outbound/fsync_writestream.js +1 -1
- package/outbound/hmail.js +178 -218
- package/outbound/index.js +86 -99
- package/outbound/qfile.js +1 -1
- package/outbound/queue.js +51 -44
- package/outbound/timer_queue.js +3 -2
- package/outbound/tls.js +19 -7
- package/package.json +59 -48
- package/plugins/.eslintrc.yaml +0 -6
- package/plugins/auth/auth_base.js +4 -2
- package/plugins/auth/auth_proxy.js +14 -12
- package/plugins/auth/auth_vpopmaild.js +1 -1
- package/plugins/block_me.js +1 -1
- package/plugins/data.signatures.js +2 -4
- package/plugins/early_talker.js +2 -1
- package/plugins/mail_from.is_resolvable.js +65 -135
- package/plugins/queue/deliver.js +4 -5
- package/plugins/queue/lmtp.js +11 -14
- package/plugins/queue/qmail-queue.js +2 -2
- package/plugins/queue/quarantine.js +2 -2
- package/plugins/queue/rabbitmq.js +16 -17
- package/plugins/queue/smtp_forward.js +3 -3
- package/plugins/queue/smtp_proxy.js +10 -1
- package/plugins/queue/test.js +2 -2
- package/plugins/rcpt_to.host_list_base.js +5 -5
- package/plugins/rcpt_to.in_host_list.js +2 -2
- package/plugins/relay.js +6 -7
- package/plugins/reseed_rng.js +1 -1
- package/plugins/status.js +37 -33
- package/plugins/tls.js +2 -2
- package/plugins/xclient.js +3 -2
- package/plugins.js +50 -54
- package/run_tests +3 -30
- package/server.js +190 -190
- package/smtp_client.js +30 -23
- package/{tests → test}/config/plugins +0 -2
- package/{tests → test}/config/smtp.ini +1 -1
- package/test/config/tls/example.com/_.example.com.key +28 -0
- package/test/config/tls/example.com/example.com.crt +25 -0
- package/test/connection.js +302 -0
- package/test/endpoint.js +94 -0
- package/{tests → test}/fixtures/line_socket.js +1 -1
- package/{tests → test}/fixtures/util_hmailitem.js +19 -25
- package/{tests → test}/host_pool.js +42 -57
- package/test/logger.js +258 -0
- package/test/outbound/hmail.js +141 -0
- package/test/outbound/index.js +220 -0
- package/test/outbound/qfile.js +126 -0
- package/test/outbound_bounce_net_errors.js +142 -0
- package/{tests → test}/outbound_bounce_rfc3464.js +110 -122
- package/test/plugins/auth/auth_base.js +484 -0
- package/test/plugins/auth/auth_vpopmaild.js +83 -0
- package/test/plugins/early_talker.js +104 -0
- package/test/plugins/mail_from.is_resolvable.js +35 -0
- package/test/plugins/queue/smtp_forward.js +206 -0
- package/test/plugins/rcpt_to.host_list_base.js +122 -0
- package/test/plugins/rcpt_to.in_host_list.js +193 -0
- package/test/plugins/relay.js +303 -0
- package/test/plugins/status.js +130 -0
- package/test/plugins/tls.js +70 -0
- package/test/plugins.js +228 -0
- package/test/rfc1869.js +73 -0
- package/test/server.js +491 -0
- package/test/smtp_client.js +299 -0
- package/test/tls_socket.js +273 -0
- package/test/transaction.js +270 -0
- package/tls_socket.js +202 -252
- package/transaction.js +8 -23
- package/CONTRIBUTING.md +0 -1
- package/bin/dkimverify +0 -40
- package/config/access.domains +0 -13
- package/config/attachment.ctype.regex +0 -2
- package/config/attachment.filename.regex +0 -1
- package/config/avg.ini +0 -5
- package/config/bounce.ini +0 -15
- package/config/data.headers.ini +0 -61
- package/config/dkim/dkim_key_gen.sh +0 -78
- package/config/dkim_sign.ini +0 -4
- package/config/dkim_verify.ini +0 -7
- package/config/dnsbl.ini +0 -23
- package/config/greylist.ini +0 -43
- package/config/helo.checks.ini +0 -52
- package/config/messagesniffer.ini +0 -18
- package/config/spamassassin.ini +0 -56
- package/dkim.js +0 -614
- package/docs/plugins/avg.md +0 -35
- package/docs/plugins/bounce.md +0 -69
- package/docs/plugins/clamd.md +0 -147
- package/docs/plugins/esets.md +0 -8
- package/docs/plugins/greylist.md +0 -90
- package/docs/plugins/helo.checks.md +0 -135
- package/docs/plugins/messagesniffer.md +0 -163
- package/docs/plugins/spamassassin.md +0 -180
- package/outbound/mx_lookup.js +0 -70
- package/plugins/auth/auth_ldap.js +0 -3
- package/plugins/avg.js +0 -162
- package/plugins/backscatterer.js +0 -25
- package/plugins/bounce.js +0 -381
- package/plugins/clamd.js +0 -382
- package/plugins/data.uribl.js +0 -4
- package/plugins/dkim_sign.js +0 -395
- package/plugins/dkim_verify.js +0 -62
- package/plugins/dns_list_base.js +0 -221
- package/plugins/dnsbl.js +0 -146
- package/plugins/dnswl.js +0 -58
- package/plugins/esets.js +0 -71
- package/plugins/graph.js +0 -5
- package/plugins/greylist.js +0 -645
- package/plugins/helo.checks.js +0 -533
- package/plugins/messagesniffer.js +0 -381
- package/plugins/rcpt_to.ldap.js +0 -3
- package/plugins/rcpt_to.max_count.js +0 -24
- package/plugins/spamassassin.js +0 -384
- package/tests/config/dkim/example.com/dns +0 -29
- package/tests/config/dkim/example.com/private +0 -6
- package/tests/config/dkim/example.com/public +0 -4
- package/tests/config/dkim/example.com/selector +0 -1
- package/tests/config/dkim.private.key +0 -6
- package/tests/config/dkim_sign.ini +0 -4
- package/tests/config/helo.checks.ini +0 -52
- package/tests/connection.js +0 -327
- package/tests/endpoint.js +0 -128
- package/tests/fixtures/vm_harness.js +0 -59
- package/tests/logger.js +0 -327
- package/tests/outbound/hmail.js +0 -112
- package/tests/outbound/index.js +0 -324
- package/tests/outbound/qfile.js +0 -67
- package/tests/outbound_bounce_net_errors.js +0 -173
- package/tests/plugins/auth/auth_base.js +0 -463
- package/tests/plugins/auth/auth_vpopmaild.js +0 -91
- package/tests/plugins/bounce.js +0 -307
- package/tests/plugins/clamd.js +0 -224
- package/tests/plugins/deprecated/relay_acl.js +0 -140
- package/tests/plugins/deprecated/relay_all.js +0 -59
- package/tests/plugins/dkim_sign.js +0 -315
- package/tests/plugins/dkim_signer.js +0 -108
- package/tests/plugins/dns_list_base.js +0 -259
- package/tests/plugins/dnsbl.js +0 -101
- package/tests/plugins/early_talker.js +0 -115
- package/tests/plugins/greylist.js +0 -58
- package/tests/plugins/helo.checks.js +0 -525
- package/tests/plugins/mail_from.is_resolvable.js +0 -116
- package/tests/plugins/queue/smtp_forward.js +0 -221
- package/tests/plugins/rcpt_to.host_list_base.js +0 -132
- package/tests/plugins/rcpt_to.in_host_list.js +0 -218
- package/tests/plugins/relay.js +0 -339
- package/tests/plugins/spamassassin.js +0 -171
- package/tests/plugins/status.js +0 -138
- package/tests/plugins/tls.js +0 -84
- package/tests/plugins.js +0 -247
- package/tests/rfc1869.js +0 -61
- package/tests/server.js +0 -510
- package/tests/smtp_client/auth.js +0 -105
- package/tests/smtp_client/basic.js +0 -101
- package/tests/smtp_client.js +0 -80
- package/tests/tls_socket.js +0 -333
- package/tests/transaction.js +0 -284
- /package/docs/{plugins → deprecated}/dkim_sign.md +0 -0
- /package/docs/{plugins → deprecated}/dkim_verify.md +0 -0
- /package/docs/{plugins → deprecated}/dnsbl.md +0 -0
- /package/docs/{plugins → deprecated}/dnswl.md +0 -0
- /package/{tests → test}/.eslintrc.yaml +0 -0
- /package/{tests → test}/config/auth_flat_file.ini +0 -0
- /package/{tests → test}/config/dhparams.pem +0 -0
- /package/{tests → test}/config/host_list +0 -0
- /package/{tests → test}/config/outbound_tls_cert.pem +0 -0
- /package/{tests → test}/config/outbound_tls_key.pem +0 -0
- /package/{tests → test}/config/smtp_forward.ini +0 -0
- /package/{tests → test}/config/tls/ec.pem +0 -0
- /package/{tests → test}/config/tls/haraka.local.pem +0 -0
- /package/{tests → test}/config/tls/mismatched.pem +0 -0
- /package/{tests → test}/config/tls.ini +0 -0
- /package/{tests → test}/config/tls_cert.pem +0 -0
- /package/{tests → test}/config/tls_key.pem +0 -0
- /package/{tests → test}/fixtures/todo_qfile.txt +0 -0
- /package/{tests → test}/installation/config/test-plugin-flat +0 -0
- /package/{tests → test}/installation/config/test-plugin.ini +0 -0
- /package/{tests → test}/installation/config/tls.ini +0 -0
- /package/{tests → test}/installation/node_modules/load_first/index.js +0 -0
- /package/{tests → test}/installation/node_modules/load_first/package.json +0 -0
- /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin-flat +0 -0
- /package/{tests → test}/installation/node_modules/test-plugin/config/test-plugin.ini +0 -0
- /package/{tests → test}/installation/node_modules/test-plugin/package.json +0 -0
- /package/{tests → test}/installation/node_modules/test-plugin/test-plugin.js +0 -0
- /package/{tests → test}/installation/plugins/base_plugin.js +0 -0
- /package/{tests → test}/installation/plugins/folder_plugin/index.js +0 -0
- /package/{tests → test}/installation/plugins/folder_plugin/package.json +0 -0
- /package/{tests → test}/installation/plugins/inherits.js +0 -0
- /package/{tests → test}/installation/plugins/load_first.js +0 -0
- /package/{tests → test}/installation/plugins/plugin.js +0 -0
- /package/{tests → test}/installation/plugins/tls.js +0 -0
- /package/{tests → test}/loud/config/dhparams.pem +0 -0
- /package/{tests → test}/loud/config/tls/goobered.pem +0 -0
- /package/{tests → test}/loud/config/tls.ini +0 -0
- /package/{tests → test}/mail_specimen/base64-root-part.txt +0 -0
- /package/{tests → test}/mail_specimen/varied-fold-lengths-preserve-data.txt +0 -0
- /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_fixed +0 -0
- /package/{tests → test}/queue/1507509981169_1507509981169_0_61403_e0Y0Ym_1_haraka +0 -0
- /package/{tests → test}/queue/1508269674999_1508269674999_0_34002_socVUF_1_haraka +0 -0
- /package/{tests → test}/queue/1508455115683_1508455115683_0_90253_9Q4o4V_1_haraka +0 -0
- /package/{tests → test}/queue/multibyte +0 -0
- /package/{tests → test}/queue/plain +0 -0
- /package/{tests → test}/queue/zero-length +0 -0
- /package/{tests → test}/test-queue/delete-me +0 -0
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const fixtures = require('haraka-test-fixtures');
|
|
5
|
-
const stub_connection = fixtures.connection;
|
|
6
|
-
// const transaction = fixtures.transaction; // not yet sufficient
|
|
7
|
-
const transaction = require('../../transaction');
|
|
3
|
+
const assert = require('node:assert')
|
|
8
4
|
|
|
5
|
+
const { Address } = require('address-rfc2821');
|
|
6
|
+
const fixtures = require('haraka-test-fixtures');
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* Creates a HMailItem instance, which is passed to callback. Reports error on test param if creation fails.
|
|
12
10
|
*
|
|
13
11
|
* @param outbound_context
|
|
14
|
-
* @param test
|
|
15
12
|
* @param options
|
|
16
13
|
* @param callback
|
|
17
14
|
*/
|
|
18
|
-
exports.newMockHMailItem = (outbound_context,
|
|
15
|
+
exports.newMockHMailItem = (outbound_context, done, options, callback) => {
|
|
19
16
|
const opts = options || {};
|
|
20
17
|
exports.createHMailItem(
|
|
21
18
|
outbound_context,
|
|
22
19
|
opts,
|
|
23
20
|
(err, hmail) => {
|
|
24
21
|
if (err) {
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
assert.ok(false, `Could not create HMailItem: ${err}`);
|
|
23
|
+
done()
|
|
27
24
|
return;
|
|
28
25
|
}
|
|
29
26
|
if (!hmail.todo) {
|
|
@@ -41,7 +38,7 @@ exports.newMockHMailItem = (outbound_context, test, options, callback) => {
|
|
|
41
38
|
/**
|
|
42
39
|
* Creates a HMailItem instance for testing purpose
|
|
43
40
|
*
|
|
44
|
-
* @param outbound_context: The context of
|
|
41
|
+
* @param outbound_context: The context of outbound, e.g. from require('outbound/index.js')
|
|
45
42
|
* @param options
|
|
46
43
|
* @param callback(err, hmail)
|
|
47
44
|
*/
|
|
@@ -51,8 +48,8 @@ exports.createHMailItem = (outbound_context, options, callback) => {
|
|
|
51
48
|
const delivery_domain = options.delivery_domain || 'domain';
|
|
52
49
|
const mail_recipients = options.mail_recipients || [new Address('recipient@domain')];
|
|
53
50
|
|
|
54
|
-
const conn =
|
|
55
|
-
conn.
|
|
51
|
+
const conn = fixtures.connection.createConnection();
|
|
52
|
+
conn.init_transaction()
|
|
56
53
|
conn.transaction.mail_from = new Address(mail_from);
|
|
57
54
|
|
|
58
55
|
const todo = new outbound_context.TODOItem(delivery_domain, mail_recipients, conn.transaction);
|
|
@@ -82,11 +79,7 @@ exports.createHMailItem = (outbound_context, options, callback) => {
|
|
|
82
79
|
|
|
83
80
|
const hmails = [];
|
|
84
81
|
const ok_paths = [];
|
|
85
|
-
outbound_context.exports.process_delivery(ok_paths, todo, hmails
|
|
86
|
-
if (err) {
|
|
87
|
-
callback(`process_delivery error: ${err}`);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
82
|
+
outbound_context.exports.process_delivery(ok_paths, todo, hmails).then(() => {
|
|
90
83
|
if (hmails.length == 0) {
|
|
91
84
|
callback('No hmail producted');
|
|
92
85
|
return;
|
|
@@ -95,8 +88,10 @@ exports.createHMailItem = (outbound_context, options, callback) => {
|
|
|
95
88
|
hmail.hostlist = [ delivery_domain ];
|
|
96
89
|
callback(null, hmail);
|
|
97
90
|
}
|
|
98
|
-
})
|
|
99
|
-
|
|
91
|
+
})
|
|
92
|
+
.catch(err => {
|
|
93
|
+
callback(`process_delivery error: ${err}`);
|
|
94
|
+
})
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
/**
|
|
@@ -105,7 +100,7 @@ exports.createHMailItem = (outbound_context, options, callback) => {
|
|
|
105
100
|
* @param test
|
|
106
101
|
* @param playbook
|
|
107
102
|
*/
|
|
108
|
-
exports.playTestSmtpConversation = (hmail, socket,
|
|
103
|
+
exports.playTestSmtpConversation = (hmail, socket, done, playbook, callback) => {
|
|
109
104
|
const testmx = {
|
|
110
105
|
bind_helo: "haraka.test",
|
|
111
106
|
exchange: "remote.testhost",
|
|
@@ -115,17 +110,17 @@ exports.playTestSmtpConversation = (hmail, socket, test, playbook, callback) =>
|
|
|
115
110
|
socket.write = line => {
|
|
116
111
|
//console.log('MockSocket.write(' + line.replace(/\n/, '\\n').replace(/\r/, '\\r') + ')');
|
|
117
112
|
if (playbook.length == 0) {
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
assert.ok(false, 'missing next playbook entry');
|
|
114
|
+
done()
|
|
120
115
|
return;
|
|
121
116
|
}
|
|
122
117
|
let expected;
|
|
123
118
|
while (false != (expected = getNextEntryFromPlaybook('haraka', playbook))) {
|
|
124
119
|
if (typeof expected.test === 'function') {
|
|
125
|
-
|
|
120
|
+
assert.ok(expected.test(line), expected.description || `Expected that line works with func: ${expected.test}`);
|
|
126
121
|
}
|
|
127
122
|
else {
|
|
128
|
-
|
|
123
|
+
assert.equal(`${expected.test}\r\n`, line, expected.description || `Expected that line equals: ${expected.test}`);
|
|
129
124
|
}
|
|
130
125
|
if (expected.end_test === true) {
|
|
131
126
|
setTimeout(() => {
|
|
@@ -144,7 +139,6 @@ exports.playTestSmtpConversation = (hmail, socket, test, playbook, callback) =>
|
|
|
144
139
|
|
|
145
140
|
const welcome = getNextEntryFromPlaybook('remote', playbook);
|
|
146
141
|
socket.emit('line', welcome.line);
|
|
147
|
-
|
|
148
142
|
}
|
|
149
143
|
|
|
150
144
|
function getNextEntryFromPlaybook (ofType, playbook) {
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const assert = require('node:assert')
|
|
4
|
+
|
|
3
5
|
const HostPool = require('../host_pool');
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
"get a host"
|
|
7
|
-
test.expect(2);
|
|
7
|
+
describe('HostPool', () => {
|
|
8
|
+
it("get a host", (done) => {
|
|
8
9
|
|
|
9
10
|
const pool = new HostPool('1.1.1.1:1111, 2.2.2.2:2222');
|
|
10
|
-
|
|
11
11
|
const host = pool.get_host();
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
assert.ok( /\d\.\d\.\d\.\d/.test(host.host), `'${host.host}' looks like a IP`);
|
|
14
|
+
assert.ok( /\d\d\d\d/.test(host.port), `'${host.port}' looks like a port`);
|
|
15
|
+
done()
|
|
16
|
+
})
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
"uses all the list": test => {
|
|
21
|
-
test.expect(3);
|
|
18
|
+
it("uses all the list", (done) => {
|
|
22
19
|
|
|
23
20
|
const pool = new HostPool('1.1.1.1:1111, 2.2.2.2:2222');
|
|
24
21
|
|
|
@@ -26,29 +23,24 @@ exports.HostPool = {
|
|
|
26
23
|
const host2 = pool.get_host();
|
|
27
24
|
const host3 = pool.get_host();
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
"default port 25": test => {
|
|
36
|
-
test.expect(2);
|
|
26
|
+
assert.notEqual(host1.host, host2.host);
|
|
27
|
+
assert.notEqual(host3.host, host2.host);
|
|
28
|
+
assert.equal(host3.host, host1.host);
|
|
29
|
+
done()
|
|
30
|
+
})
|
|
37
31
|
|
|
32
|
+
it("default port 25", (done) => {
|
|
38
33
|
const pool = new HostPool('1.1.1.1, 2.2.2.2');
|
|
39
34
|
|
|
40
35
|
const host1 = pool.get_host();
|
|
41
36
|
const host2 = pool.get_host();
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
"dead host": test => {
|
|
50
|
-
test.expect(3);
|
|
38
|
+
assert.equal(host1.port, 25, `is port 25: ${host1.port}`);
|
|
39
|
+
assert.equal(host2.port, 25, `is port 25: ${host2.port}`);
|
|
40
|
+
done()
|
|
41
|
+
})
|
|
51
42
|
|
|
43
|
+
it("dead host", (done) => {
|
|
52
44
|
const pool = new HostPool('1.1.1.1:1111, 2.2.2.2:2222');
|
|
53
45
|
|
|
54
46
|
pool.failed('1.1.1.1', '1111');
|
|
@@ -56,20 +48,18 @@ exports.HostPool = {
|
|
|
56
48
|
let host;
|
|
57
49
|
|
|
58
50
|
host = pool.get_host();
|
|
59
|
-
|
|
51
|
+
assert.equal(host.host, '2.2.2.2', 'dead host is not returned');
|
|
60
52
|
host = pool.get_host();
|
|
61
|
-
|
|
53
|
+
assert.equal(host.host, '2.2.2.2', 'dead host is not returned');
|
|
62
54
|
host = pool.get_host();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
},
|
|
55
|
+
assert.equal(host.host, '2.2.2.2', 'dead host is not returned');
|
|
56
|
+
done()
|
|
57
|
+
})
|
|
67
58
|
|
|
68
59
|
// if they're *all* dead, we return a host to try anyway, to keep from
|
|
69
60
|
// accidentally DOS'ing ourselves if there's a transient but widespread
|
|
70
61
|
// network outage
|
|
71
|
-
"they're all dead"
|
|
72
|
-
test.expect(6);
|
|
62
|
+
it("they're all dead", (done) => {
|
|
73
63
|
|
|
74
64
|
let host1;
|
|
75
65
|
let host2;
|
|
@@ -82,26 +72,23 @@ exports.HostPool = {
|
|
|
82
72
|
pool.failed('2.2.2.2', '2222');
|
|
83
73
|
|
|
84
74
|
host2 = pool.get_host();
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
assert.ok (host2, "if they're all dead, try one anyway");
|
|
76
|
+
assert.notEqual(host1.host, host2.host, "rotation continues");
|
|
87
77
|
|
|
88
78
|
host1 = pool.get_host();
|
|
89
|
-
|
|
90
|
-
|
|
79
|
+
assert.ok (host1, "if they're all dead, try one anyway");
|
|
80
|
+
assert.notEqual(host1.host, host2.host, "rotation continues");
|
|
91
81
|
|
|
92
82
|
host2 = pool.get_host();
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
|
|
83
|
+
assert.ok (host2, "if they're all dead, try one anyway");
|
|
84
|
+
assert.notEqual(host1.host, host2.host, "rotation continues");
|
|
85
|
+
done()
|
|
86
|
+
})
|
|
99
87
|
|
|
100
88
|
// after .01 secs the timer to retry the dead host will fire, and then
|
|
101
89
|
// we connect using this mock socket, whose "connect" always succeeds
|
|
102
90
|
// so the code brings the dead host back to life
|
|
103
|
-
"host dead checking timer"
|
|
104
|
-
test.expect(2);
|
|
91
|
+
it("host dead checking timer", (done) => {
|
|
105
92
|
|
|
106
93
|
let num_reqs = 0;
|
|
107
94
|
const MockSocket = function MockSocket (pool) {
|
|
@@ -144,7 +131,6 @@ exports.HostPool = {
|
|
|
144
131
|
}
|
|
145
132
|
};
|
|
146
133
|
this.destroy = () => {};
|
|
147
|
-
|
|
148
134
|
};
|
|
149
135
|
|
|
150
136
|
const retry_secs = 0.001; // 1ms
|
|
@@ -156,24 +142,23 @@ exports.HostPool = {
|
|
|
156
142
|
// mark the host as failed and start up the retry timers
|
|
157
143
|
pool.failed('1.1.1.1', '1111');
|
|
158
144
|
|
|
159
|
-
|
|
145
|
+
assert.ok(pool.dead_hosts["1.1.1.1:1111"], 'yes it was marked dead');
|
|
160
146
|
|
|
161
147
|
// probe_dead_host() will hit two failures and one success (based on
|
|
162
148
|
// num_reqs above). So we wait at least 10s for that to happen:
|
|
163
149
|
const timer = setTimeout(() => {
|
|
164
150
|
clearInterval(interval);
|
|
165
|
-
|
|
166
|
-
|
|
151
|
+
assert.ok(false, 'probe_dead_host failed');
|
|
152
|
+
done()
|
|
167
153
|
}, 10 * 1000);
|
|
168
154
|
|
|
169
155
|
const interval = setInterval(() => {
|
|
170
156
|
if (!pool.dead_hosts["1.1.1.1:1111"]) {
|
|
171
157
|
clearTimeout(timer);
|
|
172
158
|
clearInterval(interval);
|
|
173
|
-
|
|
174
|
-
|
|
159
|
+
assert.ok(true, 'timer un-deaded it');
|
|
160
|
+
done()
|
|
175
161
|
}
|
|
176
162
|
}, retry_secs * 1000 * 3 );
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
163
|
+
})
|
|
164
|
+
})
|
package/test/logger.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
const assert = require('node:assert')
|
|
2
|
+
const util = require('node:util');
|
|
3
|
+
|
|
4
|
+
const _set_up = (done) => {
|
|
5
|
+
this.logger = require('../logger');
|
|
6
|
+
done();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe('logger', () => {
|
|
10
|
+
beforeEach(_set_up)
|
|
11
|
+
|
|
12
|
+
describe('init', () => {
|
|
13
|
+
it('logger', () => {
|
|
14
|
+
assert.ok(this.logger);
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
describe('log', () => {
|
|
19
|
+
it('log', () => {
|
|
20
|
+
this.logger.deferred_logs = [];
|
|
21
|
+
assert.equal(0, this.logger.deferred_logs.length);
|
|
22
|
+
assert.ok(this.logger.log('WARN','test warning'));
|
|
23
|
+
assert.equal(1, this.logger.deferred_logs.length);
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('log, w/deferred', () => {
|
|
27
|
+
this.logger.plugins = { plugin_list: true };
|
|
28
|
+
this.logger.deferred_logs.push( { level: 'INFO', data: 'log test info'} );
|
|
29
|
+
assert.ok(this.logger.log('INFO', 'another test info'));
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('log in logfmt', () => {
|
|
33
|
+
this.logger.deferred_logs = [];
|
|
34
|
+
this.logger.format = this.logger.formats.LOGFMT;
|
|
35
|
+
assert.equal(0, this.logger.deferred_logs.length);
|
|
36
|
+
assert.ok(this.logger.log('WARN','test warning'));
|
|
37
|
+
assert.equal(1, this.logger.deferred_logs.length);
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('log in logfmt w/deferred', () => {
|
|
41
|
+
this.logger.plugins = { plugin_list: true };
|
|
42
|
+
this.logger.deferred_logs.push( { level: 'INFO', data: 'log test info'} );
|
|
43
|
+
assert.ok(this.logger.log('INFO', 'another test info'));
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('log in json', () => {
|
|
47
|
+
this.logger.deferred_logs = [];
|
|
48
|
+
this.logger.format = this.logger.formats.JSON;
|
|
49
|
+
assert.equal(0, this.logger.deferred_logs.length);
|
|
50
|
+
assert.ok(this.logger.log('WARN','test warning'));
|
|
51
|
+
assert.equal(1, this.logger.deferred_logs.length);
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('log in json w/deferred', () => {
|
|
55
|
+
this.logger.plugins = { plugin_list: true };
|
|
56
|
+
this.logger.deferred_logs.push( { level: 'INFO', data: 'log test info'} );
|
|
57
|
+
assert.ok(this.logger.log('INFO', 'another test info'));
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
describe('level', () => {
|
|
62
|
+
it('both INFO and LOGINFO are log levels', () => {
|
|
63
|
+
assert.equal(this.logger.levels.INFO, 6);
|
|
64
|
+
assert.equal(this.logger.levels.LOGINFO, 6);
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('set_format', () => {
|
|
70
|
+
it('set format to DEFAULT', () => {
|
|
71
|
+
this.logger.format = '';
|
|
72
|
+
this.logger.set_format('DEFAULT');
|
|
73
|
+
assert.equal(this.logger.format, this.logger.formats.DEFAULT);
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('set format to LOGFMT', () => {
|
|
77
|
+
this.logger.format = '';
|
|
78
|
+
this.logger.set_format('LOGFMT');
|
|
79
|
+
assert.equal(this.logger.format, this.logger.formats.LOGFMT);
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('set format to JSON', () => {
|
|
83
|
+
this.logger.format = '';
|
|
84
|
+
this.logger.set_format('JSON');
|
|
85
|
+
assert.equal(this.logger.format, this.logger.formats.JSON);
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('set format to DEFAULT if empty', () => {
|
|
89
|
+
this.logger.format = '';
|
|
90
|
+
this.logger.set_format('');
|
|
91
|
+
assert.equal(this.logger.format, this.logger.formats.DEFAULT);
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('set format to DEFAULT if lowercase', () => {
|
|
95
|
+
this.logger.format = '';
|
|
96
|
+
this.logger.set_format('default');
|
|
97
|
+
assert.equal(this.logger.format, this.logger.formats.DEFAULT);
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('set format to DEFAULT if invalid', () => {
|
|
101
|
+
this.logger.format = '';
|
|
102
|
+
this.logger.set_format('invalid');
|
|
103
|
+
assert.equal(this.logger.format, this.logger.formats.DEFAULT);
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
describe('set_loglevel', () => {
|
|
109
|
+
it('set loglevel to LOGINFO', () => {
|
|
110
|
+
this.logger.set_loglevel('LOGINFO');
|
|
111
|
+
assert.equal(this.logger.loglevel, this.logger.levels.LOGINFO);
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('set loglevel to INFO', () => {
|
|
115
|
+
this.logger.set_loglevel('INFO');
|
|
116
|
+
assert.equal(this.logger.loglevel, this.logger.levels.INFO);
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('set loglevel to EMERG', () => {
|
|
120
|
+
this.logger.set_loglevel('emerg');
|
|
121
|
+
assert.equal(this.logger.loglevel, this.logger.levels.EMERG);
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('set loglevel to 6', () => {
|
|
125
|
+
this.logger.set_loglevel(6);
|
|
126
|
+
assert.equal(this.logger.loglevel, 6);
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('set loglevel to WARN if invalid', () => {
|
|
130
|
+
this.logger.set_loglevel('invalid');
|
|
131
|
+
assert.equal(this.logger.loglevel, this.logger.levels.WARN);
|
|
132
|
+
})
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
describe('set_timestamps', () => {
|
|
136
|
+
it('set timestamps to false', () => {
|
|
137
|
+
this.logger.timestamps = undefined;
|
|
138
|
+
this.logger.set_timestamps(false);
|
|
139
|
+
assert.equal(this.logger.timestamps, false);
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('set timestamps to true', () => {
|
|
143
|
+
this.logger.timestamps = undefined;
|
|
144
|
+
this.logger.set_timestamps(true);
|
|
145
|
+
assert.equal(this.logger.timestamps, true);
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
describe('would_log', () => {
|
|
150
|
+
it('should', () => {
|
|
151
|
+
this.logger.loglevel = 4;
|
|
152
|
+
assert.equal(false, this.logger.would_log(7));
|
|
153
|
+
assert.equal(false, this.logger.would_log(6));
|
|
154
|
+
assert.equal(false, this.logger.would_log(5));
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('should not', () => {
|
|
158
|
+
this.logger.loglevel = 4;
|
|
159
|
+
assert.equal(true, this.logger.would_log(4));
|
|
160
|
+
assert.equal(true, this.logger.would_log(3));
|
|
161
|
+
assert.equal(true, this.logger.would_log(2));
|
|
162
|
+
assert.equal(true, this.logger.would_log(1));
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
describe('log_respond', () => {
|
|
167
|
+
it('invalid retval', () => {
|
|
168
|
+
assert.equal(false, this.logger.log_respond(901));
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('valid retval', () => {
|
|
172
|
+
const data = { level: 'INFO', data: "test data" };
|
|
173
|
+
assert.equal(true, this.logger.log_respond(900, 'test msg', data));
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('dump_logs', () => {
|
|
178
|
+
it('empty', () => {
|
|
179
|
+
assert.ok(this.logger.dump_logs(0));
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('with deferred', () => {
|
|
183
|
+
this.logger.deferred_logs.push( { level: 'info', data: 'test info'} );
|
|
184
|
+
this.logger.deferred_logs.push( { level: 'INFO', data: 'test info, color'} );
|
|
185
|
+
this.logger.deferred_logs.push( { level: 'WARN', data: 'test warn, color'} );
|
|
186
|
+
assert.ok(this.logger.dump_logs(0));
|
|
187
|
+
assert.ok(this.logger.deferred_logs.length === 0);
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
describe('colors', () => {
|
|
192
|
+
it('colors', () => {
|
|
193
|
+
assert.ok(this.logger.colors);
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it('colorize', () => {
|
|
197
|
+
assert.ok(this.logger.colorize);
|
|
198
|
+
assert.equal('function', typeof this.logger.colorize);
|
|
199
|
+
assert.equal('error', this.logger.colorize('bad-color', 'error'));
|
|
200
|
+
const expected = util.inspect.colors ? '\u001b[34mgood\u001b[39m' : 'good';
|
|
201
|
+
assert.equal(expected, this.logger.colorize('blue', 'good'));
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
describe('log_if_level', () => {
|
|
206
|
+
it('log_if_level is a function', () => {
|
|
207
|
+
assert.ok('function' === typeof this.logger.log_if_level);
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
it('log_if_level test log entry', () => {
|
|
211
|
+
this.logger.loglevel = 9;
|
|
212
|
+
const f = this.logger.log_if_level('INFO', 'LOGINFO');
|
|
213
|
+
assert.ok(f);
|
|
214
|
+
assert.ok('function' === typeof f);
|
|
215
|
+
assert.ok(f('test info message'));
|
|
216
|
+
assert.equal(1, this.logger.deferred_logs.length);
|
|
217
|
+
// console.log(this.logger.deferred_logs[0]);
|
|
218
|
+
assert.equal('INFO', this.logger.deferred_logs[0].level);
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it('log_if_level null case', () => {
|
|
222
|
+
this.logger.loglevel = 9;
|
|
223
|
+
const f = this.logger.log_if_level('INFO', 'LOGINFO');
|
|
224
|
+
assert.ok(f(null));
|
|
225
|
+
assert.equal(2, this.logger.deferred_logs.length);
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('log_if_level false', () => {
|
|
229
|
+
this.logger.loglevel = 9;
|
|
230
|
+
const f = this.logger.log_if_level('INFO', 'LOGINFO');
|
|
231
|
+
assert.ok(f(false));
|
|
232
|
+
assert.equal(3, this.logger.deferred_logs.length);
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('log_if_level 0', () => {
|
|
236
|
+
this.logger.loglevel = 9;
|
|
237
|
+
const f = this.logger.log_if_level('INFO', 'LOGINFO');
|
|
238
|
+
assert.ok(f(0));
|
|
239
|
+
assert.equal(4, this.logger.deferred_logs.length);
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
describe('add_log_methods', () => {
|
|
244
|
+
it('ignores non-objects', () => {
|
|
245
|
+
assert.equal(undefined, this.logger.add_log_methods(''));
|
|
246
|
+
assert.equal(undefined, this.logger.add_log_methods(function foo (){}));
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it('adds functions to an object', () => {
|
|
250
|
+
const testObj = {};
|
|
251
|
+
this.logger.add_log_methods(testObj);
|
|
252
|
+
const levels = ['DATA','PROTOCOL','DEBUG','INFO','NOTICE','WARN','ERROR','CRIT','ALERT','EMERG'];
|
|
253
|
+
for (const level of levels) {
|
|
254
|
+
assert.ok('function' === typeof(testObj[`log${level.toLowerCase()}`]));
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
})
|