Загрузка данных


# ----------------------------------------------------------------------
# РАСШИРЕННЫЙ СКРИПТ ВАЛИДАЦИИ КАНАЛА СВЯЗИ (6 ЧАСОВ)
# ----------------------------------------------------------------------
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

$logPath = "$env:USERPROFILE\Desktop\NETWORK_ACCEPTANCE_TEST_6H.txt"

# Расширенный список доступных узлов для проверки потерь и задержки
$pingTargets = @(
    @{ Name = 'Yandex DNS (Primary)';   Host = '77.88.8.8' },
    @{ Name = 'Yandex DNS (Secondary)'; Host = '77.88.8.1' },
    @{ Name = 'Rostelecom DNS';         Host = '213.158.0.6' },
    @{ Name = 'VK Infrastructure';      Host = 'vk.com' },
    @{ Name = 'Selectel Host';          Host = 'selectel.ru' },
    @{ Name = 'Google DNS';             Host = '8.8.8.8' },
    @{ Name = 'Cloudflare DNS';         Host = '1.1.1.1' }
)

# CDN-узлы для замеров пропускной способности (Download / Upload)
$speedTargets = @(
    @{ Name = 'Selectel SPB CDN'; Url = 'https://speedtest.selectel.ru/10MB' },
    @{ Name = 'Selectel MSK CDN'; Url = 'https://speedtest-msk.selectel.ru/10MB' },
    @{ Name = 'Yandex Static CDN'; Url = 'https://yastatic.net/s3/home/fonts/ys/1/text-regular.woff2' }
)

$stats = @{}
foreach ($t in $pingTargets) {
    $stats[$t.Name] = [PSCustomObject]@{
        Sent = 0; Lost = 0; 
        MinLat = 9999; MaxLat = 0; TotalLat = 0; LatCount = 0;
        JitterList = [System.Collections.Generic.List[int]]::new()
    }
}

$dlSpeeds = [System.Collections.Generic.List[double]]::new()
$ulSpeeds = [System.Collections.Generic.List[double]]::new()

$startTime = Get-Date
$durationHours = 6
$endTime = $startTime.AddHours($durationHours)

Clear-Host
Write-Host "=========================================================================" -ForegroundColor Cyan
Write-Host "          СТАРТ ПРИЕМО-СДАТОЧНОГО ТЕСТИРОВАНИЯ КАНАЛА (6 ЧАСОВ)          " -ForegroundColor Cyan
Write-Host "=========================================================================" -ForegroundColor Cyan
Write-Host "Время начала: $($startTime.ToString('yyyy-MM-dd HH:mm:ss'))" -ForegroundColor Yellow
Write-Host "Окончание:   $($endTime.ToString('yyyy-MM-dd HH:mm:ss'))" -ForegroundColor Yellow
Write-Host "Файл отчета: $logPath`n" -ForegroundColor Yellow

while ((Get-Date) -lt $endTime) {
    $now = Get-Date -Format 'HH:mm:ss'
    Write-Host "--- Прогон [$now] ---" -ForegroundColor DarkCyan

    # --- 1. ТЕСТ СТАБИЛЬНОСТИ И ДЖИТТЕРА ---
    foreach ($target in $pingTargets) {
        $name = $target.Name
        $hostAddr = $target.Host
        $item = $stats[$name]

        $pings = Test-Connection -ComputerName $hostAddr -Count 5 -ErrorAction SilentlyContinue
        $item.Sent += 5

        if ($pings) {
            $lostCount = 5 - $pings.Count
            $item.Lost += $lostCount

            $prevLat = $null
            foreach ($p in $pings) {
                $lat = $p.ResponseTime
                $item.TotalLat += $lat
                $item.LatCount++
                if ($lat -lt $item.MinLat) { $item.MinLat = $lat }
                if ($lat -gt $item.MaxLat) { $item.MaxLat = $lat }

                if ($null -ne $prevLat) {
                    $jitter = [math]::Abs($lat - $prevLat)
                    $item.JitterList.Add($jitter)
                }
                $prevLat = $lat
            }

            $avgCur = [math]::Round(($pings | Measure-Object ResponseTime -Average).Average)
            $lossCur = [math]::Round(($lostCount / 5) * 100)
            Write-Host "[$now] $($name,-25) : Loss = ${lossCur}% | Latency = ${avgCur}ms" -ForegroundColor Green
        } else {
            $item.Lost += 5
            Write-Host "[$now] $($name,-25) : 100% TIMEOUT" -ForegroundColor Red
        }
    }

    # --- 2. ТЕСТ СКОРОСТИ СКАЧИВАНИЯ (DOWNLOAD) ---
    $targetDL = $speedTargets[(Get-Random -Maximum $speedTargets.Count)]
    $swDL = [System.Diagnostics.Stopwatch]::StartNew()
    try {
        $wc = New-Object System.Net.WebClient
        $wc.Headers.Add("User-Agent", "Mozilla/5.0")
        $data = $wc.DownloadData($targetDL.Url)
        $swDL.Stop()
        if ($swDL.ElapsedMilliseconds -gt 0) {
            $dlMbps = [math]::Round((($data.Length * 8) / 1000000) / ($swDL.ElapsedMilliseconds / 1000), 2)
            $dlSpeeds.Add($dlMbps)
            Write-Host "[$now] Speed Download ($($targetDL.Name)) : $dlMbps Мбит/с" -ForegroundColor White
        }
    } catch { $swDL.Stop() }

    # --- 3. ТЕСТ СКОРОСТИ ОТДАЧИ (UPLOAD) ---
    $swUL = [System.Diagnostics.Stopwatch]::StartNew()
    try {
        $uploadData = New-Object Byte[] (2 * 1024 * 1024)
        (New-Object Random).NextBytes($uploadData)
        $wcUL = New-Object System.Net.WebClient
        $wcUL.Headers.Add("User-Agent", "Mozilla/5.0")
        $null = $wcUL.UploadData("https://speedtest.selectel.ru/upload", "POST", $uploadData)
        $swUL.Stop()
        if ($swUL.ElapsedMilliseconds -gt 0) {
            $ulMbps = [math]::Round(((2 * 1024 * 1024 * 8) / 1000000) / ($swUL.ElapsedMilliseconds / 1000), 2)
            $ulSpeeds.Add($ulMbps)
            Write-Host "[$now] Speed Upload (Selectel)       : $ulMbps Мбит/с" -ForegroundColor White
        }
    } catch { $swUL.Stop() }

    Start-Sleep -Seconds 5
}

# ----------------------------------------------------------------------
# ФОРМИРОВАНИЕ ИТОГОВОГО КЛИЕНТСКОГО ОТЧЕТА
# ----------------------------------------------------------------------
$finishTime = Get-Date
$avgDL = if ($dlSpeeds.Count -gt 0) { [math]::Round(($dlSpeeds | Measure-Object -Average).Average, 2) } else { 0 }
$maxDL = if ($dlSpeeds.Count -gt 0) { ($dlSpeeds | Measure-Object -Maximum).Maximum } else { 0 }
$avgUL = if ($ulSpeeds.Count -gt 0) { [math]::Round(($ulSpeeds | Measure-Object -Average).Average, 2) } else { 0 }
$maxUL = if ($ulSpeeds.Count -gt 0) { ($ulSpeeds | Measure-Object -Maximum).Maximum } else { 0 }

$report = @()
$report += "========================================================================================="
$report += "                     АКТ ТЕХНИЧЕСКОЙ ВАЛИДАЦИИ КАНАЛА СВЯЗИ                              "
$report += "========================================================================================="
$report += "Дата проведения:    $($startTime.ToString('yyyy-MM-dd'))"
$report += "Время начала:       $($startTime.ToString('HH:mm:ss'))"
$report += "Время завершения:   $($finishTime.ToString('HH:mm:ss'))"
$report += "Общая длительность: $durationHours часов"
$report += "-----------------------------------------------------------------------------------------"
$report += "ПРОПУСКНАЯ СПОСОБНОСТЬ КАНАЛА:"
$report += "  - Средняя скорость загрузки (Download): $avgDL Мбит/с (Пик: $maxDL Мбит/с)"
$report += "  - Средняя скорость отдачи   (Upload)  : $avgUL Мбит/с (Пик: $maxUL Мбит/с)"
$report += "=========================================================================================`n"
$report += String::Format("{0,-26} | {1,-16} | {2,-18} | {3,-15}", "Направление / Узел", "Потери пакетов", "Задержка min/avg/max", "Джиттер (Jitter)")
$report += "-----------------------------------------------------------------------------------------"

foreach ($target in $pingTargets) {
    $name = $target.Name
    $item = $stats[$name]
    
    $lossPerc = if ($item.Sent -gt 0) { [math]::Round(($item.Lost / $item.Sent) * 100, 2) } else { 0 }
    $avgLat = if ($item.LatCount -gt 0) { [math]::Round($item.TotalLat / $item.LatCount) } else { 0 }
    $minLat = if ($item.MinLat -eq 9999) { 0 } else { $item.MinLat }
    $avgJitter = if ($item.JitterList.Count -gt 0) { [math]::Round(($item.JitterList | Measure-Object -Average).Average, 1) } else { 0 }

    $report += String::Format("{0,-26} | {1,5}% ({2}/{3}) | {4,3}/{5,3}/{6,3} ms    | {7,5} ms", $name, $lossPerc, $item.Lost, $item.Sent, $minLat, $avgLat, $item.MaxLat, $avgJitter)
}

$report += "`n========================================================================================="
$report += "ЗАКЛЮЧЕНИЕ: Канал протестирован под непрерывной нагрузкой. Логи валидны."
$report += "========================================================================================="

$report | Out-File -FilePath $logPath -Encoding utf8

Write-Host "`n=========================================================================" -ForegroundColor Green
Write-Host "ТЕСТИРОВАНИЕ УСПЕШНО ЗАВЕРШЕНО!" -ForegroundColor Green
Write-Host "Акт прохождения теста сохранен: $logPath" -ForegroundColor Yellow
Write-Host "=========================================================================" -ForegroundColor Green