diff --git a/src/command/handlers/ping/parse.ts b/src/command/handlers/ping/parse.ts index ad8ca9a..a33b4f3 100644 --- a/src/command/handlers/ping/parse.ts +++ b/src/command/handlers/ping/parse.ts @@ -38,7 +38,7 @@ export default function parse (rawOutput: string): PingParseOutput { const resolvedAddress = String(header?.groups?.['addr']); const timeLines = lines.slice(1).map(l => parseStatsLine(l)).filter(Boolean) as PingTimings[]; - const resolvedHostname = (/(?<=from\s).*?(?=\s\(|:\s)/.exec((lines[1] ?? '')))?.[0]; + const resolvedHostname = (/(?<=from\s).*?(?=\s\(|:\s)/i.exec((lines[1] ?? '')))?.[0]; const summaryHeaderIndex = lines.findIndex(l => /^---\s(.*)\sstatistics ---/.test(l)); const summary = parseSummary(lines.slice(summaryHeaderIndex + 1)); @@ -78,10 +78,13 @@ function parseSummary (lines: string[]): PingStats { } if (packets) { - const packetsMatch = /(?\d+)\spackets\stransmitted,\s(?\d+)\s(received|packets received),\s(?\d*(?:\.\d+)?)%\spacket\sloss/.exec(packets); - stats.total = Number.parseInt(packetsMatch?.groups?.['total'] ?? '-1', 10); - stats.loss = Number.parseFloat(packetsMatch?.groups?.['loss'] ?? '-1'); - stats.rcv = Number.parseInt(packetsMatch?.groups?.['rcv'] ?? '-1', 10); + const totalMatch = /\b(?\d+)\spackets\stransmitted/.exec(packets); + const rcvMatch = /\b(?\d+)\s(received|packets received)/.exec(packets); + const lossMatch = /\b(?\d*(?:\.\d+)?)%\spacket\sloss/.exec(packets); + + stats.total = Number.parseInt(totalMatch?.groups?.['total'] ?? '-1', 10); + stats.rcv = Number.parseInt(rcvMatch?.groups?.['rcv'] ?? '-1', 10); + stats.loss = Number.parseFloat(lossMatch?.groups?.['loss'] ?? '-1'); stats.drop = stats.total - stats.rcv; } diff --git a/test/mocks/ping-unreachable-linux.json b/test/mocks/ping-unreachable-linux.json new file mode 100644 index 0000000..436ac44 --- /dev/null +++ b/test/mocks/ping-unreachable-linux.json @@ -0,0 +1,20 @@ +{ + "testId": "test", + "measurementId": "measurement", + "result": { + "status": "finished", + "resolvedAddress": "104.18.186.31", + "resolvedHostname": "eth2-1109-fsn-lf-e03.productsup.int", + "stats": { + "min": null, + "avg": null, + "max": null, + "total": 1, + "loss": 100, + "rcv": 0, + "drop": 1 + }, + "timings": [], + "rawOutput": "PING (104.18.186.31) 56(84) bytes of data.\nFrom eth2-1109-fsn-lf-e03.productsup.int (10.254.254.17) icmp_seq=1 Destination Port Unreachable\n\n--- ping statistics ---\n1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms\n" + } +} diff --git a/test/mocks/ping-unreachable-linux.txt b/test/mocks/ping-unreachable-linux.txt new file mode 100644 index 0000000..d7b4746 --- /dev/null +++ b/test/mocks/ping-unreachable-linux.txt @@ -0,0 +1,5 @@ +PING (104.18.186.31) 56(84) bytes of data. +From eth2-1109-fsn-lf-e03.productsup.int (10.254.254.17) icmp_seq=1 Destination Port Unreachable + +--- ping statistics --- +1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms diff --git a/test/unit/command/ping-command.test.ts b/test/unit/command/ping-command.test.ts index 7fdd909..6d09acb 100644 --- a/test/unit/command/ping-command.test.ts +++ b/test/unit/command/ping-command.test.ts @@ -114,7 +114,7 @@ describe('ping command executor', () => { sandbox.reset(); }); - const successfulCommands = [ 'ping-success-linux', 'ping-success-linux-no-domain', 'ping-no-source-ip-linux' ]; + const successfulCommands = [ 'ping-success-linux', 'ping-success-linux-no-domain', 'ping-no-source-ip-linux', 'ping-unreachable-linux' ]; for (const command of successfulCommands) { it(`should run and parse successful commands - ${command}`, async () => {