Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WS & REST proxies & tests #22268

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions build/csharpTranspiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,9 @@ class NewTranspiler {
const flatResult = await this.webworkerTranspile (paths, this.getTranspilerConfig());
flatResult.forEach((file, idx) => {
let contentIndentend = file.content.split('\n').map(line => line ? ' ' + line : line).join('\n');
if (contentIndentend.includes('SKIP_TRANSPILER_CSHARP')) {
return;
}

let regexes = [
[ /object exchange(?=[,)])/g, 'Exchange exchange' ],
Expand Down
1 change: 1 addition & 0 deletions cs/tests/BaseTest.Bridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public partial class BaseTest
// bridges to make auxiliary methods available in tests
//

public static object callDynamically(object obj, object methodName, object[] args = null) => Exchange.callDynamically(obj, methodName, args);
public static object mod(object a, object b) => Exchange.mod(a, b);

public string decimalToPrecision(object a, object b, object c = null, object d = null, object e = null) => Exchange.DecimalToPrecision(a, b, c, d, e);
Expand Down
14 changes: 8 additions & 6 deletions examples/ts/proxy-usage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ async function example_socksProxy () {

async function example_webSockets () {
const myEx = new ccxt.pro.kucoin ();
myEx.httpProxy = 'http://5.75.153.75:8002'; // even though you are using WebSockets, you might also need to set up proxy for the exchange's REST requests
myEx.wsProxy = 'http://5.75.153.75:8002'; // "wsProxy" or "wssProxy" or "wsSocksProxy" (depending on your proxy protocol)
myEx.httpsProxy = 'http://5.75.153.75:8002'; // httpProxy or httpsProxy for REST requests ( even though you are using WebSockets, you might also need to set up proxy for the exchange's REST requests)
await myEx.loadMarkets ();
myEx.wssProxy = 'http://5.75.153.75:8002'; // "wsProxy" or "wssProxy" or "wsSocksProxy" (depending on your proxy protocol)
while (true) {
const ticker = await myEx.watchTicker ('BTC/USDT');
console.log (ticker);
break;
}
// ### to ensure that ws-proxy works correctly and how remote test server sees your IP, use below and check output ###
myEx.verbose = true;
await myEx.watch ('ws://5.75.153.75:9876', 'test', 'test');
}


await example_proxyUrl ();
// await example_httpProxy ();
// await example_socksProxy ();
// await example_webSockets ();
// test any from: example_proxyUrl(), example_httpProxy(), example_socksProxy(), example_webSockets()
await example_webSockets ();
49 changes: 49 additions & 0 deletions ts/src/pro/test/Exchange/test.proxies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import assert from 'assert';
import { Exchange } from "../../../../ccxt";
import testSharedMethods from '../../../test/Exchange/base/test.sharedMethods.js';

// SKIP_TRANSPILER_CSHARP

async function testWsProxies (exchange: Exchange, skippedProperties: object, language: string) {
// todo: other proxies, i.e. 'socksWsProxy' etc
if (exchange.inArray (language, [ 'js', 'ts' ])) {
const dynamicMethodName = 'loadHttpProxyAgent'; // c# trick
await exchange[dynamicMethodName] ();
} else if (exchange.inArray (language, [ 'cs', 'php' ])) {
// skip them for now
return;
}
const [ proxyUrl, httpProxy, httpsProxy, socksProxy ] = testSharedMethods.removeProxyOptions (exchange, skippedProperties);
await testWsProxy (exchange, skippedProperties);
// reset the instance property
testSharedMethods.setProxyOptions (exchange, skippedProperties, proxyUrl, httpProxy, httpsProxy, socksProxy);
// todo: below like in "REST" proxy tests
// await testProxyForExceptions (exchange, skippedProperties);
}


async function testWsProxy (exchange: Exchange, skippedProperties: object) {
const method = 'wsProxy';
const testVpsServerIp = '5.75.153.75';
exchange.httpProxy = 'http://' + testVpsServerIp + ':8002'; // "httpProxy" or "httpsProxy" (depending on your proxy protocol)
exchange.wsProxy = 'http://' + testVpsServerIp + ':8002'; // "wsProxy" or "wssProxy" (depending on your proxy protocol)
exchange.handleMessage = ws_helper_callback; // todo for PHP: specifically this custom example does not work in PHP to retrieve the target message, however proxies do work in PHP for websockets independently from this example
const demoServerUrl = 'ws://' + testVpsServerIp + ':9876';
return await exchange.watch (demoServerUrl, 'ws_proxy_test', 'ws_proxy_test');
}


function ws_helper_callback (client, message) {
const method = 'wsProxy';
const testVpsServerIp = '5.75.153.75';
// message like: { msg: "hi from test server", your_ip: "::ffff:5.75.153.75" }
if ('your_ip' in message) {
let ipString = message['your_ip'];
ipString = ipString.replace ('::ffff:', '');
assert (ipString === testVpsServerIp, method + ' test failed. Returned response is ' + ipString + ' while it should be "' + testVpsServerIp + '"');
client.resolve (null, 'ws_proxy_test');
}
}


export default testWsProxies;
5 changes: 2 additions & 3 deletions ts/src/test/Exchange/test.proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import assert from 'assert';
import { Exchange } from "../../../ccxt";
import testSharedMethods from './base/test.sharedMethods.js';

async function testProxies (exchange: Exchange, skippedProperties: object) {
async function testProxies (exchange: Exchange, skippedProperties: object, language: string) {
// todo: other proxies, i.e. 'httpsProxy', 'socksProxy'
await testProxyUrl (exchange, skippedProperties);
await testHttpProxy (exchange, skippedProperties);
// 'httpsProxy', 'socksProxy'
await testProxyForExceptions (exchange, skippedProperties);
}

Expand Down Expand Up @@ -37,7 +37,6 @@ async function testHttpProxy (exchange: Exchange, skippedProperties: object) {
testSharedMethods.setProxyOptions (exchange, skippedProperties, proxyUrl, httpProxy, httpsProxy, socksProxy);
}


// with the below method we test out all variations of possible proxy options, so at least 2 of them should be set together, and such cases must throw exception
async function testProxyForExceptions (exchange: Exchange, skippedProperties: object) {
const method = 'testProxyForExceptions';
Expand Down
14 changes: 7 additions & 7 deletions ts/src/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -981,16 +981,16 @@ export default class testMainClass extends baseMainTestClass {
let exception = undefined;
for (let j = 0; j < maxRetries; j++) {
try {
await this.testMethod (proxyTestName, exchange, [], true);
await this.testMethod (proxyTestName, exchange, [ this.ext ], true);
break; // if successfull, then break
} catch (e) {
exception = e;
}
}
// if exception was set, then throw it
if (exception) {
const errorMessage = '[TEST_FAILURE] Failed ' + proxyTestName + ' : ' + exceptionMessage (exception);
throw new ExchangeError (errorMessage.toString ()); // toString is a c# requirement for now
const errorMessage = '[TEST_WARNING] Failed ' + proxyTestName + ' : ' + exceptionMessage (exception);
dump (errorMessage.toString ()); // toString is a c# requirement for now
}
}

Expand All @@ -1009,10 +1009,10 @@ export default class testMainClass extends baseMainTestClass {
await close (exchange);
return;
}
// if (exchange.id === 'binance') {
// // we test proxies functionality just for one random exchange on each build, because proxy functionality is not exchange-specific, instead it's all done from base methods, so just one working sample would mean it works for all ccxt exchanges
// // await this.testProxies (exchange);
// }
if (exchange.id === 'kucoin') {
// we test proxies functionality just for one random exchange on each build, because proxy functionality is not exchange-specific, instead it's all done from base methods, so just one working sample would mean it works for all ccxt exchanges
await this.testProxies (exchange);
}
await this.testExchange (exchange, symbol);
await close (exchange);
} catch (e) {
Expand Down