()
| 588 | } |
| 589 | |
| 590 | async function performDNSTests() { |
| 591 | const totalServers = dnsServers.length; |
| 592 | const totalQueries = topWebsites.length; |
| 593 | |
| 594 | for (let i = 0; i < dnsServers.length; i++) { |
| 595 | const server = dnsServers[i]; |
| 596 | |
| 597 | // Update progress |
| 598 | btnText.textContent = `Testing ${i + 1}/${totalServers}...`; |
| 599 | progressCount.textContent = `${i + 1} of ${totalServers}`; |
| 600 | progressFill.style.width = `${((i + 1) / totalServers) * 100}%`; |
| 601 | |
| 602 | const speedResults = await Promise.all( |
| 603 | topWebsites.map(website => measureDNSSpeed(server.url, website, server.type, server.allowCors)) |
| 604 | ); |
| 605 | |
| 606 | server.individualResults = topWebsites.map((website, idx) => ({ |
| 607 | website, |
| 608 | speed: speedResults[idx] !== null ? speedResults[idx] : 'Unavailable' |
| 609 | })); |
| 610 | |
| 611 | if (totalQueries === 0) { |
| 612 | server.speed = { min: 'Unavailable', median: 'Unavailable', max: 'Unavailable', avg: 'Unavailable' }; |
| 613 | server.reliability = { status: 'no-data', successCount: 0, failureCount: 0, totalQueries: 0, message: 'No hostnames configured for testing.' }; |
| 614 | } else { |
| 615 | const penalizedResults = speedResults.map(s => typeof s === 'number' ? s : TIMEOUT_PENALTY_MS); |
| 616 | server.speed = calculateSpeedStats(penalizedResults); |
| 617 | server.reliability = buildReliabilityProfile(speedResults, totalQueries); |
| 618 | } |
| 619 | |
| 620 | updateResult(server); |
| 621 | } |
| 622 | } |
| 623 | |
| 624 | function calculateSpeedStats(results) { |
| 625 | if (!results.length) { |
no test coverage detected