mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
116 lines
3.7 KiB
TypeScript
116 lines
3.7 KiB
TypeScript
import { SystemError, dns } from "bun";
|
|
import { describe, expect, test } from "bun:test";
|
|
import { isWindows, withoutAggressiveGC } from "harness";
|
|
import { isIP, isIPv4, isIPv6 } from "node:net";
|
|
|
|
const backends = ["system", "libc", "c-ares"];
|
|
const validHostnames = ["localhost", "example.com"];
|
|
const invalidHostnames = ["adsfa.asdfasdf.asdf.com"]; // known invalid
|
|
const malformedHostnames = [" ", ".", " .", "localhost:80", "this is not a hostname"];
|
|
|
|
describe("dns", () => {
|
|
describe.each(backends)("lookup() [backend: %s]", backend => {
|
|
describe.each(validHostnames)("%s", hostname => {
|
|
test.each([
|
|
{
|
|
options: { backend },
|
|
address: isIP,
|
|
},
|
|
{
|
|
options: { backend, family: 4 },
|
|
address: isIPv4,
|
|
family: 4,
|
|
},
|
|
{
|
|
options: { backend, family: "IPv4" },
|
|
address: isIPv4,
|
|
family: 4,
|
|
},
|
|
{
|
|
options: { backend, family: 6 },
|
|
address: isIPv6,
|
|
family: 6,
|
|
},
|
|
{
|
|
options: { backend, family: "IPv6" },
|
|
address: isIPv6,
|
|
family: 6,
|
|
},
|
|
{
|
|
options: { backend, family: 0 },
|
|
address: isIP,
|
|
},
|
|
{
|
|
options: { backend, family: "any" },
|
|
address: isIP,
|
|
},
|
|
])("%j", async ({ options, address: expectedAddress, family: expectedFamily }) => {
|
|
// this behavior matchs nodejs
|
|
const expect_to_fail =
|
|
isWindows &&
|
|
backend !== "c-ares" &&
|
|
(options.family === "IPv6" || options.family === 6) &&
|
|
hostname !== "localhost";
|
|
if (expect_to_fail) {
|
|
try {
|
|
// @ts-expect-error
|
|
await dns.lookup(hostname, options);
|
|
expect.unreachable();
|
|
} catch (err: unknown) {
|
|
expect(err).toBeDefined();
|
|
expect((err as SystemError).code).toBe("DNS_ENOTFOUND");
|
|
}
|
|
return;
|
|
}
|
|
// @ts-expect-error
|
|
const result = await dns.lookup(hostname, options);
|
|
expect(result).toBeArray();
|
|
expect(result.length).toBeGreaterThan(0);
|
|
withoutAggressiveGC(() => {
|
|
for (const { family, address, ttl } of result) {
|
|
expect(address).toBeString();
|
|
expect(expectedAddress(address)).toBeTruthy();
|
|
expect(family).toBeInteger();
|
|
if (expectedFamily !== undefined) {
|
|
expect(family).toBe(expectedFamily);
|
|
}
|
|
expect(ttl).toBeInteger();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
test.each(validHostnames)("%s [parallel x 10]", async hostname => {
|
|
const results = await Promise.all(
|
|
// @ts-expect-error
|
|
Array.from({ length: 10 }, () => dns.lookup(hostname, { backend })),
|
|
);
|
|
const answers = results.flat();
|
|
expect(answers).toBeArray();
|
|
expect(answers.length).toBeGreaterThanOrEqual(10);
|
|
withoutAggressiveGC(() => {
|
|
for (const { family, address, ttl } of answers) {
|
|
expect(address).toBeString();
|
|
expect(isIP(address)).toBeTruthy();
|
|
expect(family).toBeInteger();
|
|
expect(ttl).toBeInteger();
|
|
}
|
|
});
|
|
});
|
|
test.each(invalidHostnames)("%s", hostname => {
|
|
// @ts-expect-error
|
|
expect(dns.lookup(hostname, { backend })).rejects.toMatchObject({
|
|
code: "DNS_ENOTFOUND",
|
|
name: "DNSException",
|
|
});
|
|
});
|
|
|
|
test.each(malformedHostnames)("'%s'", hostname => {
|
|
// @ts-expect-error
|
|
expect(dns.lookup(hostname, { backend })).rejects.toMatchObject({
|
|
code: expect.stringMatching(/^DNS_ENOTFOUND|DNS_ESERVFAIL|DNS_ENOTIMP$/),
|
|
name: "DNSException",
|
|
});
|
|
});
|
|
});
|
|
});
|