From 7668d3bd3efe006c90e14e014c20d670a3d2eb7a Mon Sep 17 00:00:00 2001 From: Zaid-maker Date: Wed, 27 Nov 2024 12:13:22 +0500 Subject: [PATCH] The tests now cover: - All DNS record types - Various DNS providers - Edge cases and error conditions - Response format validation - Performance metrics - Security validations --- test/backend-test/test-dns-monitor.js | 389 ++++++++++++++++++++++++-- 1 file changed, 367 insertions(+), 22 deletions(-) diff --git a/test/backend-test/test-dns-monitor.js b/test/backend-test/test-dns-monitor.js index 444aa2a27..798156c39 100644 --- a/test/backend-test/test-dns-monitor.js +++ b/test/backend-test/test-dns-monitor.js @@ -28,6 +28,201 @@ test("DNSMonitor - Timestamp Test", async (t) => { 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) => { const monitor = { hostname: "test1.example.com", @@ -83,18 +278,10 @@ test("DNS Monitor - URL Validation Test", async (t) => { maxretries: 1 }; - try { - const dnsMonitor = new DnsMonitorType(monitor); - if (!testCase.valid) { - assert.fail(`Should not create monitor for ${testCase.description}`); - } - 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}`); - } + const dnsMonitor = new DnsMonitorType(monitor); + const isValid = dnsMonitor.validateHostname(testCase.hostname); + assert.strictEqual(isValid, testCase.valid, + `${testCase.description}: ${testCase.hostname} should be ${testCase.valid ? "valid" : "invalid"}`); } }); @@ -102,47 +289,205 @@ test("DNS Monitor - Resolver Test", async (t) => { const testCases = [ { server: "8.8.8.8", + port: 53, valid: true, + expectUp: true, description: "Google DNS" }, { server: "1.1.1.1", + port: 53, valid: true, + expectUp: true, 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", + port: 53, valid: false, + expectUp: false, description: "Invalid DNS server hostname" }, { server: "javascript:alert(1)", + port: 53, valid: false, + expectUp: false, 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) { - const monitor = { - hostname: "test1.example.com", + const config = { + hostname: "example.com", dns_resolve_server: testCase.server, - port: 53, + port: testCase.port, 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, maxretries: 1 }; + const heartbeat = {}; try { - const dnsMonitor = new DnsMonitorType(monitor); - if (!testCase.valid) { - assert.fail(`Should not create monitor for ${testCase.description}`); + await monitor.check(config, heartbeat); + + 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) { - if (testCase.valid) { - assert.fail(`Should create monitor for ${testCase.description}`); + if (testCase.expectSuccess) { + 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}`); } } });