Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: probe types in test file #884

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
203 changes: 155 additions & 48 deletions Probe/Tests/Utils/PingMonitor.test.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,172 @@
import Hostname from 'Common/Types/API/Hostname';
import IPv4 from 'Common/Types/IP/IPv4';
import IPv6 from 'Common/Types/IP/IPv6';
import PositiveNumber from 'Common/Types/PositiveNumber';
import Ping, {
PingResponse,
} from '../../Utils/Monitors/MonitorTypes/PingMonitor';
import '@types/jest';
import ping from 'ping';

jest.mock('ping');

type HostResponses = {
[key: string]: { alive: boolean; time?: number } | Error;
};

const hostResponses: HostResponses = {
'google.com': { alive: true, time: 50 },
'facebook.com': { alive: true, time: 50 },
'microsoft.com': { alive: true, time: 50 },
'youtube.com': { alive: true, time: 50 },
'apple.com': { alive: true, time: 50 },
'8.8.8.8': { alive: true, time: 50 },
'2001:4860:4860::8888': { alive: true, time: 50 },
'invalid.hostname': { alive: false },
'other.hostname': new Error('some error'),
};

const mockProbe: jest.Mock = jest.fn((host: string) => {
const response: { alive: boolean; time?: number } | Error | undefined =
hostResponses[host];
if (response) {
if (response instanceof Error) {
return Promise.reject(response);
}
return Promise.resolve(response);
}
return Promise.reject(
response ?? new Error('some error including timeout and exceeded words')
);
});

describe('Ping', () => {
jest.setTimeout(10000);
test('Ping.ping should return appropriate object if the valid hostname is given', async () => {
let result: PingResponse | null = await Ping.ping(
new Hostname('google.com', 80)
);

expect(result).not.toBeNull();
expect(result!.responseTimeInMS?.toNumber()).toBeGreaterThan(0);
expect(result!.responseTimeInMS?.toNumber()).toBeLessThanOrEqual(5000);
expect(result!.isOnline).toBe(true);
result = await Ping.ping(new Hostname('www.google.com', 80), {
timeout: new PositiveNumber(5000),
describe('ping()', () => {
afterAll(() => {
jest.restoreAllMocks();
jest.mock('ping');
});

jest.setTimeout(20000);

// @ts-ignore
ping.promise.probe = mockProbe;
it('should succeed with a valid and reachable hostname', async () => {
const result: PingResponse | null = await Ping.ping(
new Hostname('google.com'),
{
timeout: new PositiveNumber(5000),
}
);

expect(result).not.toBeNull();
expect(result!.isOnline).toBe(true);
expect(result!.responseTimeInMS).toBeDefined();
expect(result!.responseTimeInMS?.toNumber()).toBeGreaterThan(0);
expect(result!.responseTimeInMS?.toNumber()).toBeLessThanOrEqual(
5000
);
});

it('should succeed with a valid IPV4 address', async () => {
const result: PingResponse | null = await Ping.ping(
new IPv4('8.8.8.8'),
{
timeout: new PositiveNumber(5000),
}
);

expect(result).not.toBeNull();
expect(result!.isOnline).toBe(true);
expect(result!.responseTimeInMS).toBeDefined();
expect(result!.responseTimeInMS?.toNumber()).toBeGreaterThan(0);
expect(result!.responseTimeInMS?.toNumber()).toBeLessThanOrEqual(
5000
);
});

it('should succeed with a valid and reachable IPv6 address', async () => {
const ipv6Address: IPv6 = new IPv6('2001:4860:4860::8888');
const result: PingResponse | null = await Ping.ping(ipv6Address);

expect(result).not.toBeNull();
expect(result!.isOnline).toBe(true);
expect(result!.responseTimeInMS).toBeDefined();
expect(result!.responseTimeInMS?.toNumber()).toBeGreaterThan(0);
expect(result!.responseTimeInMS?.toNumber()).toBeLessThanOrEqual(
5000
);
});

expect(result).not.toBeNull();
expect(result!.isOnline).toBe(true);
expect(result!.responseTimeInMS?.toNumber()).toBeGreaterThan(0);
expect(result!.responseTimeInMS?.toNumber()).toBeLessThanOrEqual(5000);
it('should fail with an invalid hostname', async () => {
const result: PingResponse | null = await Ping.ping(
new Hostname('invalid.hostname'),
{
timeout: new PositiveNumber(5000),
}
);

result = await Ping.ping(new Hostname('www.google.com', 65000), {
timeout: new PositiveNumber(5000),
expect(result).not.toBeNull();
expect(result!.isOnline).toBe(false);
expect(result!.responseTimeInMS).toBeUndefined();
});
expect(result).not.toBeNull();
expect(result!.isOnline).toBe(false);
expect(result!.responseTimeInMS).toBeUndefined();

result = await Ping.ping(new Hostname('www.a.com', 65000), {
timeout: new PositiveNumber(5000),
it('should fail with an unreachable IPv6 address', async () => {
const ipv6Address: IPv6 = new IPv6(
'abcd:ef01:2345:6789:abcd:ef01:2345:6789'
);
// since ping does not support timeouts on IPv6, we set the deadline to 1 second to avoid exceeding jest's timeout
const result: PingResponse | null = await Ping.ping(ipv6Address, {
deadline: 1,
});

expect(result).not.toBeNull();
expect(result!.isOnline).toBe(false);
expect(result!.responseTimeInMS).toBeUndefined();
});

it('should return failureCause as Timeout exceeded on timeout', async () => {
const unreachableHost: Hostname = new Hostname('10.255.255.1');
const timeout: PositiveNumber = new PositiveNumber(1); // very low to force timeout

const result: PingResponse | null = await Ping.ping(
unreachableHost,
{ timeout }
);

expect(result).not.toBeNull();
expect(result!.isOnline).toBe(false);
expect(result!.failureCause).toBe('Timeout exceeded');
});

it('should return null when the probe is offline and it is not an online check request', async () => {
jest.spyOn(Ping, 'isProbeOnline').mockResolvedValue(false);

const offlineHost: Hostname = new Hostname('other.hostname');
const result: PingResponse | null = await Ping.ping(offlineHost, {
isOnlineCheckRequest: false,
});

expect(result).toBeNull();
expect(Ping.isProbeOnline).toHaveBeenCalled();
});
expect(result).not.toBeNull();
expect(result!.isOnline).toBe(false);
expect(result!.isOnline).toBe(false);
expect(result!.responseTimeInMS).toBeUndefined();
});
test('Ping.ping should return appropriate object if the valid IPV4 or IPV6 is given', async () => {
let result: PingResponse | null = null;

result = await Ping.ping(new IPv4('172.217.170.206'), {
timeout: new PositiveNumber(5000),
}); // One of the google ip
expect(result).not.toBeNull();
expect(result!.isOnline).toBe(true);
expect(result!.responseTimeInMS?.toNumber()).toBeGreaterThan(0);
expect(result!.responseTimeInMS?.toNumber()).toBeLessThanOrEqual(5000);

result = await Ping.ping(new IPv4('192.0.2.200')); //
expect(result).not.toBeNull();
expect(result!.isOnline).toBe(false);
expect(result!.responseTimeInMS).toBeUndefined();

result = await Ping.ping(new IPv4('0.42.52.42')); // ip can't start 0
expect(result).not.toBeNull();
expect(result!.responseTimeInMS).toBeUndefined();
expect(result!.isOnline).toBe(false);

describe('isProbeOnline', () => {
it('should return true if any ping is successful', async () => {
Ping.ping = jest
.fn()
.mockResolvedValueOnce({ isOnline: false })
.mockResolvedValueOnce({ isOnline: true });

const result: boolean = await Ping.isProbeOnline();
expect(result).toBe(true);
});

it('should return false if all pings fail', async () => {
Ping.ping = jest.fn().mockResolvedValueOnce({ isOnline: false });

const result: boolean = await Ping.isProbeOnline();
expect(result).toBe(false);
});
});
});
Loading
Loading