gristlabs_grist-core/test/server/lib/ProxyAgent.ts
Paul Fitzpatrick aa69652a33
use fresher node and debian version (#1255)
This moves to node 22 and debian bookworm, since the versions we've been building and testing with are getting old.

There is some old material kept around for (speaks very quietly) Python 2 (looks around hoping no-one heard) which we continue to support for some long-time users but really really should drop soon.

The changes for the node upgrade were all test related. I did them in a way that shouldn't impair running on older versions of node, and did spot checks for this. This is to give some breathing room for upgrading Grist Lab's grist-saas as follow up work.
2024-10-10 16:59:03 -04:00

102 lines
3.9 KiB
TypeScript

import {proxyAgent} from "app/server/lib/ProxyAgent";
import {getAvailablePort} from "app/server/lib/serverUtils";
import {assert} from "chai";
import {HttpsProxyAgent} from "https-proxy-agent";
import {HttpProxyAgent} from "http-proxy-agent";
import fetch from 'node-fetch';
import {TestProxyServer} from 'test/server/lib/helpers/TestProxyServer';
import {serveSomething, Serving} from 'test/server/customUtil';
import {assertMatchArray, captureLog, EnvironmentSnapshot} from "test/server/testUtils";
describe("ProxyAgent", function () {
let oldEnv: EnvironmentSnapshot;
before(() => {
oldEnv = new EnvironmentSnapshot();
});
after(() => {
oldEnv.restore();
});
it("should be undefined if no proxy is configured", async function () {
delete process.env.GRIST_HTTPS_PROXY;
const httpProxy = proxyAgent(new URL("http://localhost:3000"));
const httpsProxy = proxyAgent(new URL("https://localhost:3000"));
assert.equal(httpProxy, undefined);
assert.equal(httpsProxy, undefined);
});
it("should be https proxy if proxy is configured and address is https", async function () {
process.env.GRIST_HTTPS_PROXY = "https://localhost:9000";
const httpsProxy = proxyAgent(new URL("https://localhost:3000"));
assert.instanceOf(httpsProxy, HttpsProxyAgent);
});
it("should be https proxy if proxy is configured and address is https", async function () {
process.env.GRIST_HTTPS_PROXY = "https://localhost:9000";
const httpsProxy = proxyAgent(new URL("http://localhost:3000"));
assert.instanceOf(httpsProxy, HttpProxyAgent);
});
describe('proxy error handling', async function() {
// Handling requests
let serving: Serving;
// Proxy server emulation to test possible behaviours of real life server
let testProxyServer: TestProxyServer;
// Simple fetch using a proxy.
function testFetch(relativePath: string) {
const url = serving.url + relativePath;
return fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
agent: proxyAgent(new URL(url)),
});
}
beforeEach(async function () {
// Set up a server and a proxy.
const port = await getAvailablePort(22340);
testProxyServer = await TestProxyServer.Prepare(port);
serving = await serveSomething(app => {
app.post('/200', (_, res) => { res.sendStatus(200); res.end(); });
app.post('/404', (_, res) => { res.sendStatus(404); res.end(); });
});
process.env.GRIST_HTTPS_PROXY = `http://localhost:${port}`;
});
afterEach(async function() {
await serving.shutdown();
await testProxyServer.dispose().catch(() => {});
});
it("should not report error when proxy is working", async function() {
// Normally fetch through proxy works and produces no errors, even for failing status.
const logMessages1 = await captureLog('warn', async () => {
assert.equal((await testFetch('/200')).status, 200);
assert.equal((await testFetch('/404')).status, 404);
});
assert.deepEqual(logMessages1, []);
});
it("should report error when proxy fails", async function() {
// if the proxy isn't listening, fetches produces error messages.
await testProxyServer.dispose();
// Error message depends a little on node version.
const logMessages2 = await captureLog('warn', async () => {
await assert.isRejected(testFetch('/200'), /(request.*failed)|(ECONNREFUSED)/);
await assert.isRejected(testFetch('/404'), /(request.*failed)|(ECONNREFUSED)/);
});
// We rely on "ProxyAgent error" message to detect issues with the proxy server.
// Error message depends a little on node version.
assertMatchArray(logMessages2, [
/warn: ProxyAgent error.*((request.*failed)|(ECONNREFUSED)|(AggregateError))/,
/warn: ProxyAgent error.*((request.*failed)|(ECONNREFUSED)|(AggregateError))/,
]);
});
});
});