ccxt 4.1.97 → 4.1.98

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/run-tests-ws.js DELETED
@@ -1,290 +0,0 @@
1
- // ----------------------------------------------------------------------------
2
- // Usage: node run-tests [--php] [--js] [--python] [exchange] [symbol]
3
-
4
- // ----------------------------------------------------------------------------
5
-
6
- import fs from 'fs'
7
- import ansi from 'ansicolor'
8
- import log from 'ololog'
9
- import {spawn} from 'child_process'
10
- ansi.nice
11
-
12
- // ----------------------------------------------------------------------------
13
-
14
- const [,, ...args] = process.argv
15
-
16
- const keys = {
17
-
18
- '--ts': false, // run TypeScript tests only
19
- '--js': false, // run JavaScript tests only
20
- '--php': false, // run PHP tests only
21
- '--python': false, // run Python 3 tests only
22
- '--python-async': false, // run Python 3 async tests only
23
- }
24
-
25
- let exchanges = []
26
- let symbol = 'all'
27
- let maxConcurrency = 5 // Number.MAX_VALUE // no limit
28
-
29
- for (const arg of args) {
30
- if (arg.startsWith ('--')) { keys[arg] = true }
31
- else if (arg.includes ('/')) { symbol = arg }
32
- else if (Number.isFinite (Number (arg))) { maxConcurrency = Number (arg) }
33
- else { exchanges.push (arg) }
34
- }
35
-
36
- // ----------------------------------------------------------------------------
37
-
38
- if (!exchanges.length) {
39
-
40
- if (!fs.existsSync ('./exchanges.json')) {
41
-
42
- log.bright.red ('\n\tNo', 'exchanges.json'.white, 'found, please run', 'npm run build'.white, 'to generate it!\n')
43
- process.exit (1)
44
- }
45
- let exchangesFile = fs.readFileSync('./exchanges.json');
46
- exchangesFile = JSON.parse(exchangesFile)
47
- exchanges = exchangesFile.ws
48
- }
49
-
50
- // ----------------------------------------------------------------------------
51
-
52
- const sleep = s => new Promise (resolve => setTimeout (resolve, s))
53
- const maxProcessTimeout = 300000 // 5 minutes
54
-
55
- // ----------------------------------------------------------------------------
56
-
57
- const exec = (bin, ...args) => {
58
-
59
- // a custom version of child_process.exec that captures both stdout and
60
- // stderr, not separating them into distinct buffers — so that we can show
61
- // the same output as if it were running in a terminal.
62
-
63
- const ps = spawn (bin, args, { timeout: maxProcessTimeout })
64
-
65
- let output = ''
66
- let stderr = ''
67
- let hasWarnings = false
68
-
69
- ps.stdout.on ('data', data => { output += data.toString () })
70
- ps.stderr.on ('data', data => { output += data.toString (); stderr += data.toString (); hasWarnings = true })
71
-
72
- let return_
73
- const promise = new Promise ((resolve) => {
74
- return_ = resolve
75
- })
76
-
77
- ps.on ('exit', (code, signal) => {
78
-
79
- output = ansi.strip (output.trim ())
80
- stderr = ansi.strip (stderr)
81
-
82
- const regex = /\[[a-z]+?\]/gmi
83
-
84
- let match = undefined
85
- const warnings = []
86
-
87
- match = regex.exec (output)
88
-
89
- if (match) {
90
- warnings.push (match[0])
91
- do {
92
- if (match = regex.exec (output)) {
93
- warnings.push (match[0])
94
- }
95
- } while (match);
96
- }
97
-
98
- return_ ({
99
- failed: code !== 0,
100
- stalled: (code === null) && (signal !== null),
101
- output,
102
- hasOutput: output.length > 0,
103
- hasWarnings: hasWarnings || warnings.length > 0,
104
- warnings: warnings,
105
- })
106
- })
107
- return promise
108
- }
109
-
110
- // ----------------------------------------------------------------------------
111
-
112
- let numExchangesTested = 0
113
-
114
- // tests of different languages for the same exchange should be run
115
- // sequentially to prevent the interleaving nonces problem.
116
-
117
- // ----------------------------------------------------------------------------
118
-
119
- const sequentialMap = async (input, fn) => {
120
-
121
- const result = []
122
- for (const item of input) { result.push (await fn (item)) }
123
- return result
124
- }
125
-
126
- // ----------------------------------------------------------------------------
127
-
128
- const testExchange = async (exchange) => {
129
-
130
- // run tests for all/selected languages (in parallel)
131
-
132
- const args = [exchange, ... (symbol === 'all') ? [] : [ symbol ]]
133
- , allTestsWithoutTs = [
134
- { language: 'JavaScript', key: '--js', exec: ['node', 'js/src/pro/test/test.js', ...args] },
135
- { language: 'Python 3', key: '--python', exec: ['python3', 'python/ccxt/pro/test/test_async.py', ...args] },
136
- { language: 'Python 3 Async', key: '--python-async', exec: ['python3', 'python/ccxt/pro/test/test_async.py', ...args] },
137
- { language: 'PHP', key: '--php', exec: ['php', '-f', 'php/pro/test/test.php', ...args] }
138
- ]
139
- , allTests = allTestsWithoutTs.concat([
140
- { language: 'TypeScript', key: '--ts', exec: ['node', '--loader', 'ts-node/esm', 'ts/src/pro/test/test.ts', ...args] },
141
- ])
142
- , selectedTests = allTests.filter (t => keys[t.key])
143
- , scheduledTests = selectedTests.length ? selectedTests : allTestsWithoutTs
144
- , completeTests = await sequentialMap (scheduledTests, async test => Object.assign (test, await exec (...test.exec)))
145
- , failed = completeTests.find (test => test.failed)
146
- , stalled = completeTests.find (test => test.stalled)
147
- , hasWarnings = completeTests.find (test => test.hasWarnings)
148
- , warnings = completeTests.reduce ((total, { warnings }) => total.concat (warnings), [])
149
-
150
- // print interactive log output
151
-
152
- numExchangesTested++
153
-
154
- const percentsDone = ((numExchangesTested / exchanges.length) * 100).toFixed (0) + '%'
155
-
156
- let result
157
- if (stalled) {
158
- // a timeout is always also a fail
159
- result = 'TIMEOUT'.red
160
- } else if (failed) {
161
- result = 'FAILED'.red
162
- } else if (hasWarnings) {
163
- result = warnings.join (' ').yellow
164
- } else {
165
- result = 'OK'.green
166
- }
167
-
168
- const date = (new Date()).toISOString ()
169
- log.bright (date, ('[' + percentsDone + ']').dim, 'Testing WS', exchange.cyan, result)
170
-
171
- // return collected data to main loop
172
-
173
- return {
174
-
175
- exchange,
176
- failed,
177
- stalled,
178
- hasWarnings,
179
- explain () {
180
- for (const { language, failed, stalled, output, hasWarnings } of completeTests) {
181
- if (failed || hasWarnings) {
182
-
183
- if (!failed && output.indexOf('[Skipped]') >= 0)
184
- continue;
185
-
186
- if (failed || stalled) { log.bright ((stalled ? '\nTIMEOUT' : '\nFAILED').bgBrightRed.white, exchange.red, '(' + language + '):\n') }
187
- else { log.bright ('\nWARN'.yellow.inverse, exchange.yellow, '(' + language + '):\n') }
188
-
189
- log.indent (1) (output)
190
- }
191
- }
192
- }
193
- }
194
- }
195
-
196
- // ----------------------------------------------------------------------------
197
-
198
- function TaskPool (maxConcurrency) {
199
-
200
- const pending = []
201
- , queue = []
202
-
203
- let numActive = 0
204
-
205
- return {
206
-
207
- pending,
208
-
209
- run (task) {
210
-
211
- if (numActive >= maxConcurrency) { // queue task
212
-
213
- return new Promise (resolve => queue.push (() => this.run (task).then (resolve)))
214
-
215
- } else { // execute task
216
-
217
- let p = task ().then (x => {
218
- numActive--
219
- return (queue.length && (numActive < maxConcurrency))
220
- ? queue.shift () ().then (() => x)
221
- : x
222
- })
223
- numActive++
224
- pending.push (p)
225
- return p
226
- }
227
- }
228
- }
229
- }
230
-
231
- // ----------------------------------------------------------------------------
232
-
233
- async function testAllExchanges () {
234
-
235
- const taskPool = TaskPool (maxConcurrency)
236
- const results = []
237
-
238
- for (const exchange of exchanges) {
239
- taskPool.run (() => testExchange (exchange).then (x => results.push (x)))
240
- }
241
-
242
- await Promise.all (taskPool.pending)
243
-
244
- return results
245
- }
246
-
247
- // ----------------------------------------------------------------------------
248
-
249
- (async function () {
250
-
251
- log.bright.magenta.noPretty ('Testing'.white, Object.assign (
252
- { exchanges, symbol, keys },
253
- maxConcurrency >= Number.MAX_VALUE ? {} : { maxConcurrency }))
254
-
255
- const tested = await testAllExchanges ()
256
- , warnings = tested.filter (t => !t.failed && t.hasWarnings)
257
- , failed = tested.filter (t => t.failed && !t.stalled)
258
- , stalled = tested.filter (t => t.stalled)
259
- , succeeded = tested.filter (t => !t.failed && !t.hasWarnings)
260
-
261
- log.newline ()
262
-
263
- warnings.forEach (t => t.explain ())
264
- failed.forEach (t => t.explain ())
265
-
266
- log.newline ()
267
-
268
- if (failed.length) { log.noPretty.bright.red ('FAIL'.bgBrightRed.white, failed.map (t => t.exchange)) }
269
- if (stalled.length) { log.noPretty.bright.red ('TIMEOUT'.bgBrightRed.white, stalled.map (t => t.exchange)) }
270
- if (warnings.length) { log.noPretty.bright.yellow ('WARN'.inverse, warnings.map (t => t.exchange)) }
271
-
272
- log.newline ()
273
-
274
- log.bright ('All done,', [failed.length && (failed.length + ' failed') .red,
275
- stalled.length && (stalled.length + ' timed out').red,
276
- succeeded.length && (succeeded.length + ' succeeded').green,
277
- warnings.length && (warnings.length + ' warnings') .yellow].filter (s => s).join (', '))
278
-
279
- if (failed.length) {
280
-
281
- await sleep (10000) // to fight TravisCI log truncation issue, see https://github.com/travis-ci/travis-ci/issues/8189
282
- process.exit (1)
283
-
284
- } else {
285
- process.exit (0)
286
- }
287
-
288
- }) ();
289
-
290
- // ----------------------------------------------------------------------------