Skip to content

Commit

Permalink
Merge pull request #464 from AikidoSec/undici-v7
Browse files Browse the repository at this point in the history
Test all supported undici versions: v4, v5, v6 and v7
  • Loading branch information
willem-delbare authored Nov 28, 2024
2 parents d643665 + a40d851 commit bf661cc
Show file tree
Hide file tree
Showing 16 changed files with 525 additions and 397 deletions.
13 changes: 11 additions & 2 deletions library/agent/hooks/Package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ type PackageName = string;
export class Package {
private versions: VersionedPackage[] = [];

constructor(private readonly packageName: PackageName) {
if (!this.packageName) {
constructor(private packageName: PackageName) {
this.assertValidPackageName(this.packageName);
}

private assertValidPackageName(name: string) {
if (!name) {
throw new Error("Package name is required");
}
}
Expand All @@ -22,6 +26,11 @@ export class Package {
return this.packageName;
}

setName(name: string) {
this.assertValidPackageName(name);
this.packageName = name;
}

withVersion(range: string): VersionedPackage {
const pkg = new VersionedPackage(range);
this.versions.push(pkg);
Expand Down
26 changes: 26 additions & 0 deletions library/agent/hooks/wrapRequire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,29 @@ function executeInterceptors(
export function getOriginalRequire() {
return originalRequire;
}

// In order to support multiple versions of the same package, we need to rewrite the package name
// e.g. In our sources and sinks, we use the real package name `hooks.addPackage("undici")`
// but in the tests we want to `require("undici-v6")` instead of `require("undici")`
export function __internalRewritePackageName(
packageName: string,
aliasForTesting: string
) {
if (!isRequireWrapped) {
throw new Error(
"Start the agent before calling __internalRewritePackageName(..)"
);
}

Check warning on line 320 in library/agent/hooks/wrapRequire.ts

View check run for this annotation

Codecov / codecov/patch

library/agent/hooks/wrapRequire.ts#L317-L320

Added lines #L317 - L320 were not covered by tests

if (packages.length === 0) {
throw new Error("No packages to patch");
}

Check warning on line 324 in library/agent/hooks/wrapRequire.ts

View check run for this annotation

Codecov / codecov/patch

library/agent/hooks/wrapRequire.ts#L323-L324

Added lines #L323 - L324 were not covered by tests

const pkg = packages.find((pkg) => pkg.getName() === packageName);

if (!pkg) {
throw new Error(`Could not find package ${packageName}`);
}

Check warning on line 330 in library/agent/hooks/wrapRequire.ts

View check run for this annotation

Codecov / codecov/patch

library/agent/hooks/wrapRequire.ts#L329-L330

Added lines #L329 - L330 were not covered by tests

pkg.setName(aliasForTesting);
}
35 changes: 35 additions & 0 deletions library/helpers/startTestAgent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ReportingAPI } from "../agent/api/ReportingAPI";
import type { Token } from "../agent/api/Token";
import { __internalRewritePackageName } from "../agent/hooks/wrapRequire";
import type { Logger } from "../agent/logger/Logger";
import { Wrapper } from "../agent/Wrapper";
import { createTestAgent } from "./createTestAgent";

type PackageName = string;
type AliasToRequire = string;

/**
* Start a test agent for testing purposes
*/
export function startTestAgent(opts: {
block?: boolean;
logger?: Logger;
api?: ReportingAPI;
token?: Token;
serverless?: string;
wrappers: Wrapper[];
rewrite: Record<PackageName, AliasToRequire>;
}) {
const agent = createTestAgent(opts);
agent.start(opts.wrappers);

// In order to support multiple versions of the same package, we need to rewrite the package name
// e.g. In our sources and sinks, we use the real package name `hooks.addPackage("undici")`
// but in the tests we want to `require("undici-v6")` instead of `require("undici")`
// The `__internalRewritePackageName` function allows us to do this
Object.keys(opts.rewrite).forEach((packageName) => {
__internalRewritePackageName(packageName, opts.rewrite[packageName]);
});

return agent;
}
63 changes: 54 additions & 9 deletions library/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@
"tap": "^18.6.1",
"type-fest": "^4.24.0",
"typescript": "^5.3.3",
"undici": "^6.12.0",
"xml-js": "^1.6.11",
"xml2js": "^0.6.2"
"xml2js": "^0.6.2",
"undici-v4": "npm:undici@^4.0.0",
"undici-v5": "npm:undici@^5.0.0",
"undici-v6": "npm:undici@^6.0.0",
"undici-v7": "npm:undici@^7.0.0"
},
"scripts": {
"test": "node ../scripts/run-tap.js",
Expand Down
9 changes: 5 additions & 4 deletions library/sinks/Undici.custom.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import * as dns from "dns";
import * as t from "tap";
import { Token } from "../agent/api/Token";
import { Context, runWithContext } from "../agent/Context";
import { startTestAgent } from "../helpers/startTestAgent";
import { wrap } from "../helpers/wrap";
import { getMajorNodeVersion } from "../helpers/getNodeVersion";
import { Undici } from "./Undici";
import { createTestAgent } from "../helpers/createTestAgent";

function createContext(): Context {
return {
Expand Down Expand Up @@ -42,13 +42,14 @@ t.test(
getMajorNodeVersion() <= 16 ? "ReadableStream is not available" : false,
},
async (t) => {
const agent = createTestAgent({
startTestAgent({
token: new Token("123"),
wrappers: [new Undici()],
rewrite: { undici: "undici-v6" },
});
agent.start([new Undici()]);

const { request, Dispatcher, setGlobalDispatcher, getGlobalDispatcher } =
require("undici") as typeof import("undici");
require("undici-v6") as typeof import("undici-v6");

// See https://www.npmjs.com/package/@n8n_io/license-sdk
// They set a custom dispatcher to proxy certain requests
Expand Down
15 changes: 6 additions & 9 deletions library/sinks/Undici.localhost.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
/* eslint-disable prefer-rest-params */
import * as t from "tap";
import { Agent } from "../agent/Agent";
import { createServer, Server } from "http";
import { ReportingAPIForTesting } from "../agent/api/ReportingAPIForTesting";
import { Token } from "../agent/api/Token";
import { Context, runWithContext } from "../agent/Context";
import { LoggerNoop } from "../agent/logger/LoggerNoop";
import { createTestAgent } from "../helpers/createTestAgent";
import { getMajorNodeVersion } from "../helpers/getNodeVersion";
import { startTestAgent } from "../helpers/startTestAgent";
import { Undici } from "./Undici";

function createContext({
Expand Down Expand Up @@ -53,12 +50,12 @@ function createContext({
};
}

const agent = createTestAgent({
startTestAgent({
token: new Token("123"),
wrappers: [new Undici()],
rewrite: { undici: "undici-v6" },
});

agent.start([new Undici()]);

const port = 1346;
const serverUrl = `http://localhost:${port}`;
const hostHeader = `localhost:${port}`;
Expand All @@ -83,7 +80,7 @@ t.test(
getMajorNodeVersion() <= 16 ? "ReadableStream is not available" : false,
},
async (t) => {
const { request } = require("undici");
const { request } = require("undici-v6") as typeof import("undici-v6");

await runWithContext(
createContext({
Expand All @@ -108,7 +105,7 @@ t.test(
getMajorNodeVersion() <= 16 ? "ReadableStream is not available" : false,
},
async (t) => {
const { request } = require("undici");
const { request } = require("undici-v6") as typeof import("undici-v6");

const error = await t.rejects(async () => {
await runWithContext(
Expand Down
Loading

0 comments on commit bf661cc

Please sign in to comment.