@yarkivaev/source-to-sink 1.1.0 → 1.2.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/.github/workflows/ci.yml +1 -1
- package/eslint.config.js +176 -0
- package/index.js +1 -0
- package/package.json +11 -5
- package/src/batch.js +2 -2
- package/src/lokiSource.js +3 -3
- package/src/modbusSource.js +52 -9
- package/src/mqttSource.js +5 -5
- package/src/pollingSource.js +4 -3
- package/src/postgresSink.js +7 -7
- package/src/sqliteSink.js +55 -0
- package/src/stompSource.js +20 -11
- package/src/timedBatch.js +4 -4
- package/test/integration_clickhouseSink.js +5 -5
- package/test/integration_lokiSource.js +13 -13
- package/test/integration_mqttSink.js +12 -12
- package/test/integration_mqttSource.js +19 -19
- package/test/test_batch.js +21 -35
- package/test/test_circuit.js +12 -12
- package/test/test_clickhouseSink.js +8 -8
- package/test/test_lokiSource.js +12 -12
- package/test/test_modbusSource.js +37 -14
- package/test/test_mqttSink.js +6 -6
- package/test/test_mqttSource.js +8 -8
- package/test/test_pollingSource.js +23 -23
- package/test/test_postgresSink.js +12 -12
- package/test/test_sqliteSink.js +176 -0
- package/test/test_stompSource.js +8 -8
- package/test/test_timedBatch.js +13 -13
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
-
import {
|
|
2
|
+
import { after, before, describe, it } from 'mocha';
|
|
3
3
|
import { GenericContainer } from 'testcontainers';
|
|
4
4
|
import lokiSource from '../src/lokiSource.js';
|
|
5
5
|
import clock from '../src/clock.js';
|
|
@@ -50,7 +50,7 @@ describe('lokiSource integration', function() {
|
|
|
50
50
|
// Loki not ready yet
|
|
51
51
|
}
|
|
52
52
|
retries -= 1;
|
|
53
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
53
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -65,13 +65,13 @@ describe('lokiSource integration', function() {
|
|
|
65
65
|
this.timeout(30000);
|
|
66
66
|
const received = [];
|
|
67
67
|
const app = `app${Math.random().toString(36).slice(2)}`;
|
|
68
|
-
const collector = { accept: (entry) => received.push(entry) };
|
|
68
|
+
const collector = { accept: (entry) => {return received.push(entry)} };
|
|
69
69
|
const clk = clock();
|
|
70
70
|
const source = lokiSource(url, `{app="${app}"}`, 0.5, collector, clk);
|
|
71
71
|
source.start();
|
|
72
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
72
|
+
await new Promise((resolve) => { setTimeout(resolve, 500); });
|
|
73
73
|
await pushToLoki(url, { app }, `test entry ${Math.random()}`);
|
|
74
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
74
|
+
await new Promise((resolve) => { setTimeout(resolve, 3000); });
|
|
75
75
|
source.stop();
|
|
76
76
|
assert.strictEqual(received.length >= 1, true, 'Should receive entries from Loki');
|
|
77
77
|
});
|
|
@@ -80,13 +80,13 @@ describe('lokiSource integration', function() {
|
|
|
80
80
|
this.timeout(30000);
|
|
81
81
|
const received = [];
|
|
82
82
|
const app = `app${Math.random().toString(36).slice(2)}`;
|
|
83
|
-
const collector = { accept: (entry) => received.push(entry) };
|
|
83
|
+
const collector = { accept: (entry) => {return received.push(entry)} };
|
|
84
84
|
const clk = clock();
|
|
85
85
|
const source = lokiSource(url, `{app="${app}"}`, 0.5, collector, clk);
|
|
86
86
|
source.start();
|
|
87
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
87
|
+
await new Promise((resolve) => { setTimeout(resolve, 500); });
|
|
88
88
|
await pushToLoki(url, { app }, `тест запись ${Math.random()}`);
|
|
89
|
-
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
89
|
+
await new Promise((resolve) => { setTimeout(resolve, 3000); });
|
|
90
90
|
source.stop();
|
|
91
91
|
assert.strictEqual(received.length >= 1, true, 'Should receive entries with unicode');
|
|
92
92
|
});
|
|
@@ -95,15 +95,15 @@ describe('lokiSource integration', function() {
|
|
|
95
95
|
this.timeout(30000);
|
|
96
96
|
const received = [];
|
|
97
97
|
const app = `app${Math.random().toString(36).slice(2)}`;
|
|
98
|
-
const collector = { accept: (entry) => received.push(entry) };
|
|
98
|
+
const collector = { accept: (entry) => {return received.push(entry)} };
|
|
99
99
|
const clk = clock();
|
|
100
100
|
const source = lokiSource(url, `{app="${app}"}`, 0.5, collector, clk);
|
|
101
101
|
source.start();
|
|
102
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
102
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
103
103
|
source.stop();
|
|
104
|
-
const
|
|
104
|
+
const snapshot = received.length;
|
|
105
105
|
await pushToLoki(url, { app }, `after stop ${Math.random()}`);
|
|
106
|
-
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
107
|
-
assert.strictEqual(received.length,
|
|
106
|
+
await new Promise((resolve) => { setTimeout(resolve, 2000); });
|
|
107
|
+
assert.strictEqual(received.length, snapshot, 'Should not receive entries after stop');
|
|
108
108
|
});
|
|
109
109
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
-
import {
|
|
2
|
+
import { after, before, describe, it } from 'mocha';
|
|
3
3
|
import { GenericContainer } from 'testcontainers';
|
|
4
4
|
import mqtt from 'mqtt';
|
|
5
5
|
import mqttSink from '../src/mqttSink.js';
|
|
@@ -23,7 +23,7 @@ describe('mqttSink integration', function() {
|
|
|
23
23
|
await new Promise((resolve, reject) => {
|
|
24
24
|
subscriber.on('connect', resolve);
|
|
25
25
|
subscriber.on('error', reject);
|
|
26
|
-
setTimeout(() => reject(new Error('MQTT connection timeout')), 10000);
|
|
26
|
+
setTimeout(() => { reject(new Error('MQTT connection timeout')); }, 10000);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
|
|
@@ -45,13 +45,13 @@ describe('mqttSink integration', function() {
|
|
|
45
45
|
subscriber.on('message', (t, payload) => {
|
|
46
46
|
received.push({ topic: t, payload: payload.toString() });
|
|
47
47
|
});
|
|
48
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
48
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
49
49
|
const sink = mqttSink(url);
|
|
50
50
|
sink.start();
|
|
51
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
51
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
52
52
|
const value = `${Math.random()}`;
|
|
53
53
|
sink.write([{ topic, payload: value }]);
|
|
54
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
54
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
55
55
|
sink.stop();
|
|
56
56
|
assert.strictEqual(received.length >= 1, true, 'Subscriber should receive published record');
|
|
57
57
|
});
|
|
@@ -66,13 +66,13 @@ describe('mqttSink integration', function() {
|
|
|
66
66
|
received.push(payload.toString());
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
69
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
70
70
|
const sink = mqttSink(url);
|
|
71
71
|
sink.start();
|
|
72
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
72
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
73
73
|
const text = `Данные температуры ${Math.random()}`;
|
|
74
74
|
sink.write([{ topic, payload: text }]);
|
|
75
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
75
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
76
76
|
sink.stop();
|
|
77
77
|
assert.strictEqual(received.length >= 1, true, 'Subscriber should receive unicode payload');
|
|
78
78
|
});
|
|
@@ -87,14 +87,14 @@ describe('mqttSink integration', function() {
|
|
|
87
87
|
received.push(payload.toString());
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
90
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
91
91
|
const sink = mqttSink(url);
|
|
92
92
|
sink.start();
|
|
93
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
93
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
94
94
|
sink.stop();
|
|
95
95
|
assert.throws(
|
|
96
|
-
() => sink.write([{ topic, payload: `${Math.random()}` }]),
|
|
97
|
-
/not connected
|
|
96
|
+
() => {return sink.write([{ topic, payload: `${Math.random()}` }])},
|
|
97
|
+
/not connected/u,
|
|
98
98
|
'Should throw when writing after stop'
|
|
99
99
|
);
|
|
100
100
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
-
import {
|
|
2
|
+
import { after, before, describe, it } from 'mocha';
|
|
3
3
|
import { GenericContainer } from 'testcontainers';
|
|
4
4
|
import mqtt from 'mqtt';
|
|
5
5
|
import mqttSource from '../src/mqttSource.js';
|
|
@@ -23,7 +23,7 @@ describe('mqttSource integration', function() {
|
|
|
23
23
|
await new Promise((resolve, reject) => {
|
|
24
24
|
publisher.on('connect', resolve);
|
|
25
25
|
publisher.on('error', reject);
|
|
26
|
-
setTimeout(() => reject(new Error('MQTT connection timeout')), 10000);
|
|
26
|
+
setTimeout(() => { reject(new Error('MQTT connection timeout')); }, 10000);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
|
|
@@ -41,13 +41,13 @@ describe('mqttSource integration', function() {
|
|
|
41
41
|
this.timeout(10000);
|
|
42
42
|
const received = [];
|
|
43
43
|
const topic = `sensors/${Math.random().toString(36).slice(2)}`;
|
|
44
|
-
const collector = { accept: (record) => received.push(record) };
|
|
44
|
+
const collector = { accept: (record) => {return received.push(record)} };
|
|
45
45
|
const source = mqttSource(url, topic, collector);
|
|
46
46
|
source.start();
|
|
47
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
47
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
48
48
|
const record = { value: Math.random(), unit: `\u00b0C` };
|
|
49
49
|
publisher.publish(topic, JSON.stringify(record));
|
|
50
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
50
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
51
51
|
source.stop();
|
|
52
52
|
assert.strictEqual(received.length >= 1, true, 'Should receive message from broker');
|
|
53
53
|
});
|
|
@@ -56,13 +56,13 @@ describe('mqttSource integration', function() {
|
|
|
56
56
|
this.timeout(10000);
|
|
57
57
|
const received = [];
|
|
58
58
|
const topic = `sensors/${Math.random().toString(36).slice(2)}`;
|
|
59
|
-
const collector = { accept: (record) => received.push(record) };
|
|
59
|
+
const collector = { accept: (record) => {return received.push(record)} };
|
|
60
60
|
const source = mqttSource(url, topic, collector);
|
|
61
61
|
source.start();
|
|
62
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
62
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
63
63
|
const record = { name: `Тест${Math.random()}`, value: Math.random() };
|
|
64
64
|
publisher.publish(topic, JSON.stringify(record));
|
|
65
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
65
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
66
66
|
source.stop();
|
|
67
67
|
assert.strictEqual(received.length >= 1, true, 'Should receive message with unicode');
|
|
68
68
|
});
|
|
@@ -71,15 +71,15 @@ describe('mqttSource integration', function() {
|
|
|
71
71
|
this.timeout(10000);
|
|
72
72
|
const received = [];
|
|
73
73
|
const topic = `sensors/${Math.random().toString(36).slice(2)}`;
|
|
74
|
-
const collector = { accept: (record) => received.push(record) };
|
|
74
|
+
const collector = { accept: (record) => {return received.push(record)} };
|
|
75
75
|
const source = mqttSource(url, topic, collector);
|
|
76
76
|
source.start();
|
|
77
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
77
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
78
78
|
source.stop();
|
|
79
|
-
const
|
|
79
|
+
const snapshot = received.length;
|
|
80
80
|
publisher.publish(topic, JSON.stringify({ value: Math.random() }));
|
|
81
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
82
|
-
assert.strictEqual(received.length,
|
|
81
|
+
await new Promise((resolve) => { setTimeout(resolve, 500); });
|
|
82
|
+
assert.strictEqual(received.length, snapshot, 'Should not receive messages after stop');
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
it('receives messages from multiple comma separated topics', async function() {
|
|
@@ -89,13 +89,13 @@ describe('mqttSource integration', function() {
|
|
|
89
89
|
const first = `plant/${suffix}`;
|
|
90
90
|
const second = `device/${suffix}`;
|
|
91
91
|
const topics = `${first},${second}`;
|
|
92
|
-
const collector = { accept: (record) => received.push(record) };
|
|
92
|
+
const collector = { accept: (record) => {return received.push(record)} };
|
|
93
93
|
const source = mqttSource(url, topics, collector);
|
|
94
94
|
source.start();
|
|
95
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
95
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
96
96
|
publisher.publish(first, JSON.stringify({ source: 'first', value: Math.random() }));
|
|
97
97
|
publisher.publish(second, JSON.stringify({ source: 'second', value: Math.random() }));
|
|
98
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
98
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
99
99
|
source.stop();
|
|
100
100
|
assert.strictEqual(received.length, 2, 'Should receive messages from both topics');
|
|
101
101
|
});
|
|
@@ -104,13 +104,13 @@ describe('mqttSource integration', function() {
|
|
|
104
104
|
this.timeout(10000);
|
|
105
105
|
const received = [];
|
|
106
106
|
const topic = `raw/${Math.random().toString(36).slice(2)}`;
|
|
107
|
-
const collector = { accept: (record) => received.push(record) };
|
|
107
|
+
const collector = { accept: (record) => {return received.push(record)} };
|
|
108
108
|
const source = mqttSource(url, topic, collector);
|
|
109
109
|
source.start();
|
|
110
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
110
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
111
111
|
const payload = `plain text message ${Math.random()}`;
|
|
112
112
|
publisher.publish(topic, payload);
|
|
113
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
113
|
+
await new Promise((resolve) => { setTimeout(resolve, 1000); });
|
|
114
114
|
source.stop();
|
|
115
115
|
assert.strictEqual(received.length, 1, 'Should receive raw message');
|
|
116
116
|
assert.strictEqual(received[0].topic, topic, 'Should include topic');
|
package/test/test_batch.js
CHANGED
|
@@ -7,12 +7,12 @@ import fakeClock from './fakeClock.js';
|
|
|
7
7
|
describe('batch', () => {
|
|
8
8
|
it('flushes when batch size is reached', () => {
|
|
9
9
|
const received = [];
|
|
10
|
-
const sink = { write: (records) => received.push(...records) };
|
|
10
|
+
const sink = { write: (records) => {return received.push(...records)} };
|
|
11
11
|
const size = Math.floor(Math.random() * 5) + 2;
|
|
12
12
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
13
13
|
const c = circuit(5, 60, clk);
|
|
14
14
|
const b = batch(sink, size, c);
|
|
15
|
-
for (let i = 0; i < size; i
|
|
15
|
+
for (let i = 0; i < size; i += 1) {
|
|
16
16
|
b.accept({ value: `\u00e9\u00f1\u00fc${i}` });
|
|
17
17
|
}
|
|
18
18
|
b.stop();
|
|
@@ -21,12 +21,12 @@ describe('batch', () => {
|
|
|
21
21
|
|
|
22
22
|
it('flushes on manual flush call', () => {
|
|
23
23
|
const received = [];
|
|
24
|
-
const sink = { write: (records) => received.push(...records) };
|
|
24
|
+
const sink = { write: (records) => {return received.push(...records)} };
|
|
25
25
|
const count = Math.floor(Math.random() * 5) + 1;
|
|
26
26
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
27
27
|
const c = circuit(5, 60, clk);
|
|
28
28
|
const b = batch(sink, 100, c);
|
|
29
|
-
for (let i = 0; i < count; i
|
|
29
|
+
for (let i = 0; i < count; i += 1) {
|
|
30
30
|
b.accept({ id: `\u4e2d\u6587${i}` });
|
|
31
31
|
}
|
|
32
32
|
b.flush();
|
|
@@ -47,12 +47,12 @@ describe('batch', () => {
|
|
|
47
47
|
|
|
48
48
|
it('clears records on stop', () => {
|
|
49
49
|
const received = [];
|
|
50
|
-
const sink = { write: (records) => received.push(...records) };
|
|
50
|
+
const sink = { write: (records) => {return received.push(...records)} };
|
|
51
51
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
52
52
|
const c = circuit(5, 60, clk);
|
|
53
53
|
const b = batch(sink, 100, c);
|
|
54
54
|
const count = Math.floor(Math.random() * 5) + 1;
|
|
55
|
-
for (let i = 0; i < count; i
|
|
55
|
+
for (let i = 0; i < count; i += 1) {
|
|
56
56
|
b.accept({ x: Math.random() });
|
|
57
57
|
}
|
|
58
58
|
b.stop();
|
|
@@ -62,7 +62,7 @@ describe('batch', () => {
|
|
|
62
62
|
|
|
63
63
|
it('respects circuit when allowing', () => {
|
|
64
64
|
const received = [];
|
|
65
|
-
const sink = { write: (records) => received.push(...records) };
|
|
65
|
+
const sink = { write: (records) => {return received.push(...records)} };
|
|
66
66
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
67
67
|
const c = circuit(5, 60, clk);
|
|
68
68
|
const b = batch(sink, 2, c);
|
|
@@ -74,7 +74,7 @@ describe('batch', () => {
|
|
|
74
74
|
|
|
75
75
|
it('skips flush when circuit is not allowing', () => {
|
|
76
76
|
const received = [];
|
|
77
|
-
const sink = { write: (records) => received.push(...records) };
|
|
77
|
+
const sink = { write: (records) => {return received.push(...records)} };
|
|
78
78
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
79
79
|
const c = circuit(1, 60, clk);
|
|
80
80
|
c.fail();
|
|
@@ -89,7 +89,7 @@ describe('batch', () => {
|
|
|
89
89
|
let succeeded = false;
|
|
90
90
|
const sink = { write: () => {} };
|
|
91
91
|
const c = {
|
|
92
|
-
allowing: () => true,
|
|
92
|
+
allowing: () => {return true},
|
|
93
93
|
succeed: () => { succeeded = true; },
|
|
94
94
|
fail: () => {}
|
|
95
95
|
};
|
|
@@ -99,29 +99,15 @@ describe('batch', () => {
|
|
|
99
99
|
assert.strictEqual(succeeded, true, 'Should call succeed on circuit');
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
it('calls fail on circuit when sink throws', () => {
|
|
103
|
-
let failed = false;
|
|
104
|
-
const sink = { write: () => { throw new Error('Sink failure'); } };
|
|
105
|
-
const c = {
|
|
106
|
-
allowing: () => true,
|
|
107
|
-
succeed: () => {},
|
|
108
|
-
fail: () => { failed = true; }
|
|
109
|
-
};
|
|
110
|
-
const b = batch(sink, 1, c);
|
|
111
|
-
try { b.accept({ v: Math.random() }); } catch (e) { /* expected */ }
|
|
112
|
-
b.stop();
|
|
113
|
-
assert.strictEqual(failed, true, 'Should call fail on circuit');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
102
|
it('propagates error when sink throws', () => {
|
|
117
103
|
const sink = { write: () => { throw new Error('Sink failure'); } };
|
|
118
104
|
const c = {
|
|
119
|
-
allowing: () => true,
|
|
105
|
+
allowing: () => {return true},
|
|
120
106
|
succeed: () => {},
|
|
121
107
|
fail: () => {}
|
|
122
108
|
};
|
|
123
109
|
const b = batch(sink, 1, c);
|
|
124
|
-
assert.throws(() => b.accept({ v: Math.random() }), /Sink failure
|
|
110
|
+
assert.throws(() => {return b.accept({ v: Math.random() })}, /Sink failure/u, 'Should propagate error');
|
|
125
111
|
});
|
|
126
112
|
|
|
127
113
|
it('preserves records after failed write', () => {
|
|
@@ -137,34 +123,34 @@ describe('batch', () => {
|
|
|
137
123
|
}
|
|
138
124
|
};
|
|
139
125
|
const c = {
|
|
140
|
-
allowing: () => true,
|
|
126
|
+
allowing: () => {return true},
|
|
141
127
|
succeed: () => {},
|
|
142
128
|
fail: () => {}
|
|
143
129
|
};
|
|
144
130
|
const b = batch(sink, 100, c);
|
|
145
131
|
b.accept({ data: `\u00e9${Math.random()}` });
|
|
146
|
-
|
|
132
|
+
assert.throws(() => {return b.flush()}, /Temporary failure/u, 'Should throw on first attempt');
|
|
147
133
|
b.flush();
|
|
148
134
|
b.stop();
|
|
149
135
|
assert.strictEqual(received.length, 1, 'Should preserve records after failed write');
|
|
150
136
|
});
|
|
151
137
|
|
|
152
138
|
it('throws on missing sink', () => {
|
|
153
|
-
const c = { allowing: () => true, succeed: () => {}, fail: () => {} };
|
|
139
|
+
const c = { allowing: () => {return true}, succeed: () => {}, fail: () => {} };
|
|
154
140
|
assert.throws(
|
|
155
|
-
() => batch(null, 10, c),
|
|
156
|
-
/Sink must have a write
|
|
141
|
+
() => {return batch(null, 10, c)},
|
|
142
|
+
/Sink must have a write/u,
|
|
157
143
|
'Should reject missing sink'
|
|
158
144
|
);
|
|
159
145
|
});
|
|
160
146
|
|
|
161
147
|
it('throws on invalid size', () => {
|
|
162
148
|
const sink = { write: () => {} };
|
|
163
|
-
const c = { allowing: () => true, succeed: () => {}, fail: () => {} };
|
|
149
|
+
const c = { allowing: () => {return true}, succeed: () => {}, fail: () => {} };
|
|
164
150
|
const invalid = -Math.floor(Math.random() * 10);
|
|
165
151
|
assert.throws(
|
|
166
|
-
() => batch(sink, invalid, c),
|
|
167
|
-
/Size must be a positive number
|
|
152
|
+
() => {return batch(sink, invalid, c)},
|
|
153
|
+
/Size must be a positive number/u,
|
|
168
154
|
'Should reject invalid size'
|
|
169
155
|
);
|
|
170
156
|
});
|
|
@@ -172,8 +158,8 @@ describe('batch', () => {
|
|
|
172
158
|
it('throws on missing circuit', () => {
|
|
173
159
|
const sink = { write: () => {} };
|
|
174
160
|
assert.throws(
|
|
175
|
-
() => batch(sink, 10),
|
|
176
|
-
/Circuit must have an allowing\(\) method
|
|
161
|
+
() => {return batch(sink, 10)},
|
|
162
|
+
/Circuit must have an allowing\(\) method/u,
|
|
177
163
|
'Should reject missing circuit'
|
|
178
164
|
);
|
|
179
165
|
});
|
package/test/test_circuit.js
CHANGED
|
@@ -17,7 +17,7 @@ describe('circuit', () => {
|
|
|
17
17
|
const timeout = Math.random() * 100 + 1;
|
|
18
18
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
19
19
|
const c = circuit(threshold, timeout, clk);
|
|
20
|
-
for (let i = 0; i < threshold - 1; i
|
|
20
|
+
for (let i = 0; i < threshold - 1; i += 1) {
|
|
21
21
|
c.fail();
|
|
22
22
|
}
|
|
23
23
|
assert.strictEqual(c.allowing(), true, 'Circuit should remain allowing below threshold');
|
|
@@ -28,7 +28,7 @@ describe('circuit', () => {
|
|
|
28
28
|
const timeout = Math.random() * 100 + 1;
|
|
29
29
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
30
30
|
const c = circuit(threshold, timeout, clk);
|
|
31
|
-
for (let i = 0; i < threshold; i
|
|
31
|
+
for (let i = 0; i < threshold; i += 1) {
|
|
32
32
|
c.fail();
|
|
33
33
|
}
|
|
34
34
|
assert.strictEqual(c.allowing(), false, 'Circuit should stop allowing at threshold');
|
|
@@ -39,7 +39,7 @@ describe('circuit', () => {
|
|
|
39
39
|
const timeout = Math.random() * 100 + 1;
|
|
40
40
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
41
41
|
const c = circuit(threshold, timeout, clk);
|
|
42
|
-
for (let i = 0; i < threshold - 1; i
|
|
42
|
+
for (let i = 0; i < threshold - 1; i += 1) {
|
|
43
43
|
c.fail();
|
|
44
44
|
}
|
|
45
45
|
c.succeed();
|
|
@@ -52,7 +52,7 @@ describe('circuit', () => {
|
|
|
52
52
|
const timeout = 60;
|
|
53
53
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
54
54
|
const c = circuit(threshold, timeout, clk);
|
|
55
|
-
for (let i = 0; i < threshold; i
|
|
55
|
+
for (let i = 0; i < threshold; i += 1) {
|
|
56
56
|
c.fail();
|
|
57
57
|
}
|
|
58
58
|
clk.advance(timeout * 1000);
|
|
@@ -64,8 +64,8 @@ describe('circuit', () => {
|
|
|
64
64
|
const invalid = -Math.floor(Math.random() * 10);
|
|
65
65
|
const clk = fakeClock(0);
|
|
66
66
|
assert.throws(
|
|
67
|
-
() => circuit(invalid, timeout, clk),
|
|
68
|
-
/Threshold must be a positive number
|
|
67
|
+
() => {return circuit(invalid, timeout, clk)},
|
|
68
|
+
/Threshold must be a positive number/u,
|
|
69
69
|
'Should reject invalid threshold'
|
|
70
70
|
);
|
|
71
71
|
});
|
|
@@ -75,8 +75,8 @@ describe('circuit', () => {
|
|
|
75
75
|
const invalid = -Math.random() * 10 - 1;
|
|
76
76
|
const clk = fakeClock(0);
|
|
77
77
|
assert.throws(
|
|
78
|
-
() => circuit(threshold, invalid, clk),
|
|
79
|
-
/Timeout must be a non-negative number
|
|
78
|
+
() => {return circuit(threshold, invalid, clk)},
|
|
79
|
+
/Timeout must be a non-negative number/u,
|
|
80
80
|
'Should reject invalid timeout'
|
|
81
81
|
);
|
|
82
82
|
});
|
|
@@ -85,8 +85,8 @@ describe('circuit', () => {
|
|
|
85
85
|
const threshold = Math.floor(Math.random() * 10) + 1;
|
|
86
86
|
const timeout = Math.random() * 100 + 1;
|
|
87
87
|
assert.throws(
|
|
88
|
-
() => circuit(threshold, timeout),
|
|
89
|
-
/Clock must have a millis\(\) method
|
|
88
|
+
() => {return circuit(threshold, timeout)},
|
|
89
|
+
/Clock must have a millis\(\) method/u,
|
|
90
90
|
'Should reject missing clock'
|
|
91
91
|
);
|
|
92
92
|
});
|
|
@@ -96,12 +96,12 @@ describe('circuit', () => {
|
|
|
96
96
|
const timeout = 60;
|
|
97
97
|
const clk = fakeClock(Math.floor(Math.random() * 10000));
|
|
98
98
|
const c = circuit(threshold, timeout, clk);
|
|
99
|
-
for (let i = 0; i < threshold; i
|
|
99
|
+
for (let i = 0; i < threshold; i += 1) {
|
|
100
100
|
c.fail();
|
|
101
101
|
}
|
|
102
102
|
clk.advance(timeout * 1000);
|
|
103
103
|
c.allowing();
|
|
104
|
-
for (let i = 0; i < threshold - 1; i
|
|
104
|
+
for (let i = 0; i < threshold - 1; i += 1) {
|
|
105
105
|
c.fail();
|
|
106
106
|
}
|
|
107
107
|
assert.strictEqual(c.allowing(), true, 'Circuit should remain allowing after reset');
|
|
@@ -5,32 +5,32 @@ import clickhouseSink from '../src/clickhouseSink.js';
|
|
|
5
5
|
describe('clickhouseSink', () => {
|
|
6
6
|
it('throws on missing url', () => {
|
|
7
7
|
assert.throws(
|
|
8
|
-
() => clickhouseSink(null, 'metrics'),
|
|
9
|
-
/URL must be a non-empty string
|
|
8
|
+
() => {return clickhouseSink(null, 'metrics')},
|
|
9
|
+
/URL must be a non-empty string/u,
|
|
10
10
|
'Should reject missing url'
|
|
11
11
|
);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
it('throws on empty url', () => {
|
|
15
15
|
assert.throws(
|
|
16
|
-
() => clickhouseSink('', 'metrics'),
|
|
17
|
-
/URL must be a non-empty string
|
|
16
|
+
() => {return clickhouseSink('', 'metrics')},
|
|
17
|
+
/URL must be a non-empty string/u,
|
|
18
18
|
'Should reject empty url'
|
|
19
19
|
);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
it('throws on missing table', () => {
|
|
23
23
|
assert.throws(
|
|
24
|
-
() => clickhouseSink('http://localhost:8123', null),
|
|
25
|
-
/Table must be a non-empty string
|
|
24
|
+
() => {return clickhouseSink('http://localhost:8123', null)},
|
|
25
|
+
/Table must be a non-empty string/u,
|
|
26
26
|
'Should reject missing table'
|
|
27
27
|
);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
it('throws on empty table', () => {
|
|
31
31
|
assert.throws(
|
|
32
|
-
() => clickhouseSink('http://localhost:8123', ''),
|
|
33
|
-
/Table must be a non-empty string
|
|
32
|
+
() => {return clickhouseSink('http://localhost:8123', '')},
|
|
33
|
+
/Table must be a non-empty string/u,
|
|
34
34
|
'Should reject empty table'
|
|
35
35
|
);
|
|
36
36
|
});
|
package/test/test_lokiSource.js
CHANGED
|
@@ -8,8 +8,8 @@ describe('lokiSource', () => {
|
|
|
8
8
|
const collector = { accept: () => {} };
|
|
9
9
|
const clk = fakeClock(0);
|
|
10
10
|
assert.throws(
|
|
11
|
-
() => lokiSource(null, '{app="test"}', 10, collector, clk),
|
|
12
|
-
/URL must be a non-empty string
|
|
11
|
+
() => {return lokiSource(null, '{app="test"}', 10, collector, clk)},
|
|
12
|
+
/URL must be a non-empty string/u,
|
|
13
13
|
'Should reject missing url'
|
|
14
14
|
);
|
|
15
15
|
});
|
|
@@ -18,8 +18,8 @@ describe('lokiSource', () => {
|
|
|
18
18
|
const collector = { accept: () => {} };
|
|
19
19
|
const clk = fakeClock(0);
|
|
20
20
|
assert.throws(
|
|
21
|
-
() => lokiSource('', '{app="test"}', 10, collector, clk),
|
|
22
|
-
/URL must be a non-empty string
|
|
21
|
+
() => {return lokiSource('', '{app="test"}', 10, collector, clk)},
|
|
22
|
+
/URL must be a non-empty string/u,
|
|
23
23
|
'Should reject empty url'
|
|
24
24
|
);
|
|
25
25
|
});
|
|
@@ -28,8 +28,8 @@ describe('lokiSource', () => {
|
|
|
28
28
|
const collector = { accept: () => {} };
|
|
29
29
|
const clk = fakeClock(0);
|
|
30
30
|
assert.throws(
|
|
31
|
-
() => lokiSource('http://localhost:3100', '', 10, collector, clk),
|
|
32
|
-
/Query must be a non-empty string
|
|
31
|
+
() => {return lokiSource('http://localhost:3100', '', 10, collector, clk)},
|
|
32
|
+
/Query must be a non-empty string/u,
|
|
33
33
|
'Should reject empty query'
|
|
34
34
|
);
|
|
35
35
|
});
|
|
@@ -38,8 +38,8 @@ describe('lokiSource', () => {
|
|
|
38
38
|
const collector = { accept: () => {} };
|
|
39
39
|
const clk = fakeClock(0);
|
|
40
40
|
assert.throws(
|
|
41
|
-
() => lokiSource('http://localhost:3100', '{app="test"}', -1, collector, clk),
|
|
42
|
-
/Interval must be a positive number
|
|
41
|
+
() => {return lokiSource('http://localhost:3100', '{app="test"}', -1, collector, clk)},
|
|
42
|
+
/Interval must be a positive number/u,
|
|
43
43
|
'Should reject invalid interval'
|
|
44
44
|
);
|
|
45
45
|
});
|
|
@@ -47,8 +47,8 @@ describe('lokiSource', () => {
|
|
|
47
47
|
it('throws on missing collector', () => {
|
|
48
48
|
const clk = fakeClock(0);
|
|
49
49
|
assert.throws(
|
|
50
|
-
() => lokiSource('http://localhost:3100', '{app="test"}', 10, null, clk),
|
|
51
|
-
/Collector must have an accept\(\) method
|
|
50
|
+
() => {return lokiSource('http://localhost:3100', '{app="test"}', 10, null, clk)},
|
|
51
|
+
/Collector must have an accept\(\) method/u,
|
|
52
52
|
'Should reject missing collector'
|
|
53
53
|
);
|
|
54
54
|
});
|
|
@@ -56,8 +56,8 @@ describe('lokiSource', () => {
|
|
|
56
56
|
it('throws on missing clock', () => {
|
|
57
57
|
const collector = { accept: () => {} };
|
|
58
58
|
assert.throws(
|
|
59
|
-
() => lokiSource('http://localhost:3100', '{app="test"}', 10, collector, null),
|
|
60
|
-
/Clock must have a millis\(\) method
|
|
59
|
+
() => {return lokiSource('http://localhost:3100', '{app="test"}', 10, collector, null)},
|
|
60
|
+
/Clock must have a millis\(\) method/u,
|
|
61
61
|
'Should reject missing clock'
|
|
62
62
|
);
|
|
63
63
|
});
|