mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-03-13 12:54:47 +00:00
The tests now cover:
- All DNS record types - Various DNS providers - Edge cases and error conditions - Response format validation - Performance metrics - Security validations
This commit is contained in:
parent
54cbf5794d
commit
7668d3bd3e
1 changed files with 367 additions and 22 deletions
|
@ -28,6 +28,201 @@ test("DNSMonitor - Timestamp Test", async (t) => {
|
||||||
assert.strictEqual(monitor.timestamp.valueOf(), now.valueOf(), "Should set timestamp correctly");
|
assert.strictEqual(monitor.timestamp.valueOf(), now.valueOf(), "Should set timestamp correctly");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("DNS Monitor - Hostname Validation Test", async (t) => {
|
||||||
|
const monitor = new DnsMonitorType();
|
||||||
|
const testCases = [
|
||||||
|
{
|
||||||
|
hostname: "example.com",
|
||||||
|
valid: true,
|
||||||
|
description: "Simple valid domain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "sub1.sub2.example.com",
|
||||||
|
valid: true,
|
||||||
|
description: "Multiple subdomain levels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "xn--bcher-kva.example", // bücher.example
|
||||||
|
valid: true,
|
||||||
|
description: "Punycode domain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "example.com/path",
|
||||||
|
valid: false,
|
||||||
|
description: "Domain with path"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "http://example.com",
|
||||||
|
valid: false,
|
||||||
|
description: "Domain with protocol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "example.com:80",
|
||||||
|
valid: false,
|
||||||
|
description: "Domain with port"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "example.com?query=1",
|
||||||
|
valid: false,
|
||||||
|
description: "Domain with query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "example.com#fragment",
|
||||||
|
valid: false,
|
||||||
|
description: "Domain with fragment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "javascript:alert(1)",
|
||||||
|
valid: false,
|
||||||
|
description: "XSS attempt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "data:text/plain;base64,SGVsbG8=",
|
||||||
|
valid: false,
|
||||||
|
description: "Data URL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "file:///etc/passwd",
|
||||||
|
valid: false,
|
||||||
|
description: "File protocol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "localhost",
|
||||||
|
valid: true,
|
||||||
|
description: "Localhost"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "-invalid.com",
|
||||||
|
valid: false,
|
||||||
|
description: "Invalid starting character"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "example-.com",
|
||||||
|
valid: false,
|
||||||
|
description: "Invalid ending character"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
hostname: "exa mple.com",
|
||||||
|
valid: false,
|
||||||
|
description: "Contains spaces"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const testCase of testCases) {
|
||||||
|
const isValid = monitor.validateHostname(testCase.hostname);
|
||||||
|
assert.strictEqual(isValid, testCase.valid, `${testCase.description}: ${testCase.hostname}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("DNS Monitor - Check Method Test", async (t) => {
|
||||||
|
const monitor = new DnsMonitorType();
|
||||||
|
const testCases = [
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
hostname: "example.com",
|
||||||
|
dns_resolve_type: "A",
|
||||||
|
dns_resolve_server: "8.8.8.8",
|
||||||
|
port: 53
|
||||||
|
},
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "Valid A record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
hostname: "invalid.hostname.thisdoesnotexist",
|
||||||
|
dns_resolve_type: "A",
|
||||||
|
dns_resolve_server: "8.8.8.8",
|
||||||
|
port: 53
|
||||||
|
},
|
||||||
|
expectSuccess: false,
|
||||||
|
description: "Non-existent domain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
hostname: "example.com",
|
||||||
|
dns_resolve_type: "MX",
|
||||||
|
dns_resolve_server: "8.8.8.8",
|
||||||
|
port: 53
|
||||||
|
},
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "MX record lookup"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const testCase of testCases) {
|
||||||
|
const heartbeat = {};
|
||||||
|
try {
|
||||||
|
await monitor.check(testCase.config, heartbeat);
|
||||||
|
if (!testCase.expectSuccess) {
|
||||||
|
assert.fail(`Expected failure for ${testCase.description}`);
|
||||||
|
}
|
||||||
|
if (testCase.expectSuccess) {
|
||||||
|
assert.ok(heartbeat.status === UP || heartbeat.status === DOWN,
|
||||||
|
`Should set heartbeat status for ${testCase.description}`);
|
||||||
|
assert.ok(heartbeat.msg,
|
||||||
|
`Should set heartbeat message for ${testCase.description}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (testCase.expectSuccess) {
|
||||||
|
assert.fail(`Expected success for ${testCase.description}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("DNS Monitor - Condition Evaluation Test", async (t) => {
|
||||||
|
const monitor = new DnsMonitorType();
|
||||||
|
const testCases = [
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
hostname: "example.com",
|
||||||
|
dns_resolve_type: "A",
|
||||||
|
dns_resolve_server: "8.8.8.8",
|
||||||
|
port: 53,
|
||||||
|
condition_expression_group: JSON.stringify({
|
||||||
|
operator: "AND",
|
||||||
|
expressions: [{
|
||||||
|
variable: "record",
|
||||||
|
operator: "contains",
|
||||||
|
value: "93.184.216"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
expectUp: true,
|
||||||
|
description: "IP address condition"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
hostname: "example.com",
|
||||||
|
dns_resolve_type: "MX",
|
||||||
|
dns_resolve_server: "8.8.8.8",
|
||||||
|
port: 53,
|
||||||
|
condition_expression_group: JSON.stringify({
|
||||||
|
operator: "AND",
|
||||||
|
expressions: [{
|
||||||
|
variable: "record",
|
||||||
|
operator: "contains",
|
||||||
|
value: "aspmx"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
expectUp: true,
|
||||||
|
description: "MX record condition"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const testCase of testCases) {
|
||||||
|
const heartbeat = {};
|
||||||
|
try {
|
||||||
|
await monitor.check(testCase.config, heartbeat);
|
||||||
|
assert.strictEqual(heartbeat.status, testCase.expectUp ? UP : DOWN,
|
||||||
|
`${testCase.description}: Expected status ${testCase.expectUp ? "UP" : "DOWN"}`);
|
||||||
|
} catch (error) {
|
||||||
|
assert.fail(`Test failed for ${testCase.description}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("DNS Monitor - Basic A Record Test", async (t) => {
|
test("DNS Monitor - Basic A Record Test", async (t) => {
|
||||||
const monitor = {
|
const monitor = {
|
||||||
hostname: "test1.example.com",
|
hostname: "test1.example.com",
|
||||||
|
@ -83,18 +278,10 @@ test("DNS Monitor - URL Validation Test", async (t) => {
|
||||||
maxretries: 1
|
maxretries: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
|
||||||
const dnsMonitor = new DnsMonitorType(monitor);
|
const dnsMonitor = new DnsMonitorType(monitor);
|
||||||
if (!testCase.valid) {
|
const isValid = dnsMonitor.validateHostname(testCase.hostname);
|
||||||
assert.fail(`Should not create monitor for ${testCase.description}`);
|
assert.strictEqual(isValid, testCase.valid,
|
||||||
}
|
`${testCase.description}: ${testCase.hostname} should be ${testCase.valid ? "valid" : "invalid"}`);
|
||||||
assert.ok(dnsMonitor, `Should create monitor for ${testCase.description}`);
|
|
||||||
} catch (error) {
|
|
||||||
if (testCase.valid) {
|
|
||||||
assert.fail(`Should create monitor for ${testCase.description}`);
|
|
||||||
}
|
|
||||||
assert.ok(error, `Should throw error for ${testCase.description}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -102,47 +289,205 @@ test("DNS Monitor - Resolver Test", async (t) => {
|
||||||
const testCases = [
|
const testCases = [
|
||||||
{
|
{
|
||||||
server: "8.8.8.8",
|
server: "8.8.8.8",
|
||||||
|
port: 53,
|
||||||
valid: true,
|
valid: true,
|
||||||
|
expectUp: true,
|
||||||
description: "Google DNS"
|
description: "Google DNS"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
server: "1.1.1.1",
|
server: "1.1.1.1",
|
||||||
|
port: 53,
|
||||||
valid: true,
|
valid: true,
|
||||||
|
expectUp: true,
|
||||||
description: "Cloudflare DNS"
|
description: "Cloudflare DNS"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
server: "9.9.9.9",
|
||||||
|
port: 53,
|
||||||
|
valid: true,
|
||||||
|
expectUp: true,
|
||||||
|
description: "Quad9 DNS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
server: "208.67.222.222",
|
||||||
|
port: 53,
|
||||||
|
valid: true,
|
||||||
|
expectUp: true,
|
||||||
|
description: "OpenDNS"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
server: "malicious.com",
|
server: "malicious.com",
|
||||||
|
port: 53,
|
||||||
valid: false,
|
valid: false,
|
||||||
|
expectUp: false,
|
||||||
description: "Invalid DNS server hostname"
|
description: "Invalid DNS server hostname"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
server: "javascript:alert(1)",
|
server: "javascript:alert(1)",
|
||||||
|
port: 53,
|
||||||
valid: false,
|
valid: false,
|
||||||
|
expectUp: false,
|
||||||
description: "Invalid protocol"
|
description: "Invalid protocol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
server: "8.8.8.8",
|
||||||
|
port: 5353,
|
||||||
|
valid: true,
|
||||||
|
expectUp: false,
|
||||||
|
description: "Invalid port"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
server: "192.168.0.1",
|
||||||
|
port: 53,
|
||||||
|
valid: true,
|
||||||
|
expectUp: false,
|
||||||
|
description: "Private IP address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
server: "256.256.256.256",
|
||||||
|
port: 53,
|
||||||
|
valid: false,
|
||||||
|
expectUp: false,
|
||||||
|
description: "Invalid IP address"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const monitor = new DnsMonitorType();
|
||||||
|
|
||||||
for (const testCase of testCases) {
|
for (const testCase of testCases) {
|
||||||
const monitor = {
|
const config = {
|
||||||
hostname: "test1.example.com",
|
hostname: "example.com",
|
||||||
dns_resolve_server: testCase.server,
|
dns_resolve_server: testCase.server,
|
||||||
port: 53,
|
port: testCase.port,
|
||||||
dns_resolve_type: "A",
|
dns_resolve_type: "A",
|
||||||
|
dns_resolve_server_port: testCase.port,
|
||||||
|
maxretries: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test hostname validation first
|
||||||
|
const isValidHostname = monitor.validateHostname(config.hostname);
|
||||||
|
assert.ok(isValidHostname, "Monitor hostname should be valid");
|
||||||
|
|
||||||
|
// Test DNS resolver
|
||||||
|
const heartbeat = {};
|
||||||
|
try {
|
||||||
|
await monitor.check(config, heartbeat);
|
||||||
|
|
||||||
|
if (!testCase.valid) {
|
||||||
|
assert.strictEqual(heartbeat.status, DOWN,
|
||||||
|
`${testCase.description}: Should set status to DOWN for invalid DNS server`);
|
||||||
|
} else {
|
||||||
|
assert.ok(heartbeat.status === UP || heartbeat.status === DOWN,
|
||||||
|
`${testCase.description}: Should set valid heartbeat status`);
|
||||||
|
assert.ok(heartbeat.msg,
|
||||||
|
`${testCase.description}: Should set heartbeat message`);
|
||||||
|
|
||||||
|
if (testCase.expectUp) {
|
||||||
|
assert.strictEqual(heartbeat.status, UP,
|
||||||
|
`${testCase.description}: Should be UP for valid DNS server`);
|
||||||
|
} else {
|
||||||
|
assert.strictEqual(heartbeat.status, DOWN,
|
||||||
|
`${testCase.description}: Should be DOWN for problematic DNS server`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (testCase.valid && testCase.expectUp) {
|
||||||
|
assert.fail(`${testCase.description}: Unexpected error - ${error.message}`);
|
||||||
|
} else {
|
||||||
|
assert.ok(error,
|
||||||
|
`${testCase.description}: Should handle error for invalid DNS server`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("DNS Monitor - Record Type Test", async (t) => {
|
||||||
|
const testCases = [
|
||||||
|
{
|
||||||
|
type: "A",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "A record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "AAAA",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "AAAA record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "MX",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "MX record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "TXT",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "TXT record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "NS",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "NS record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "CNAME",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "CNAME record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "SOA",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "SOA record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "CAA",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "CAA record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "SRV",
|
||||||
|
expectSuccess: true,
|
||||||
|
description: "SRV record lookup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "INVALID",
|
||||||
|
expectSuccess: false,
|
||||||
|
description: "Invalid record type"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const monitor = new DnsMonitorType();
|
||||||
|
|
||||||
|
for (const testCase of testCases) {
|
||||||
|
const config = {
|
||||||
|
hostname: "example.com",
|
||||||
|
dns_resolve_server: "8.8.8.8",
|
||||||
|
port: 53,
|
||||||
|
dns_resolve_type: testCase.type,
|
||||||
dns_resolve_server_port: 53,
|
dns_resolve_server_port: 53,
|
||||||
maxretries: 1
|
maxretries: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const heartbeat = {};
|
||||||
try {
|
try {
|
||||||
const dnsMonitor = new DnsMonitorType(monitor);
|
await monitor.check(config, heartbeat);
|
||||||
if (!testCase.valid) {
|
|
||||||
assert.fail(`Should not create monitor for ${testCase.description}`);
|
if (!testCase.expectSuccess) {
|
||||||
|
assert.fail(`${testCase.description}: Should fail for invalid record type`);
|
||||||
}
|
}
|
||||||
assert.ok(dnsMonitor, `Should create monitor for ${testCase.description}`);
|
|
||||||
|
assert.ok(heartbeat.status === UP || heartbeat.status === DOWN,
|
||||||
|
`${testCase.description}: Should set valid heartbeat status`);
|
||||||
|
assert.ok(heartbeat.msg,
|
||||||
|
`${testCase.description}: Should set heartbeat message`);
|
||||||
|
assert.ok(heartbeat.ping > 0,
|
||||||
|
`${testCase.description}: Should measure response time`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (testCase.valid) {
|
if (testCase.expectSuccess) {
|
||||||
assert.fail(`Should create monitor for ${testCase.description}`);
|
assert.fail(`${testCase.description}: Unexpected error - ${error.message}`);
|
||||||
|
} else {
|
||||||
|
assert.ok(error,
|
||||||
|
`${testCase.description}: Should handle error for invalid record type`);
|
||||||
}
|
}
|
||||||
assert.ok(error, `Should throw error for ${testCase.description}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue