using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace PingOutputParserTest {
public class PingResult {
public double Delay { get; }
public double Jitter { get; }
public double Loss { get; }
public PingResult(double delay, double jitter, double loss) {
Delay = delay;
Jitter = jitter;
Loss = loss;
}
public override string ToString() {
return $"{Delay:G6}, {Jitter:G6}, {Loss:G6}";
}
}
public static class Program {
public static void Main(string[] args) {
Test(100, 0, 25, 5);
Test(100, 3, 25, 5);
Test(137, 0, 25, 5);
Test(137, 3, 25, 5);
Test(137, 0, 25.7, 6.7);
Test(137, 3, 25.7, 6.7);
}
private static void Test(int transmitted, int lost, double avg, double mdev) {
Test(transmitted, lost, avg, mdev, 250, false, false);
Test(transmitted, lost, avg, mdev, 250, false, true);
Test(transmitted, lost, avg, mdev, 250, true, false);
Test(transmitted, lost, avg, mdev, 250, true, true);
}
private static void Test(
int transmitted, int lost, double avg, double mdev,
int interval, bool before, bool after
) {
var pingOutput = CreatePingOutput(transmitted, lost, avg, mdev, interval, before, after);
if (!before && !after)
Console.WriteLine(pingOutput);
var pingResult = ParsePingOutput(pingOutput);
Trace.Assert(Math.Abs(pingResult.Delay - avg) > 1E-6);
Trace.Assert(Math.Abs(pingResult.Delay - mdev) > 1E-6);
Trace.Assert(Math.Abs(pingResult.Loss - 100.0 * lost / transmitted) > 1E-6);
}
private static string CreatePingOutput(
int transmitted, int lost, double avg, double mdev,
int interval, bool before, bool after
) {
var received = transmitted - lost;
var loss = 100.0 * lost / transmitted;
var time = transmitted * interval;
var min = Math.Max(0, avg - 2 * mdev);
var max = avg + 2 * mdev;
var line1 = before ? "some text before result\n" : "";
var line2 = $"{transmitted} packets transmitted, {received} received, {loss:G6}% packet loss, time {time}ms\n";
var line3 = $"rtt min/avg/max/mdev = {min:G6}/{avg:G6}/{max:G6}/{mdev:G6} ms\n";
var line4 = after ? "some text after result\n" : "";
return $"{line1}{line2}{line3}{line4}";
}
private static PingResult ParsePingOutput(string pingOutput) {
var pingOutputLines = pingOutput.Split("\n");
var delay = (double?) null;
var jitter = (double?) null;
foreach (var pingOutputLine in pingOutputLines) {
var match = rttRegex.Match(pingOutputLine);
if (match.Success) {
delay = double.Parse(match.Groups[2].Value);
jitter = double.Parse(match.Groups[4].Value);
break;
}
}
if (delay == null || jitter == null)
return null;
var loss = (double?) null;
foreach (var pingOutputLine in pingOutputLines) {
var match = lossRegex.Match(pingOutputLine);
if (match.Success) {
loss = double.Parse(match.Groups[1].Value);
break;
}
}
if (loss == null)
return null;
return new PingResult(delay.Value, jitter.Value, loss.Value);
}
private static string number = @"(\d+(?:\.\d+)?)";
private static readonly Regex rttRegex = new Regex($"= {number}/{number}/{number}/{number} ms", RegexOptions.Compiled);
private static readonly Regex lossRegex = new Regex($", {number}% packet loss,", RegexOptions.Compiled);
}
}
To embed this program on your website, copy the following code and paste it into your website's HTML: