From f8171f3beb3f7b452d59810f075cbc4e1974f331 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Wed, 19 Jan 2022 16:49:46 +0000 Subject: [PATCH] update integration test for when run in gh actions - removing and cleaning - next step is to start mocking out a few of the other basic interactions with the client --- clients/validator/jest.config.js | 3 +- clients/validator/src/types.ts | 1 + .../tests/integration/client.int.test.ts | 52 ++--- .../tests/integration/integration.e2e.test.ts | 184 ++++++++++++++++++ .../integration/nym.signing.actions.test.ts | 111 ----------- .../tests/integration/signing.client.test.ts | 55 ++---- .../integration/validator.api.querier.test.ts | 57 +----- clients/validator/tests/test-utils/config.ts | 27 ++- clients/validator/tests/unit/currency.test.ts | 3 +- .../validator/tests/unit/stargate.int.test.ts | 7 +- .../tests/unit/validator.unit.test.ts | 4 +- 11 files changed, 267 insertions(+), 237 deletions(-) create mode 100644 clients/validator/tests/integration/integration.e2e.test.ts delete mode 100644 clients/validator/tests/integration/nym.signing.actions.test.ts diff --git a/clients/validator/jest.config.js b/clients/validator/jest.config.js index 2b4b293c23..224ea5e392 100644 --- a/clients/validator/jest.config.js +++ b/clients/validator/jest.config.js @@ -2,5 +2,6 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - setupFiles: ["dotenv/config"] + setupFiles: ["dotenv/config"], + testTimeout: 20000 }; \ No newline at end of file diff --git a/clients/validator/src/types.ts b/clients/validator/src/types.ts index 9b8dc11b2c..786b72ff6c 100644 --- a/clients/validator/src/types.ts +++ b/clients/validator/src/types.ts @@ -135,6 +135,7 @@ export type MixNode = { sphinx_key: string; identity_key: string; version: string; + profit_margin_percent: number; }; export type GatewayBond = { diff --git a/clients/validator/tests/integration/client.int.test.ts b/clients/validator/tests/integration/client.int.test.ts index d4b2de67df..a2ad0b3b1f 100644 --- a/clients/validator/tests/integration/client.int.test.ts +++ b/clients/validator/tests/integration/client.int.test.ts @@ -16,21 +16,18 @@ beforeEach(async () => { ); }); -//todos -//we want to mock the majority of these tests -//and keep a few integration tests in place - -describe("connect to the nym validator client and perform integration tests against the current testnet", () => { - test("get cached mixnodes", async () => { +describe("perform a few non expensive network calls with the validator client", () => { + test("get all cached mixnodes", async () => { try { const response = await client.getCachedMixnodes(); + //expect all mixnodes to have their owner address response.forEach(mixnodeDetails => { expect(mixnodeDetails.owner).toHaveLength(43) }); } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); @@ -40,53 +37,58 @@ describe("connect to the nym validator client and perform integration tests agai //we expect their balance to be zero, as it's a new account const address = await validatorClient.mnemonicToAddress(mnemonic, config.CURRENCY_PREFIX as string); const response = await client.getBalance(address); + expect(response.amount).toStrictEqual("0"); expect(response.denom).toBe("unymt"); } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); test("get minimium pledge amount for a mixnode", async () => { try { + const response = await client.minimumMixnodePledge(); + expect(response.amount).toBe("100000000"); - expect(response.denom).toBe(config.CURRENCY_PREFIX as string); + expect(response.denom).toBe(config.CURRENCY_PREFIX); } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); test("get minimium gateway pledge amount", async () => { try { const response = await client.minimumGatewayPledge(); + expect(response.amount).toBe("100000000"); expect(response.denom).toBe(config.CURRENCY_PREFIX as string); } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); - test("get current mixnet contract address", () => { + test("ensure the correct mixnet address is being passed", () => { try { - const response = client.mixnetContract; - expect(response).toStrictEqual(config.MIXNET_CONTRACT as string) + //should supply the given value from the client init + const mixnet_contract = client.mixnetContract; + expect(mixnet_contract).toStrictEqual(config.MIXNET_CONTRACT) } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); - test("get current vesting contract address", () => { + test("ensure the correct vesting address is being passed", () => { try { - const response = client.vestingContract; - expect(response).toStrictEqual(config.VESTING_CONTRACT as string) + const vesting_contract = client.vestingContract; + expect(vesting_contract).toStrictEqual(config.VESTING_CONTRACT) } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); }); diff --git a/clients/validator/tests/integration/integration.e2e.test.ts b/clients/validator/tests/integration/integration.e2e.test.ts new file mode 100644 index 0000000000..4a03b6e411 --- /dev/null +++ b/clients/validator/tests/integration/integration.e2e.test.ts @@ -0,0 +1,184 @@ +import validator from "../../src/index"; +import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; +import { Coin } from '@cosmjs/proto-signing'; +import { config } from '../test-utils/config'; +import { Gateway, GatewayOwnershipResponse, MixNode, MixOwnershipResponse } from '../../src/types'; + +let response: ExecuteResult; +let validatorClient: validator; +let ownsMixNode: MixOwnershipResponse; +let ownsGateway: GatewayOwnershipResponse; + +beforeEach(async () => { + validatorClient = await validator.connect( + config.USER_MNEMONIC, + config.NYMD_URL, + config.VALIDATOR_API, + config.CURRENCY_PREFIX, + config.MIXNET_CONTRACT, + config.VESTING_CONTRACT + ); +}); + +describe("long running e2e tests", () => { + test.only("update mixnode profit percentage", async () => { + const nodeIdentity = config.MIXNODE_IDENTITY; + const profitPercent = profitPercentage(); + + try { + //use auto fees - simulated gas + response = await validatorClient.updateMixnodeConfig(nodeIdentity, 'auto', profitPercent); + } + catch (error) { + throw error; + } + try { + ownsMixNode = await validatorClient.client.ownsMixNode(config.MIXNET_CONTRACT, config.USER_WALLET_ADDRESS); + } + catch (error) { + throw error; + } + expect(ownsMixNode.mixnode?.mix_node.profit_margin_percent).toStrictEqual(profitPercent); + }); + + test.only("unbond and bond mixnode", async () => { + + try { + await validatorClient.unbondMixNode("auto", "unbond-mixnode"); + } + catch (error) { + throw error; + } + + const profitPercent = profitPercentage(); + + const mixnodeDetails = { + host: config.MIXNODE_HOST, + mix_port: 1789, + verloc_port: 1790, + http_api_port: 8080, + identity_key: config.MIXNODE_IDENTITY, + sphinx_key: config.MIXNODE_SPHINX_KEY, + version: config.MIXNODE_VERSION, + profit_margin_percent: profitPercent + }; + + const pledgeAmount = { + denom: "unymt", + amount: "100000000" + }; + + try { + response = await validatorClient.bondMixNode( + mixnodeDetails, + config.MIXNODE_SIGNATURE, + pledgeAmount, + "auto" + ); + //see output of events + //remove shortly + response.logs.forEach((log) => { + log.events.forEach((member) => { + console.log(member.attributes); + console.log(member.type); + }); + }); + } + catch (error) { + throw error; + } + + ownsMixNode = await validatorClient.client.ownsMixNode(config.MIXNET_CONTRACT, config.USER_WALLET_ADDRESS); + expect(ownsMixNode.mixnode?.mix_node.profit_margin_percent).toStrictEqual(profitPercent); + }); + + test.skip("unbond and bond gateway", async () => { + //gateway requires different user wallet + //init client inside test + + try { + await validatorClient.unbondGateway("auto", "unbonding gateway"); + } + catch (error) { + throw error; + } + + const gateway = { + host: config.GATEWAY_HOST, + mix_port: 1789, + clients_port: 9000, + version: config.GATEWAY_VERSION, + sphinx_key: config.GATEWAY_SPHINX, + identity_key: config.GATEWAY_IDENTITY, + location: "earth" + }; + + const pledge = pledgeAmount(); + + try { + response = await validatorClient.bondGateway( + gateway, + config.GATEWAY_SIGNATURE, + pledge, + "auto" + ); + } + catch (error) { + throw error; + } + ownsGateway = await validatorClient.client.ownsGateway(config.MIXNET_CONTRACT, config.USER_WALLET_ADDRESS); + expect(ownsGateway.gateway?.bond_amount).toStrictEqual(pledge.amount); + expect(ownsGateway.address).toStrictEqual(config.USER_WALLET_ADDRESS); + }); + + test.only("delegate to mixnode, then undelegate", async () => { + + const pledge = pledgeAmount(); + const getBalance = await validatorClient.getBalance(config.USER_WALLET_ADDRESS); + console.log(getBalance); + + try { + response = await validatorClient.delegateToMixNode( + config.MIXNODE_IDENTITY, + pledge, + "auto" + ); + response.logs.forEach((log) => { + console.log(log.events); + console.log(log.log); + console.log(log.msg_index); + }) + } + catch (error) { + throw error; + } + try { + const unbond = await validatorClient.undelegateFromMixNode( + config.MIXNODE_IDENTITY, + "auto" + ); + + //see output of events + //remove shortly + unbond.logs.forEach((logs) => { + logs.events.forEach((events) => { + console.log(events.type); + console.log(events.attributes); + }) + }); + } catch (error) { + throw error; + } + }); +}); + +const profitPercentage = (): number => { + return Math.floor(Math.random() * 100) + 1; +} + +const pledgeAmount = (): Coin => { + return { + denom: "unymt", + amount: "100000000" + }; +} \ No newline at end of file diff --git a/clients/validator/tests/integration/nym.signing.actions.test.ts b/clients/validator/tests/integration/nym.signing.actions.test.ts deleted file mode 100644 index ca5170e939..0000000000 --- a/clients/validator/tests/integration/nym.signing.actions.test.ts +++ /dev/null @@ -1,111 +0,0 @@ -import SigningClient from '../../src/signing-client'; -import validator from "../../src/index"; -import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; -import { Coin, DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'; -import { config } from '../test-utils/config'; -import { Gateway, MixNode } from '../../src/types'; - -let signingClient: SigningClient; -let mnemonic: string; -let response: ExecuteResult; -let wallet: DirectSecp256k1HdWallet; - -beforeEach(async () => { - if (config.USER_MNEMONIC != undefined) { - mnemonic = config.USER_MNEMONIC as string; - } - else { - mnemonic = validator.randomMnemonic(); - } - - wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic); - - signingClient = await SigningClient.connectWithNymSigner( - wallet, - config.NYMD_URL as string, - config.VALIDATOR_API as string, - config.CURRENCY_PREFIX as string); -}); - -describe("simple actions to simulate a users actions for nym", () => { - test.only("bond mixnode", async () => { - - //provide your mixnode details - // - ownersignature - // - nym wallet address - // - Mixnode model - const nymwalletaddress = "string"; - - const mixnodeDetails = { - host: "1.1.1.1", - mix_port: 1789, - verloc_port: 1790, - http_api_port: 8080, - identity_key: "", - sphinx_key: "", - version: "0.12.1" - } - - const ownerSignature = "some signature"; - - const coin = { - denom: "unymt", - amount: "1000" - }; - - try { - response = await signingClient.bondMixNode( - nymwalletaddress, - mixnodeDetails, - ownerSignature, - coin - ); - //todo - do something - //example = expect(response.logs[0].events[0].type).toStrictEqual("test"); - } - catch (e) { - console.log(e); - } - }); - test.only("bond gateway", async () => { - - //provide your mixnode details - // - ownersignature - // - nym wallet address - // - Gateway model - // - the minimum pledge amount to the gateway - - const nymwalletaddress = "string"; - - const gateway = { - host: "1.1.1.1", - mix_port: 1789, - clients_port: 9000, - version: "0.12.1", - sphinx_key: "", - identity_key: "", - location: "earth" - }; - - const ownerSignature = "some signature"; - - const coin = { - denom: "unymt", - amount: "10000" - }; - - try { - response = await signingClient.bondGateway( - nymwalletaddress, - gateway, - ownerSignature, - coin - ); - //todo - do something - //example = expect(response.logs[0].events[0].type).toStrictEqual("test"); - } - catch (e) { - console.log(e); - } - }); -}); \ No newline at end of file diff --git a/clients/validator/tests/integration/signing.client.test.ts b/clients/validator/tests/integration/signing.client.test.ts index 1e4d145fe7..5403d42bdd 100644 --- a/clients/validator/tests/integration/signing.client.test.ts +++ b/clients/validator/tests/integration/signing.client.test.ts @@ -1,66 +1,49 @@ import SigningClient from '../../src/signing-client'; import validator from "../../src/index"; import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'; -import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'; import { config } from '../test-utils/config'; let cosmWasmClient: CosmWasmClient; -let signingClient: SigningClient; let mnemonic: string; beforeEach(async () => { - cosmWasmClient = await SigningClient.connect(config.NYMD_URL as string); - - mnemonic = validator.randomMnemonic(); - const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic) - signingClient = await SigningClient.connectWithNymSigner( - wallet, - config.NYMD_URL as string, - config.VALIDATOR_API as string, - config.CURRENCY_PREFIX as string); + cosmWasmClient = await SigningClient.connect(config.NYMD_URL); }); -describe("alternate between the signing clients of nym and perform basic requests", () => { - test("retrieve balance using the cosmwasm client", async () => { +describe("peform basic network checks with the cosmwasm client", () => { + test("retrieve a newly created users balance", async () => { try { - const randomAddress = await validator.mnemonicToAddress(mnemonic, config.CURRENCY_PREFIX as string); - const balance = await cosmWasmClient.getBalance(randomAddress, config.CURRENCY_PREFIX as string); - expect(balance.denom).toStrictEqual(config.CURRENCY_PREFIX as string); + const randomAddress = await validator.mnemonicToAddress(mnemonic, config.CURRENCY_PREFIX); + const balance = await cosmWasmClient.getBalance(randomAddress, config.CURRENCY_PREFIX); + + expect(balance.denom).toStrictEqual(config.CURRENCY_PREFIX); expect(balance.amount).toStrictEqual("0"); } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); + test("get the chain id of the network", async () => { try { - //pass these values in environment variables in the future const chainId = await cosmWasmClient.getChainId(); - expect(chainId).toStrictEqual(config.CHAIN_ID as string); + expect(chainId).toStrictEqual(config.CHAIN_ID); } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); - test("get height then search its block", async () => { + + test("get height then search for it by it's block", async () => { try { const height = await cosmWasmClient.getHeight() const block = await cosmWasmClient.getBlock(height); - expect(block.header.chainId).toStrictEqual(config.CHAIN_ID as string); + + expect(block.header.chainId).toStrictEqual(config.CHAIN_ID); expect(block.header.height).toStrictEqual(height); } - catch (e) { - console.log(e); - } - }); - test("get current reward pool", async () => { - try { - //this is due to change due to when rewards get distributed - const rewards = await signingClient.getRewardPool(config.MIXNET_CONTRACT as string); - expect(rewards).toStrictEqual("250000000000000"); - } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); }); \ No newline at end of file diff --git a/clients/validator/tests/integration/validator.api.querier.test.ts b/clients/validator/tests/integration/validator.api.querier.test.ts index 471d96b44e..f3ca59310c 100644 --- a/clients/validator/tests/integration/validator.api.querier.test.ts +++ b/clients/validator/tests/integration/validator.api.querier.test.ts @@ -1,6 +1,5 @@ import ValidatorApiQuerier from '../../src/validator-api-querier'; import { config } from '../test-utils/config'; -import { now, elapsed} from '../test-utils/utils'; let client: ValidatorApiQuerier; @@ -8,62 +7,18 @@ beforeEach(() => { client = new ValidatorApiQuerier(config.VALIDATOR_API as string); }); -//todos -//we want to mock the majority of these tests -//and keep a few integration tests in place - -describe("call out to the validator api and run queries", () => { - test.skip("build client and get all mixnodes", async () => { - try { - //this test was currently ran against a set of prefix data - //this will change - const ownerAddress = "nymt1ydqkmz0ddpvkd3l0vyf8k5xjrqtcnxxvhlpdsr"; - let response = await client.getActiveMixnodes(); - expect(response[0].owner).toStrictEqual(ownerAddress); - } - catch (e) { - console.log(e); - } - }); - +describe("init the validator api querier", () => { test("get rewarded mixnodes", async () => { try { - // we assume that all mixnodes will have their owners address - // also active sets will determine rewarded mixnodes + //all mixnodes will have their owners address let response = await client.getRewardedMixnodes(); - response.forEach(rNode => { - expect(rNode.owner.length).toStrictEqual(43); + response.forEach((Node) => { + expect(Node.owner.length).toStrictEqual(43); }) } - catch (e) { - console.log(e); - } - }); - - test("get cached gateways and it should be six", async () => { - try { - //current gateways running in sandbox-testnet 8 - let response = await client.getCachedGateways(); - expect(response.length).toStrictEqual(8); - } - catch (e) { - console.log(e); - } - }); - - - test("get cached mixnodes", async () => { - try { - const start = now(); - let response = await client.getCachedMixnodes(); - response.forEach(mixnode => { - expect(mixnode.owner.length).toStrictEqual(43); - }) - console.log(elapsed(start, true)); - } - catch (e) { - console.log(e); + catch (error) { + throw error; } }); }); diff --git a/clients/validator/tests/test-utils/config.ts b/clients/validator/tests/test-utils/config.ts index 55599f4e25..1906263afd 100644 --- a/clients/validator/tests/test-utils/config.ts +++ b/clients/validator/tests/test-utils/config.ts @@ -1,10 +1,21 @@ export const config = { - NYMD_URL: process.env.NYMD_URL, - VALIDATOR_API: process.env.VALIDATOR_API, - MIXNET_CONTRACT: process.env.MIXNET_CONTRACT, - VESTING_CONTRACT: process.env.VESTING_CONTRACT, - USER_MNEMONIC: process.env.USER_MNEMONIC, - USER_WALLET_ADDRESS: process.env.USER_WALLET_ADDRESS, - CURRENCY_PREFIX: process.env.CURRENCY_PREFIX, - CHAIN_ID: process.env.CHAIN_ID + NYMD_URL: process.env.NYMD_URL as string, + VALIDATOR_API: process.env.VALIDATOR_API as string, + MIXNET_CONTRACT: process.env.MIXNET_CONTRACT as string, + VESTING_CONTRACT: process.env.VESTING_CONTRACT as string, + USER_MNEMONIC: process.env.USER_MNEMONIC as string, + USER_WALLET_ADDRESS: process.env.USER_WALLET_ADDRESS as string, + CURRENCY_PREFIX: process.env.CURRENCY_PREFIX as string, + CHAIN_ID: process.env.CHAIN_ID as string, + MIXNODE_IDENTITY: process.env.MIXNODE_IDENTITY as string, + MIXNODE_SPHINX_KEY: process.env.MIXNODE_SPHINX_KEY as string, + MIXNODE_SIGNATURE: process.env.MIXNODE_SIGNATURE as string, + MIXNODE_HOST: process.env.MIXNODE_HOST as string, + MIXNODE_VERSION: process.env.MIXNODE_VERSION as string, + GATEWAY_IDENTITY: process.env.GATEWAY_IDENTITY as string, + GATEWAY_SIGNATURE: process.env.GATEWAY_SIGNATURE as string, + GATEWAY_SPHINX: process.env.GATEWAY_SPHINX as string, + GATEWAY_LOCATION: process.env.GATEWAY_LOCATION as string, + GATEWAY_HOST: process.env.GATEWAY_HOST as string, + GATEWAY_VERSION: process.env.GATEWAY_VERSION as string, } diff --git a/clients/validator/tests/unit/currency.test.ts b/clients/validator/tests/unit/currency.test.ts index 1926c3abb4..12d59dc629 100644 --- a/clients/validator/tests/unit/currency.test.ts +++ b/clients/validator/tests/unit/currency.test.ts @@ -1,9 +1,10 @@ const currency = require('../../src/currency'); -describe("provide unit tests around the the currency module", () => { +describe("currency module tests", () => { test.skip("convert to native balance", () => { const decimal = "12.0346"; const value = currency.printableBalanceToNative(decimal); + expect(value).toStrictEqual("12034600"); }); }); diff --git a/clients/validator/tests/unit/stargate.int.test.ts b/clients/validator/tests/unit/stargate.int.test.ts index 8104d41557..17f7debb6b 100644 --- a/clients/validator/tests/unit/stargate.int.test.ts +++ b/clients/validator/tests/unit/stargate.int.test.ts @@ -1,10 +1,11 @@ const stargate = require("../../src/stargate-helper"); import { config } from '../test-utils/config'; -describe("test the stargate functions within the client", () => { - test("test that the gas price is returned correctly", () => { - const nymCurrency = config.CURRENCY_PREFIX as string; +describe("test the stargate functions within the project", () => { + test("gas price is returned correctly", () => { + const nymCurrency = config.CURRENCY_PREFIX; const getGasPrice = stargate.nymGasPrice(nymCurrency); + expect(getGasPrice.denom).toBe(`u${nymCurrency}`); }); diff --git a/clients/validator/tests/unit/validator.unit.test.ts b/clients/validator/tests/unit/validator.unit.test.ts index 0e38bbd67e..264385ad11 100644 --- a/clients/validator/tests/unit/validator.unit.test.ts +++ b/clients/validator/tests/unit/validator.unit.test.ts @@ -1,18 +1,20 @@ import validator from "../../src/index"; import { config } from '../test-utils/config'; -const NETWORK_DENOM = config.CURRENCY_PREFIX as string; +const NETWORK_DENOM = config.CURRENCY_PREFIX; describe("perform basic interactions with the validator", () => { test("build client and get all mixnodes", async () => { const mnemonic = validator.randomMnemonic(); const mnemonicCount = mnemonic.split(" ").length; + expect(mnemonicCount).toStrictEqual(24); }); test("build client and get all mixnodes", async () => { const buildMnemonic = validator.randomMnemonic(); const mnemonic = await validator.mnemonicToAddress(buildMnemonic, NETWORK_DENOM); + expect(mnemonic).toHaveLength(43); expect(mnemonic).toContain(NETWORK_DENOM); });