Skip to content

Commit

Permalink
fix: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alexey-yarmosh committed Apr 10, 2024
1 parent 8ddd34a commit 443141e
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 63 deletions.
8 changes: 4 additions & 4 deletions src/lib/admin-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ export class AdminData {
getUpdatedProbes (probes: Probe[]) {
return probes.map(probe => ({
...probe,
location: this.getUpdatedLocation(probe) || probe.location,
location: this.getUpdatedLocation(probe),
}));
}

getUpdatedLocation (probe: Probe): ProbeLocation | null {
getUpdatedLocation (probe: Probe): ProbeLocation {
for (const [ range, adminData ] of this.locationOverrides) {
const ip = ipaddr.parse(probe.ipAddress);

Expand All @@ -55,13 +55,13 @@ export class AdminData {
city: adminData.city,
normalizedCity: normalizeFromPublicName(adminData.city),
country: adminData.country,
...(adminData.state && { state: adminData.state }),
state: adminData.state,
latitude: adminData.latitude,
longitude: adminData.longitude,
};
}
}

return null;
return probe.location;
}
}
12 changes: 6 additions & 6 deletions src/lib/adopted-probes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { scopedLogger } from './logger.js';
import type { fetchProbesWithAdminData as serverFetchProbesWithAdminData } from './ws/server.js';
import type { Probe, ProbeLocation } from '../probe/types.js';
import { normalizeFromPublicName } from './geoip/utils.js';
import { getIndex } from '../probe/builder.js';
import { getIndex } from './location/location.js';

const logger = scopedLogger('adopted-probes');

Expand Down Expand Up @@ -96,18 +96,18 @@ export class AdoptedProbes {
return this.adoptedIpToProbe.get(ip);
}

getUpdatedLocation (probe: Probe): ProbeLocation | null {
getUpdatedLocation (probe: Probe): ProbeLocation {
const adoptedProbe = this.getByIp(probe.ipAddress);

if (!adoptedProbe || !adoptedProbe.isCustomCity || adoptedProbe.countryOfCustomCity !== probe.location.country) {
return null;
return probe.location;
}

return {
...probe.location,
city: adoptedProbe.city!,
normalizedCity: normalizeFromPublicName(adoptedProbe.city!),
...(adoptedProbe.state && { state: adoptedProbe.state }),
state: adoptedProbe.state,
latitude: adoptedProbe.latitude!,
longitude: adoptedProbe.longitude!,
};
Expand Down Expand Up @@ -147,9 +147,9 @@ export class AdoptedProbes {

return {
...probe,
location: newLocation || probe.location,
location: newLocation,
tags: newTags,
index: getIndex(newLocation || probe.location, newTags),
index: getIndex(newLocation, newTags),
};
});
}
Expand Down
24 changes: 24 additions & 0 deletions src/lib/location/location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from './countries.js';
import { aliases as networkAliases } from './networks.js';
import { aliases as continentAliases } from './continents.js';
import type { ProbeLocation, Tag } from '../../probe/types.js';

const countryToRegionMap = new Map(_.flatMap(regions, (v, r) => v.map(c => [ c, r ])));

Expand Down Expand Up @@ -95,3 +96,26 @@ export const getRegionAliases = (key: string): string[] => {
return array ?? [];
};

export const getIndex = (location: ProbeLocation, tags: Tag[]) => {
// Storing index as string[][] so every category will have it's exact position in the index array across all probes
const index = [
[ location.country ],
[ getCountryIso3ByIso2(location.country) ],
[ getCountryByIso(location.country) ],
getCountryAliases(location.country),
[ location.normalizedCity ],
location.state ? [ location.state ] : [],
location.state ? [ getStateNameByIso(location.state) ] : [],
[ location.continent ],
getContinentAliases(location.continent),
[ location.region ],
getRegionAliases(location.region),
[ `as${location.asn}` ],
tags.filter(tag => tag.type === 'system').map(tag => tag.value),
[ location.normalizedNetwork ],
getNetworkAliases(location.normalizedNetwork),
].map(category => category.map(s => s.toLowerCase().replaceAll('-', ' ')));

return index;
};

7 changes: 1 addition & 6 deletions src/lib/probe-override.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@ export class ProbeOverride {
getUpdatedLocation (probe: Probe) {
const adminLocation = this.adminData.getUpdatedLocation(probe);
const adoptedLocation = this.adoptedProbes.getUpdatedLocation(probe);

return {
...probe.location,
...adminLocation,
...adoptedLocation,
};
return { ...adminLocation, ...adoptedLocation };
}

addAdminData (probes: Probe[]) {
Expand Down
33 changes: 1 addition & 32 deletions src/probe/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@ import * as process from 'node:process';
import type { Socket } from 'socket.io';
import { isIpPrivate } from '../lib/private-ip.js';
import semver from 'semver';
import {
getStateNameByIso,
getCountryByIso,
getCountryIso3ByIso2,
getCountryAliases,
getNetworkAliases,
getContinentAliases,
getRegionAliases,
} from '../lib/location/location.js';
import { getIndex } from '../lib/location/location.js';
import { ProbeError } from '../lib/probe-error.js';
import { createGeoipClient, LocationInfo } from '../lib/geoip/client.js';
import type GeoipClient from '../lib/geoip/client.js';
Expand Down Expand Up @@ -95,29 +87,6 @@ export const buildProbe = async (socket: Socket): Promise<Probe> => {
};
};

export const getIndex = (location: ProbeLocation, tags: Tag[]) => {
// Storing index as string[][] so every category will have it's exact position in the index array across all probes
const index = [
[ location.country ],
[ getCountryIso3ByIso2(location.country) ],
[ getCountryByIso(location.country) ],
getCountryAliases(location.country),
[ location.normalizedCity ],
location.state ? [ location.state ] : [],
location.state ? [ getStateNameByIso(location.state) ] : [],
[ location.continent ],
getContinentAliases(location.continent),
[ location.region ],
getRegionAliases(location.region),
[ `as${location.asn}` ],
tags.filter(tag => tag.type === 'system').map(tag => tag.value),
[ location.normalizedNetwork ],
getNetworkAliases(location.normalizedNetwork),
].map(category => category.map(s => s.toLowerCase().replaceAll('-', ' ')));

return index;
};

const getLocation = (ipInfo: LocationInfo): ProbeLocation => ({
continent: ipInfo.continent,
region: ipInfo.region,
Expand Down
8 changes: 4 additions & 4 deletions test/tests/unit/adopted-probes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ describe('AdoptedProbes', () => {
});
});

it('getUpdatedLocation method should return null if connected.country !== adopted.countryOfCustomCity', async () => {
it('getUpdatedLocation method should return same location object if connected.country !== adopted.countryOfCustomCity', async () => {
const adoptedProbes = new AdoptedProbes(sqlStub as unknown as Knex, fetchSocketsStub);
selectStub.resolves([{
...defaultAdoptedProbe,
Expand All @@ -407,10 +407,10 @@ describe('AdoptedProbes', () => {

await adoptedProbes.syncDashboardData();
const updatedLocation = adoptedProbes.getUpdatedLocation(defaultConnectedProbe);
expect(updatedLocation).to.equal(null);
expect(updatedLocation).to.equal(defaultConnectedProbe.location);
});

it('getUpdatedLocation method should return null if "isCustomCity: false"', async () => {
it('getUpdatedLocation method should return same location object if "isCustomCity: false"', async () => {
const adoptedProbes = new AdoptedProbes(sqlStub as unknown as Knex, fetchSocketsStub);
selectStub.resolves([{
...defaultAdoptedProbe,
Expand All @@ -422,7 +422,7 @@ describe('AdoptedProbes', () => {

await adoptedProbes.syncDashboardData();
const updatedLocation = adoptedProbes.getUpdatedLocation(defaultConnectedProbe);
expect(updatedLocation).to.equal(null);
expect(updatedLocation).to.equal(defaultConnectedProbe.location);
});

it('getUpdatedTags method should return updated tags', async () => {
Expand Down
28 changes: 17 additions & 11 deletions test/tests/unit/ws/synced-probe-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { Probe } from '../../../../src/probe/types.js';
import { getRegionByCountry } from '../../../../src/lib/location/location.js';
import { getRedisClient } from '../../../../src/lib/redis/client.js';
import { ProbeOverride } from '../../../../src/lib/probe-override.js';
import { AdminData } from '../../../../src/lib/admin-data.js';

describe('SyncedProbeList', () => {
const sandbox = sinon.createSandbox();
Expand Down Expand Up @@ -36,7 +37,9 @@ describe('SyncedProbeList', () => {
} as unknown as WsServerNamespace;

const adoptedProbes = sandbox.createStubInstance(AdoptedProbes);
const probeOverride = new ProbeOverride(adoptedProbes);
const adminData = sandbox.createStubInstance(AdminData);
adminData.locationOverrides = new Map();

Check failure on line 41 in test/tests/unit/ws/synced-probe-list.test.ts

View workflow job for this annotation

GitHub Actions / Run e2e tests

Property 'locationOverrides' is private and only accessible within class 'AdminData'.

Check failure on line 41 in test/tests/unit/ws/synced-probe-list.test.ts

View workflow job for this annotation

GitHub Actions / Run tests

Property 'locationOverrides' is private and only accessible within class 'AdminData'.
const probeOverride = new ProbeOverride(adoptedProbes, adminData);

let syncedProbeList: SyncedProbeList;

Expand All @@ -47,6 +50,9 @@ describe('SyncedProbeList', () => {
localFetchSocketsStub.resolves([]);
adoptedProbes.getUpdatedLocation.callThrough();
adoptedProbes.getUpdatedTags.callThrough();
adoptedProbes.getUpdatedProbes.callThrough();
adminData.getUpdatedLocation.callThrough();
adminData.getUpdatedProbes.callThrough();

syncedProbeList = new SyncedProbeList(redisClient, ioNamespace, probeOverride);
});
Expand All @@ -58,8 +64,8 @@ describe('SyncedProbeList', () => {

it('updates and emits local probes during sync', async () => {
const sockets = [
{ data: { probe: { client: 'A' } } },
{ data: { probe: { client: 'B' } } },
{ data: { probe: { client: 'A', location: {} } } },
{ data: { probe: { client: 'B', location: {} } } },
];

localFetchSocketsStub.resolves(sockets);
Expand Down Expand Up @@ -97,9 +103,9 @@ describe('SyncedProbeList', () => {

it('emits stats in the message on change', async () => {
const sockets = [
{ data: { probe: { client: 'A', stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } } } },
{ data: { probe: { client: 'B', stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } } } },
{ data: { probe: { client: 'C', stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } } } },
{ data: { probe: { client: 'A', location: {}, stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } } } },
{ data: { probe: { client: 'B', location: {}, stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } } } },
{ data: { probe: { client: 'C', location: {}, stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } } } },
];

localFetchSocketsStub.resolves(sockets);
Expand Down Expand Up @@ -191,9 +197,9 @@ describe('SyncedProbeList', () => {

it('reads remote stats updates', async () => {
const probes = {
A: { client: 'A', stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } },
B: { client: 'B', stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } },
C: { client: 'C', stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } },
A: { client: 'A', location: {}, stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } },
B: { client: 'B', location: {}, stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } },
C: { client: 'C', location: {}, stats: { cpu: { count: 1, load: [{ idle: 0, usage: 0 }] }, jobs: { count: 0 } } },
} as unknown as Record<string, Probe>;

redisXRange.resolves([
Expand Down Expand Up @@ -254,8 +260,8 @@ describe('SyncedProbeList', () => {

it('expires remote probes after the timeout', async () => {
const probes = {
A: { client: 'A' },
B: { client: 'B' },
A: { client: 'A', location: {} },
B: { client: 'B', location: {} },
} as unknown as Record<string, Probe>;

redisXRange.resolves([
Expand Down

0 comments on commit 443141e

Please sign in to comment.