Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/parser/clonePingResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { pingResponse } from "../types";

function clonePingResponse(obj: pingResponse): pingResponse {
return {
host: obj.host,
numericHost: obj.numericHost,
alive: obj.alive,
output: obj.output,
time: obj.time,
times: obj.times?.length ? [...obj.times] : [],
min: obj.min,
max: obj.max,
avg: obj.avg,
bufferSize: obj.bufferSize,
stddev: obj.stddev,
packetLoss: obj.packetLoss,
};
}

export default clonePingResponse;
8 changes: 5 additions & 3 deletions src/parser/parserFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,23 @@ import linux from './linux'
import { extendedPingOptions, pingResponse } from '../types'
import { ERROR_MESSAGES } from '../messages'
import parser from "./parser.interface";
import clonePingResponse from './clonePingResponse'

//create instance of parser based on operating system
function parserFactory(platform: string, output?: string[], options?: extendedPingOptions): pingResponse {
let parser: parser;
let isWindows: boolean = false;
const baseReponse = clonePingResponse(defaultResponse)
if (!isPlatformSupported(platform)) {
throw new supportedError(ERROR_MESSAGES.PLATFORM_NOT_SUPPORTED.replace('platform', platform));
}
if (platform === 'win32') {
parser = new windows(defaultResponse, options);
parser = new windows(baseReponse, options);
isWindows = true;
} else if (platform === 'darwin') {
parser = new mac(defaultResponse, options);
parser = new mac(baseReponse, options);
} else {
parser = new linux(defaultResponse, options);
parser = new linux(baseReponse, options);
}
let result = parseOutput(parser, isWindows, output);
return result;
Expand Down
51 changes: 51 additions & 0 deletions test/parser/clonePingRespons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import test from "ava";
import clonePingResponse from "../../src/parser/clonePingResponse";
import { pingResponse } from "../../src/types";

test("clonePingResponse creates a deep copy of pingResponse", (t) => {
const original: pingResponse = {
host: "localhost",
numericHost: "127.0.0.1",
alive: true,
output: "Ping successful",
time: 10,
times: [10, 12, 11],
min: 10,
max: 12,
avg: 11,
bufferSize: 32,
stddev: 1,
packetLoss: "0%",
};

const clone = clonePingResponse(original);

t.deepEqual(clone, original);
t.not(clone, original);
t.not(clone.times, original.times);

clone.times.push(99);
t.notDeepEqual(clone.times, original.times);
});

test("clonePingResponse handles undefined times array", (t) => {
const original: pingResponse = {
host: "localhost",
numericHost: "127.0.0.1",
alive: true,
output: "Ping successful",
time: 10,
times: [],
min: 10,
max: 12,
avg: 11,
bufferSize: 32,
stddev: 1,
packetLoss: "0%",
};

const clone = clonePingResponse(original);
console.log({ clone });

t.deepEqual(clone.times, []);
});
106 changes: 55 additions & 51 deletions test/parser/parser.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,59 @@
import test from 'ava'
import parserFactory from '../../src/parser/parserFactory'
const fs = require('fs');
const readline = require('readline');
import * as response from './replies.json'

import test from "ava";
import parserFactory from "../../src/parser/parserFactory";
const fs = require("fs");
const readline = require("readline");
import * as response from "./replies.json";

const normalize = (val: any) => ({
...val,
bufferSize: val.bufferSize ?? undefined,
});
//function to read file line by line to mock actual response
async function processLineByLine(path: string): Promise<string[]> {
let text: string[] = [];
const fileStream = fs.createReadStream(path);

//reading file line by line
const rl = readline.createInterface({
input: fileStream,
output: process.stdout,
console: false
});
for await (const line of rl) {
// Each line in file will be successively available here as `line`.
text.push(line + '\n');
}
return text;
let text: string[] = [];
const fileStream = fs.createReadStream(path);

//reading file line by line
const rl = readline.createInterface({
input: fileStream,
output: process.stdout,
console: false,
});
for await (const line of rl) {
// Each line in file will be successively available here as `line`.
text.push(line + "\n");
}
return text;
}

test('ouput for windows IPV4 ping', async t => {
let input = await processLineByLine(__dirname + '/samples/windowsIPV4.txt');
let output = parserFactory("win32", input);
t.deepEqual(output as any, response.windows_ipv4);
})

test('ouput for windows IPV6 ping', async t => {
let input = await processLineByLine(__dirname + '/samples/windowsIPV6.txt');
let output = parserFactory("win32", input, {IPV6:true});
t.deepEqual(output as any, response.windows_ipv6);
})

test('ouput for linux IPV4 ping', async t => {
let input = await processLineByLine(__dirname + '/samples/linuxIPV4.txt');
let output = parserFactory("linux", input);
t.deepEqual(output as any, response.linux_ipv4);
})

test('ouput for linux IPV6 ping', async t => {
let input = await processLineByLine(__dirname + '/samples/linuxIPV6.txt');
let output = parserFactory("linux", input, {IPV6:true});
t.deepEqual(output as any, response.linux_ipv6);
})

test('ouput for mac IPV4 ping', async t => {
let input = await processLineByLine(__dirname + '/samples/macIPV4.txt');
let output = parserFactory("darwin", input);
t.deepEqual(output as any, response.macos_ipv4);
})

//TO-DO - Add a mac ipv6 test
test("ouput for windows IPV4 ping", async (t) => {
let input = await processLineByLine(__dirname + "/samples/windowsIPV4.txt");
let output = parserFactory("win32", input);
t.deepEqual(output as any, response.windows_ipv4);
});

test("ouput for windows IPV6 ping", async (t) => {
let input = await processLineByLine(__dirname + "/samples/windowsIPV6.txt");
let output = parserFactory("win32", input, { IPV6: true });
t.deepEqual(output, normalize(response.windows_ipv6));
});

test("ouput for linux IPV4 ping", async (t) => {
let input = await processLineByLine(__dirname + "/samples/linuxIPV4.txt");
let output = parserFactory("linux", input);
t.deepEqual(output as any, normalize(response.linux_ipv4));
});

test("ouput for linux IPV6 ping", async (t) => {
let input = await processLineByLine(__dirname + "/samples/linuxIPV6.txt");
let output = parserFactory("linux", input, { IPV6: true });
t.deepEqual(output as any, normalize(response.linux_ipv6));
});

test("ouput for mac IPV4 ping", async (t) => {
let input = await processLineByLine(__dirname + "/samples/macIPV4.txt");
let output = parserFactory("darwin", input);
t.deepEqual(output as any, normalize(response.macos_ipv4));
});

//TO-DO - Add a mac ipv6 test
165 changes: 71 additions & 94 deletions test/parser/replies.json
Original file line number Diff line number Diff line change
@@ -1,95 +1,72 @@
{
"windows_ipv4": {
"host": "www.some-domain.com",
"numericHost": "127.0.0.1",
"alive": true,
"output": "Pinging www.some-domain.com [127.0.0.1] with 32 bytes of\nReply from 127.0.0.1: bytes=32 time=564ms TTL=237\nReply from 127.0.0.1: bytes=32 time=555ms TTL=237\nReply from 127.0.0.1: bytes=32 time=554ms TTL=237\nReply from 127.0.0.1: bytes=32 time=548ms TTL=237\n\nPing statistics for 127.0.0.1:\n Packets: Sent = 4, Received = 4, Lost = 0 (0% loss)\nApproximate round trip times in milli-seconds:\n Minimum = 548ms, Maximum = 564ms, Average = 555ms\n",
"time": 564,
"times": [
564,
555,
554,
548
],
"min": "548.000",
"max": "564.000",
"avg": "555.000",
"bufferSize": 32,
"stddev": "5.717",
"packetLoss": "0"
},
"macos_ipv4": {
"host": "google.com",
"numericHost": "172.217.24.46",
"alive": true,
"output": "PING google.com (172.217.24.46): 56 data bytes\n64 bytes from 172.217.24.46: icmp_seq=0 ttl=54 time=5.371 ms\n64 bytes from 172.217.24.46: icmp_seq=1 ttl=54 time=4.269 ms\n64 bytes from 172.217.24.46: icmp_seq=2 ttl=54 time=4.970 ms\n64 bytes from 172.217.24.46: icmp_seq=3 ttl=54 time=5.228 ms\n\n--- google.com ping statistics ---\n4 packets transmitted, 4 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 4.269/4.960/5.371/0.424 ms\n",
"time": 5.371,
"times": [
5.371,
4.269,
4.97,
5.228
],
"min": "4.269",
"max": "5.371",
"avg": "4.960",
"bufferSize": 32,
"stddev": "0.424",
"packetLoss": "0.0"
},
"linux_ipv4": {
"host": "localhost",
"numericHost": "127.0.0.1",
"alive": true,
"output": "PING localhost (127.0.0.1) 56(84) bytes of data.\n64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.022 ms\n64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.027 ms\n64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.029 ms\n64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.030 ms\n\n--- localhost ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 2999ms\nrtt min/avg/max/mdev = 0.022/0.027/0.030/0.003 ms\n",
"time": 0.022,
"times": [
0.022,
0.027,
0.029,
0.03
],
"min": "0.022",
"max": "0.030",
"avg": "0.027",
"bufferSize": 32,
"stddev": "0.003",
"packetLoss": "0"
},
"linux_ipv6": {
"host": "2606:4700:4700::1111",
"numericHost": "2606:4700:4700::1111",
"alive": true,
"output": "PING 2606:4700:4700::1111(2606:4700:4700::1111) 56 data bytes\n64 bytes from 2606:4700:4700::1111: icmp_seq=1 ttl=57 time=0.672 ms\n64 bytes from 2606:4700:4700::1111: icmp_seq=2 ttl=57 time=1.00 ms\n\n--- 2606:4700:4700::1111 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1000ms\nrtt min/avg/max/mdev = 0.672/0.840/1.009/0.170 ms\n",
"time": 0.672,
"times": [
0.672,
1.00
],
"min": "0.672",
"max": "1.009",
"avg": "0.840",
"bufferSize": 32,
"stddev": "0.170",
"packetLoss": "0"
},
"windows_ipv6": {
"host": "fe80::2940:90ec:a964:4b42%7",
"numericHost": "fe80::2940:90ec:a964:4b42%7",
"alive": true,
"output": "Pinging fe80::2940:90ec:a964:4b42%7 with 32 bytes of data:\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\n\nPing statistics for fe80::2940:90ec:a964:4b42%7:\n Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\nApproximate round trip times in milli-seconds:\n Minimum = 0ms, Maximum = 0ms, Average = 0ms\n",
"time": 1,
"times": [
1,
1,
1,
1
],
"min": "0.000",
"max": "0.000",
"avg": "0.000",
"bufferSize": 32,
"stddev": "5.717",
"packetLoss": "0"
}
}
"windows_ipv4": {
"host": "www.some-domain.com",
"numericHost": "127.0.0.1",
"alive": true,
"output": "Pinging www.some-domain.com [127.0.0.1] with 32 bytes of\nReply from 127.0.0.1: bytes=32 time=564ms TTL=237\nReply from 127.0.0.1: bytes=32 time=555ms TTL=237\nReply from 127.0.0.1: bytes=32 time=554ms TTL=237\nReply from 127.0.0.1: bytes=32 time=548ms TTL=237\n\nPing statistics for 127.0.0.1:\n Packets: Sent = 4, Received = 4, Lost = 0 (0% loss)\nApproximate round trip times in milli-seconds:\n Minimum = 548ms, Maximum = 564ms, Average = 555ms\n",
"time": 564,
"times": [564, 555, 554, 548],
"min": "548.000",
"max": "564.000",
"avg": "555.000",
"bufferSize": 32,
"stddev": "5.717",
"packetLoss": "0"
},
"macos_ipv4": {
"host": "google.com",
"numericHost": "172.217.24.46",
"alive": true,
"output": "PING google.com (172.217.24.46): 56 data bytes\n64 bytes from 172.217.24.46: icmp_seq=0 ttl=54 time=5.371 ms\n64 bytes from 172.217.24.46: icmp_seq=1 ttl=54 time=4.269 ms\n64 bytes from 172.217.24.46: icmp_seq=2 ttl=54 time=4.970 ms\n64 bytes from 172.217.24.46: icmp_seq=3 ttl=54 time=5.228 ms\n\n--- google.com ping statistics ---\n4 packets transmitted, 4 packets received, 0.0% packet loss\nround-trip min/avg/max/stddev = 4.269/4.960/5.371/0.424 ms\n",
"time": 5.371,
"times": [5.371, 4.269, 4.97, 5.228],
"min": "4.269",
"max": "5.371",
"avg": "4.960",
"bufferSize": null,
"stddev": "0.424",
"packetLoss": "0.0"
},
"linux_ipv4": {
"host": "localhost",
"numericHost": "127.0.0.1",
"alive": true,
"output": "PING localhost (127.0.0.1) 56(84) bytes of data.\n64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.022 ms\n64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.027 ms\n64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.029 ms\n64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.030 ms\n\n--- localhost ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 2999ms\nrtt min/avg/max/mdev = 0.022/0.027/0.030/0.003 ms\n",
"time": 0.022,
"times": [0.022, 0.027, 0.029, 0.03],
"min": "0.022",
"max": "0.030",
"avg": "0.027",
"bufferSize": null,
"stddev": "0.003",
"packetLoss": "0"
},
"linux_ipv6": {
"host": "2606:4700:4700::1111",
"numericHost": "2606:4700:4700::1111",
"alive": true,
"output": "PING 2606:4700:4700::1111(2606:4700:4700::1111) 56 data bytes\n64 bytes from 2606:4700:4700::1111: icmp_seq=1 ttl=57 time=0.672 ms\n64 bytes from 2606:4700:4700::1111: icmp_seq=2 ttl=57 time=1.00 ms\n\n--- 2606:4700:4700::1111 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1000ms\nrtt min/avg/max/mdev = 0.672/0.840/1.009/0.170 ms\n",
"time": 0.672,
"times": [0.672, 1.0],
"min": "0.672",
"max": "1.009",
"avg": "0.840",
"bufferSize": null,
"stddev": "0.170",
"packetLoss": "0"
},
"windows_ipv6": {
"host": "fe80::2940:90ec:a964:4b42%7",
"numericHost": "fe80::2940:90ec:a964:4b42%7",
"alive": true,
"output": "Pinging fe80::2940:90ec:a964:4b42%7 with 32 bytes of data:\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\nReply from fe80::2940:90ec:a964:4b42%7: time<1ms\n\nPing statistics for fe80::2940:90ec:a964:4b42%7:\n Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\nApproximate round trip times in milli-seconds:\n Minimum = 0ms, Maximum = 0ms, Average = 0ms\n",
"time": 1,
"times": [1, 1, 1, 1],
"min": "0.000",
"max": "0.000",
"avg": "0.000",
"bufferSize": null,
"stddev": "0.000",
"packetLoss": "0"
}
}