Browse Source

test(lnd): add additional unit tests

feat/auto-update
jamaljsr 5 years ago
parent
commit
df0f68b94b
  1. 18
      src/lib/bitcoin/bitcoindService.spec.ts
  2. 10
      src/lib/bitcoin/bitcoindService.ts
  3. 22
      src/lib/lnd/lndService.spec.ts
  4. 10
      src/lib/lnd/lndService.ts
  5. 18
      src/store/models/network.spec.ts
  6. 11
      src/store/models/network.ts
  7. 4
      src/utils/async.ts

18
src/lib/bitcoin/bitcoindService.spec.ts

@ -29,4 +29,22 @@ describe('BitcoindService', () => {
expect(BitcoinCore.prototype.generateToAddress).toBeCalledWith(2, 'abcdef');
expect(result[0]).toEqual('blockhash1');
});
describe('waitUntilOnline', () => {
it('should return true when successful', async () => {
BitcoinCore.prototype.getBlockchainInfo = jest
.fn()
.mockReturnValue({ blocks: 123 });
const result = await bitcoindService.waitUntilOnline();
expect(result).toBe(true);
expect(BitcoinCore.prototype.getBlockchainInfo).toBeCalledTimes(1);
});
it('should return false on failure', async () => {
BitcoinCore.prototype.getBlockchainInfo = jest.fn().mockRejectedValue(new Error());
const result = await bitcoindService.waitUntilOnline(18443, 0.5, 1);
expect(result).toBe(false);
expect(BitcoinCore.prototype.getBlockchainInfo).toBeCalledTimes(5);
});
});
});

10
src/lib/bitcoin/bitcoindService.ts

@ -19,7 +19,11 @@ class BitcoindService implements BitcoindLibrary {
return await this.creatClient(port).getWalletInfo();
}
async waitUntilOnline(port?: number) {
async waitUntilOnline(
port?: number,
interval = 3 * 1000, // check every 3 seconds
timeout = 30 * 1000, // timeout after 30 seconds
) {
return waitFor(
async () => {
try {
@ -29,8 +33,8 @@ class BitcoindService implements BitcoindLibrary {
return false;
}
},
2 * 1000, // check every 3 seconds
30 * 1000, // timeout after 30 seconds
interval,
timeout,
);
}

22
src/lib/lnd/lndService.spec.ts

@ -1,7 +1,11 @@
import { IpcSender } from 'lib/ipc/ipcService';
import { getNetwork } from 'utils/tests';
// import * as asyncUtil from 'utils/async';
import lndService from './lndService';
// jest.mock('utils/async');
// const asyncUtilMock = asyncUtil as jest.Mocked<typeof asyncUtil>;
describe('LndService', () => {
const node = getNetwork().nodes.lightning[0];
let actualIpc: IpcSender;
@ -21,4 +25,22 @@ describe('LndService', () => {
lndService.getInfo(node);
expect(lndService.ipc).toBeCalledWith('get-info', { node });
});
describe('waitUntilOnline', () => {
it('should return true when successful', async () => {
const ipc = lndService.ipc as jest.Mock;
ipc.mockResolvedValue({});
const result = await lndService.waitUntilOnline(node);
expect(result).toBe(true);
expect(ipc).toBeCalledTimes(1);
});
it('should return false on failure', async () => {
const ipc = lndService.ipc as jest.Mock;
ipc.mockRejectedValue(new Error());
const result = await lndService.waitUntilOnline(node, 0.5, 1);
expect(result).toBe(false);
expect(ipc).toBeCalledTimes(5);
});
});
});

10
src/lib/lnd/lndService.ts

@ -14,7 +14,11 @@ class LndService implements LndLibrary {
return await this.ipc('get-info', { node });
}
async waitUntilOnline(node: LndNode): Promise<boolean> {
async waitUntilOnline(
node: LndNode,
interval = 3 * 1000, // check every 3 seconds
timeout = 30 * 1000, // timeout after 30 seconds
): Promise<boolean> {
return waitFor(
async () => {
try {
@ -24,8 +28,8 @@ class LndService implements LndLibrary {
return false;
}
},
3 * 1000, // check every 3 seconds
30 * 1000, // timeout after 30 seconds
interval,
timeout,
);
}
}

18
src/store/models/network.spec.ts

@ -178,6 +178,24 @@ describe('Network model', () => {
await start(network.id);
expect(injections.dockerService.start).toBeCalledWith(network);
});
it('should set LND node status to error if the node startup fails', async () => {
lndServiceMock.waitUntilOnline.mockResolvedValue(false);
const { start } = store.getActions().network;
const network = firstNetwork();
await start(network.id);
const { lightning } = firstNetwork().nodes;
lightning.forEach(node => expect(node.status).toBe(Status.Error));
});
it('should set bitcoind node status to error if the node startup fails', async () => {
bitcoindServiceMock.waitUntilOnline.mockResolvedValue(false);
const { start } = store.getActions().network;
const network = firstNetwork();
await start(network.id);
const { bitcoin } = firstNetwork().nodes;
bitcoin.forEach(node => expect(node.status).toBe(Status.Error));
});
});
describe('Stopping', () => {

11
src/store/models/network.ts

@ -17,7 +17,6 @@ export interface NetworkModel {
networks: Network[];
loaded: boolean;
networkById: Computed<NetworkModel, (id?: string | number) => Network>;
allStatuses: Computed<NetworkModel, (id?: number) => Status[]>;
setNetworks: Action<NetworkModel, Network[]>;
setLoaded: Action<NetworkModel, boolean>;
load: Thunk<NetworkModel, any, StoreInjections, RootModel, Promise<void>>;
@ -52,16 +51,6 @@ const networkModel: NetworkModel = {
}
return network;
}),
allStatuses: computed(state => (id?: string | number) => {
const network = state.networks.find(n => n.id === id);
if (!network) {
throw new Error(`Network with the id '${id}' was not found.`);
}
return [network.status].concat(
network.nodes.bitcoin.map(n => n.status),
network.nodes.lightning.map(n => n.status),
);
}),
// reducer actions (mutations allowed thx to immer)
setNetworks: action((state, networks) => {
state.networks = networks;

4
src/utils/async.ts

@ -9,11 +9,11 @@ export const waitFor = async (
interval = 500,
timeout = 5000,
): Promise<boolean> => {
// if the file already exists, then return immediately
// if the condition is true, then return immediately
if (await conditionFunc()) {
return Promise.resolve(true);
}
// return a promise that will resolve when the file exists
// return a promise that will resolve when the condition is true
return new Promise(resolve => {
// keep a countdown of the number of times to check
// so it can abort after a the timeout expires

Loading…
Cancel
Save