You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			197 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			197 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			TypeScript
		
	
// tslint:disable: no-implicit-dependencies max-func-body-length no-unused-expression
 | 
						|
 | 
						|
import chai from 'chai';
 | 
						|
import * as sinon from 'sinon';
 | 
						|
import _ from 'lodash';
 | 
						|
import { describe } from 'mocha';
 | 
						|
 | 
						|
import { TestUtils } from '../../../test-utils';
 | 
						|
import { Onions, SnodePool } from '../../../../session/apis/snode_api';
 | 
						|
import * as Data from '../../../../data/data';
 | 
						|
 | 
						|
import chaiAsPromised from 'chai-as-promised';
 | 
						|
import * as OnionPaths from '../../../../session/onions/onionPath';
 | 
						|
import { generateFakeSnodes, generateFakeSnodeWithEdKey } from '../../../test-utils/utils';
 | 
						|
import { SeedNodeAPI } from '../../../../session/apis/seed_node_api';
 | 
						|
chai.use(chaiAsPromised as any);
 | 
						|
chai.should();
 | 
						|
 | 
						|
const { expect } = chai;
 | 
						|
 | 
						|
const guard1ed = 'e3ec6fcc79e64c2af6a48a9865d4bf4b739ec7708d75f35acc3d478f9161534e';
 | 
						|
const guard2ed = 'e3ec6fcc79e64c2af6a48a9865d4bf4b739ec7708d75f35acc3d478f91615349';
 | 
						|
const guard3ed = 'e3ec6fcc79e64c2af6a48a9865d4bf4b739ec7708d75f35acc3d478f9161534a';
 | 
						|
 | 
						|
const fakeSnodePool: Array<Data.Snode> = [
 | 
						|
  ...generateFakeSnodes(12),
 | 
						|
  generateFakeSnodeWithEdKey(guard1ed),
 | 
						|
  generateFakeSnodeWithEdKey(guard2ed),
 | 
						|
  generateFakeSnodeWithEdKey(guard3ed),
 | 
						|
  ...generateFakeSnodes(3),
 | 
						|
];
 | 
						|
 | 
						|
// tslint:disable: variable-name
 | 
						|
 | 
						|
// tslint:disable-next-line: max-func-body-length
 | 
						|
describe('GuardNodes', () => {
 | 
						|
  // Initialize new stubbed cache
 | 
						|
  const sandbox = sinon.createSandbox();
 | 
						|
  let getSnodePoolFromDBOrFetchFromSeed: sinon.SinonStub;
 | 
						|
  let fetchFromSeedWithRetriesAndWriteToDb: sinon.SinonStub;
 | 
						|
  describe('selectGuardNodes', () => {
 | 
						|
    beforeEach(() => {
 | 
						|
      OnionPaths.clearTestOnionPath();
 | 
						|
 | 
						|
      TestUtils.stubWindowLog();
 | 
						|
      TestUtils.stubWindow('getGlobalOnlineStatus', () => true);
 | 
						|
 | 
						|
      Onions.resetSnodeFailureCount();
 | 
						|
      OnionPaths.resetPathFailureCount();
 | 
						|
      SnodePool.TEST_resetState();
 | 
						|
    });
 | 
						|
 | 
						|
    afterEach(() => {
 | 
						|
      TestUtils.restoreStubs();
 | 
						|
      sandbox.restore();
 | 
						|
    });
 | 
						|
 | 
						|
    it('does not fetch from seed if we got 12 or more snodes in the db', async () => {
 | 
						|
      sandbox.stub(Data, 'getSnodePoolFromDb').resolves(fakeSnodePool);
 | 
						|
 | 
						|
      getSnodePoolFromDBOrFetchFromSeed = sandbox
 | 
						|
        .stub(SnodePool, 'getSnodePoolFromDBOrFetchFromSeed')
 | 
						|
        .callThrough();
 | 
						|
      fetchFromSeedWithRetriesAndWriteToDb = sandbox
 | 
						|
        .stub(SnodePool, 'TEST_fetchFromSeedWithRetriesAndWriteToDb')
 | 
						|
        .resolves();
 | 
						|
      const testGuardNode = sandbox.stub(OnionPaths, 'TEST_testGuardNode').resolves(true);
 | 
						|
 | 
						|
      sandbox.stub(Data, 'updateGuardNodes').resolves();
 | 
						|
      // run the command
 | 
						|
      const fetchedGuardNodes = await OnionPaths.selectGuardNodes();
 | 
						|
 | 
						|
      expect(
 | 
						|
        getSnodePoolFromDBOrFetchFromSeed.callCount,
 | 
						|
        'getSnodePoolFromDBOrFetchFromSeed should have been called'
 | 
						|
      ).to.be.eq(1);
 | 
						|
      expect(
 | 
						|
        fetchFromSeedWithRetriesAndWriteToDb.callCount,
 | 
						|
        'fetchFromSeedWithRetriesAndWriteToDb should not have been called'
 | 
						|
      ).to.be.eq(0);
 | 
						|
      expect(
 | 
						|
        testGuardNode.callCount,
 | 
						|
        'firstGuardNode should have been called three times'
 | 
						|
      ).to.be.eq(3);
 | 
						|
      const firstGuardNode = testGuardNode.firstCall.args[0];
 | 
						|
      const secondGuardNode = testGuardNode.secondCall.args[0];
 | 
						|
      const thirdGuardNode = testGuardNode.thirdCall.args[0];
 | 
						|
      expect(fetchedGuardNodes).to.deep.equal([firstGuardNode, secondGuardNode, thirdGuardNode]);
 | 
						|
    });
 | 
						|
 | 
						|
    it('throws an error if we got enough snodes in the db but none test passes', async () => {
 | 
						|
      sandbox.stub(Data, 'getSnodePoolFromDb').resolves(fakeSnodePool);
 | 
						|
 | 
						|
      getSnodePoolFromDBOrFetchFromSeed = sandbox
 | 
						|
        .stub(SnodePool, 'getSnodePoolFromDBOrFetchFromSeed')
 | 
						|
        .callThrough();
 | 
						|
      fetchFromSeedWithRetriesAndWriteToDb = sandbox
 | 
						|
        .stub(SnodePool, 'TEST_fetchFromSeedWithRetriesAndWriteToDb')
 | 
						|
        .resolves();
 | 
						|
      const testGuardNode = sandbox.stub(OnionPaths, 'TEST_testGuardNode').resolves(false);
 | 
						|
 | 
						|
      sandbox.stub(Data, 'updateGuardNodes').resolves();
 | 
						|
      // run the command
 | 
						|
      let throwedError: string | undefined;
 | 
						|
      try {
 | 
						|
        await OnionPaths.selectGuardNodes();
 | 
						|
      } catch (e) {
 | 
						|
        throwedError = e.message;
 | 
						|
      }
 | 
						|
 | 
						|
      expect(
 | 
						|
        getSnodePoolFromDBOrFetchFromSeed.callCount,
 | 
						|
        'getSnodePoolFromDBOrFetchFromSeed should have been called'
 | 
						|
      ).to.be.eq(1);
 | 
						|
      expect(
 | 
						|
        fetchFromSeedWithRetriesAndWriteToDb.callCount,
 | 
						|
        'fetchFromSeedWithRetriesAndWriteToDb should not have been called'
 | 
						|
      ).to.be.eq(0);
 | 
						|
      expect(
 | 
						|
        testGuardNode.callCount,
 | 
						|
        'firstGuardNode should have been called three times'
 | 
						|
      ).to.be.eq(18);
 | 
						|
      expect(throwedError).to.be.equal('selectGuardNodes stopping after attempts: 6');
 | 
						|
    });
 | 
						|
 | 
						|
    it('throws an error if we have to fetch from seed, fetch from seed enough snode but we still fail', async () => {
 | 
						|
      const invalidSndodePool = fakeSnodePool.slice(0, 11);
 | 
						|
      sandbox.stub(Data, 'getSnodePoolFromDb').resolves(invalidSndodePool);
 | 
						|
      TestUtils.stubWindow('getSeedNodeList', () => [{ url: 'whatever' }]);
 | 
						|
 | 
						|
      getSnodePoolFromDBOrFetchFromSeed = sandbox
 | 
						|
        .stub(SnodePool, 'getSnodePoolFromDBOrFetchFromSeed')
 | 
						|
        .callThrough();
 | 
						|
      fetchFromSeedWithRetriesAndWriteToDb = sandbox
 | 
						|
        .stub(SeedNodeAPI, 'fetchSnodePoolFromSeedNodeWithRetries')
 | 
						|
        .resolves(fakeSnodePool);
 | 
						|
 | 
						|
      sandbox.stub(Data, 'updateGuardNodes').resolves();
 | 
						|
      // run the command
 | 
						|
      let throwedError: string | undefined;
 | 
						|
      try {
 | 
						|
        await OnionPaths.selectGuardNodes();
 | 
						|
      } catch (e) {
 | 
						|
        throwedError = e.message;
 | 
						|
      }
 | 
						|
 | 
						|
      expect(throwedError).to.be.equal('selectGuardNodes stopping after attempts: 6');
 | 
						|
    });
 | 
						|
 | 
						|
    it('returns valid guardnode if we have to fetch from seed, fetch from seed enough snodes but guard node tests passes', async () => {
 | 
						|
      const invalidSndodePool = fakeSnodePool.slice(0, 11);
 | 
						|
      sandbox.stub(Data, 'getSnodePoolFromDb').resolves(invalidSndodePool);
 | 
						|
      TestUtils.stubWindow('getSeedNodeList', () => [{ url: 'whatever' }]);
 | 
						|
      const testGuardNode = sandbox.stub(OnionPaths, 'TEST_testGuardNode').resolves(true);
 | 
						|
 | 
						|
      getSnodePoolFromDBOrFetchFromSeed = sandbox
 | 
						|
        .stub(SnodePool, 'getSnodePoolFromDBOrFetchFromSeed')
 | 
						|
        .callThrough();
 | 
						|
      fetchFromSeedWithRetriesAndWriteToDb = sandbox
 | 
						|
        .stub(SeedNodeAPI, 'fetchSnodePoolFromSeedNodeWithRetries')
 | 
						|
        .resolves(fakeSnodePool);
 | 
						|
 | 
						|
      sandbox.stub(Data, 'updateGuardNodes').resolves();
 | 
						|
      // run the command
 | 
						|
      const guardNodes = await OnionPaths.selectGuardNodes();
 | 
						|
 | 
						|
      expect(guardNodes.length).to.be.equal(3);
 | 
						|
      expect(testGuardNode.callCount).to.be.equal(3);
 | 
						|
    });
 | 
						|
 | 
						|
    it('throws if we have to fetch from seed, fetch from seed but not have enough fetched snodes', async () => {
 | 
						|
      const invalidSndodePool = fakeSnodePool.slice(0, 11);
 | 
						|
      sandbox.stub(Data, 'getSnodePoolFromDb').resolves(invalidSndodePool);
 | 
						|
      TestUtils.stubWindow('getSeedNodeList', () => [{ url: 'whatever' }]);
 | 
						|
 | 
						|
      getSnodePoolFromDBOrFetchFromSeed = sandbox
 | 
						|
        .stub(SnodePool, 'getSnodePoolFromDBOrFetchFromSeed')
 | 
						|
        .callThrough();
 | 
						|
      fetchFromSeedWithRetriesAndWriteToDb = sandbox
 | 
						|
        .stub(SeedNodeAPI, 'fetchSnodePoolFromSeedNodeWithRetries')
 | 
						|
        .resolves(invalidSndodePool);
 | 
						|
 | 
						|
      sandbox.stub(Data, 'updateGuardNodes').resolves();
 | 
						|
      // run the command
 | 
						|
      let throwedError: string | undefined;
 | 
						|
      try {
 | 
						|
        await OnionPaths.selectGuardNodes();
 | 
						|
      } catch (e) {
 | 
						|
        throwedError = e.message;
 | 
						|
      }
 | 
						|
      expect(throwedError).to.be.equal(
 | 
						|
        'Could not select guard nodes. Not enough nodes in the pool: 11'
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
});
 |