Browse Source

network-tests: run tests for all workgroups

Mokhtar Naamani 4 years ago
parent
commit
de51bf6ed1

+ 1 - 1
README.md

@@ -109,7 +109,7 @@ A step by step guide to setup a full node and validator on the Joystream testnet
 
 ```bash
 docker-compose up -d
-yarn workspace network-tests test
+DEBUG=* yarn workspace network-tests scenario-full
 docker-compose down
 ```
 

+ 1 - 1
docker-compose-with-storage.yml

@@ -24,7 +24,7 @@ services:
       - '127.0.0.1:9944:9944'
     volumes:
       - chain-data:/data
-    command: --dev --ws-external --base-path /data
+    command: --dev --ws-external --base-path /data --log runtime
 volumes:
   ipfs-data:
     driver: local

+ 1 - 1
docker-compose.yml

@@ -11,7 +11,7 @@ services:
       # dockerfile is relative to the context
       dockerfile: joystream-node.Dockerfile
     container_name: joystream-node
-    command: --dev --alice --validator --unsafe-ws-external --rpc-cors=all
+    command: --dev --alice --validator --unsafe-ws-external --rpc-cors=all --log runtime
     ports:
       - "9944:9944"
   

+ 1 - 1
tests/network-tests/package.json

@@ -5,7 +5,7 @@
   "scripts": {
     "build": "tsc --noEmit",
     "run-tests": "./run-tests.sh",
-    "scenario-full": "yarn db-path-setup && ts-node src/scenarios/full.ts",
+    "scenario-full": "yarn db-path-setup && node -r ts-node/register --unhandled-rejections=strict src/scenarios/full.ts",
     "lint": "eslint . --quiet --ext .ts",
     "checks": "tsc --noEmit --pretty && prettier ./ --check && yarn lint",
     "format": "prettier ./ --write ",

+ 1 - 0
tests/network-tests/run-tests.sh

@@ -50,6 +50,7 @@ CONTAINER_ID=`docker run -d -v ${DATA_PATH}:/data -p 9944:9944 joystream/node \
   --chain /data/chain-spec-raw.json`
 
 function cleanup() {
+    docker logs ${CONTAINER_ID} --tail 30
     docker stop ${CONTAINER_ID}
     docker rm ${CONTAINER_ID}
 }

+ 28 - 11
tests/network-tests/src/Api.ts

@@ -28,9 +28,12 @@ import {
   OpeningId,
 } from '@joystream/types/hiring'
 import { FillOpeningParameters, ProposalId } from '@joystream/types/proposals'
+import Debugger from 'debug'
+const debug = Debugger('api')
 
 export enum WorkingGroups {
   StorageWorkingGroup = 'storageWorkingGroup',
+  ContentDirectoryWorkingGroup = 'contentDirectoryWorkingGroup',
 }
 
 export class Api {
@@ -38,18 +41,29 @@ export class Api {
   private readonly sender: Sender
 
   public static async create(provider: WsProvider): Promise<Api> {
-    const api = await ApiPromise.create({ provider, types })
-
-    // Wait for api to be connected and ready
-    await api.isReady
-
-    // If a node was just started up it might take a few seconds to start producing blocks
-    // Give it a few seconds to be ready.
-    await new Promise((resolve) => {
-      setTimeout(resolve, 5000)
-    })
+    let connectAttempts = 0
+    while (true) {
+      connectAttempts++
+      debug(`Connecting to chain attempt ${connectAttempts}..`)
+      try {
+        const api = await ApiPromise.create({ provider, types })
+
+        // Wait for api to be connected and ready
+        await api.isReady
+
+        // If a node was just started up it might take a few seconds to start producing blocks
+        // Give it a few seconds to be ready.
+        await Utils.wait(5000)
+
+        return new Api(api)
+      } catch (err) {
+        if (connectAttempts === 3) {
+          throw new Error('Unable to connect to chain')
+        }
+      }
 
-    return new Api(api)
+      await Utils.wait(5000)
+    }
   }
 
   constructor(api: ApiPromise) {
@@ -61,10 +75,13 @@ export class Api {
     this.api.disconnect()
   }
 
+  // Well known WorkingGroup enum defined in runtime
   public getWorkingGroupString(workingGroup: WorkingGroups): string {
     switch (workingGroup) {
       case WorkingGroups.StorageWorkingGroup:
         return 'Storage'
+      case WorkingGroups.ContentDirectoryWorkingGroup:
+        return 'Content'
       default:
         throw new Error(`Invalid working group string representation: ${workingGroup}`)
     }

+ 3 - 3
tests/network-tests/src/flows/leaderSetup.ts

@@ -8,7 +8,7 @@ import { DbService } from '../DbService'
 import { LeaderHiringHappyCaseFixture } from '../fixtures/leaderHiringHappyCase'
 
 // Worker application happy case scenario
-export default async function leaderSetup(api: Api, env: NodeJS.ProcessEnv, db: DbService) {
+export default async function leaderSetup(api: Api, env: NodeJS.ProcessEnv, db: DbService, group: WorkingGroups) {
   const sudoUri: string = env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
   if (db.hasLeader(api.getWorkingGroupString(WorkingGroups.StorageWorkingGroup))) {
@@ -43,10 +43,10 @@ export default async function leaderSetup(api: Api, env: NodeJS.ProcessEnv, db:
     rewardInterval,
     firstRewardInterval,
     payoutAmount,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   await leaderHiringHappyCaseFixture.runner(false)
 
   db.setMembers(nKeyPairs)
-  db.setLeader(leadKeyPair[0], api.getWorkingGroupString(WorkingGroups.StorageWorkingGroup))
+  db.setLeader(leadKeyPair[0], api.getWorkingGroupString(group))
 }

+ 12 - 20
tests/network-tests/src/flows/proposals/manageLeaderRole.ts

@@ -30,7 +30,7 @@ import { ProposalId } from '@joystream/types/proposals'
 import { DbService } from '../../DbService'
 import { CouncilElectionHappyCaseFixture } from '../../fixtures/councilElectionHappyCase'
 
-export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv, db: DbService) {
+export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv, db: DbService, group: WorkingGroups) {
   const sudoUri: string = env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
   const sudo: KeyringPair = keyring.addFromUri(sudoUri)
@@ -117,7 +117,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
       applicationStake,
       roleStake,
       expectLeadOpeningAddedFixture.getCreatedOpeningId() as OpeningId,
-      WorkingGroups.StorageWorkingGroup
+      group
     )
     await applyForLeaderOpeningFixture.runner(false)
   })()
@@ -158,7 +158,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
     rewardInterval,
     payoutAmount,
     expectLeadOpeningAddedFixture.getCreatedOpeningId() as OpeningId,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Propose fill leader opening
   await fillLeaderOpeningProposalFixture.runner(false)
@@ -169,11 +169,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
     sudo,
     fillLeaderOpeningProposalFixture.getCreatedProposalId() as ProposalId
   )
-  const expectLeaderSetFixture: ExpectLeaderSetFixture = new ExpectLeaderSetFixture(
-    api,
-    leadKeyPair[0].address,
-    WorkingGroups.StorageWorkingGroup
-  )
+  const expectLeaderSetFixture: ExpectLeaderSetFixture = new ExpectLeaderSetFixture(api, leadKeyPair[0].address, group)
   // Approve fill leader opening
   voteForFillLeaderProposalFixture.runner(false)
   await expectLeaderSetFixture.runner(false)
@@ -183,7 +179,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
     m1KeyPairs,
     sudo,
     alteredPayoutAmount,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Propose leader reward
   await setLeaderRewardProposalFixture.runner(false)
@@ -197,7 +193,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
   const expectLeaderRewardAmountUpdatedFixture: ExpectLeaderRewardAmountUpdatedFixture = new ExpectLeaderRewardAmountUpdatedFixture(
     api,
     alteredPayoutAmount,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Approve new leader reward
   voteForeLeaderRewardFixture.runner(false)
@@ -208,7 +204,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
     m1KeyPairs,
     sudo,
     stakeDecrement,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
 
   // Propose decrease stake
@@ -226,11 +222,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
       decreaseLeaderStakeProposalFixture.getCreatedProposalId() as ProposalId
     )
     voteForDecreaseStakeProposal.runner(false)
-    expectLeaderStakeDecreasedFixture = new ExpectLeaderStakeDecreasedFixture(
-      api,
-      newStake,
-      WorkingGroups.StorageWorkingGroup
-    )
+    expectLeaderStakeDecreasedFixture = new ExpectLeaderStakeDecreasedFixture(api, newStake, group)
     await expectLeaderStakeDecreasedFixture.runner(false)
   })()
 
@@ -239,7 +231,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
     m1KeyPairs,
     sudo,
     slashAmount,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Propose leader slash
   await slashLeaderProposalFixture.runner(false)
@@ -256,7 +248,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
       slashLeaderProposalFixture.getCreatedProposalId() as ProposalId
     )
     voteForSlashProposalFixture.runner(false)
-    expectLeaderSlashedFixture = new ExpectLeaderSlashedFixture(api, newStake, WorkingGroups.StorageWorkingGroup)
+    expectLeaderSlashedFixture = new ExpectLeaderSlashedFixture(api, newStake, group)
     await expectLeaderSlashedFixture.runner(false)
   })()
 
@@ -266,7 +258,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
     leadKeyPair[0].address,
     sudo,
     false,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Propose terminate leader role
   await terminateLeaderRoleProposalFixture.runner(false)
@@ -274,7 +266,7 @@ export default async function manageLeaderRole(api: Api, env: NodeJS.ProcessEnv,
   let voteForLeaderRoleTerminationFixture: VoteForProposalFixture
   const expectLeaderRoleTerminatedFixture: ExpectLeaderRoleTerminatedFixture = new ExpectLeaderRoleTerminatedFixture(
     api,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Approve leader role termination
   await (async () => {

+ 8 - 5
tests/network-tests/src/flows/proposals/workingGroupMintCapacityProposal.ts

@@ -10,7 +10,12 @@ import { ProposalId } from '@joystream/types/proposals'
 import { CouncilElectionHappyCaseFixture } from '../../fixtures/councilElectionHappyCase'
 import { DbService } from '../../DbService'
 
-export default async function workingGroupMintCapactiy(api: Api, env: NodeJS.ProcessEnv, db: DbService) {
+export default async function workingGroupMintCapactiy(
+  api: Api,
+  env: NodeJS.ProcessEnv,
+  db: DbService,
+  group: WorkingGroups
+) {
   const sudoUri: string = env.SUDO_ACCOUNT_URI!
   const keyring = new Keyring({ type: 'sr25519' })
   const sudo: KeyringPair = keyring.addFromUri(sudoUri)
@@ -45,15 +50,13 @@ export default async function workingGroupMintCapactiy(api: Api, env: NodeJS.Pro
     await councilElectionHappyCaseFixture.runner(false)
   }
 
-  const newMintCapacity: BN = (await api.getWorkingGroupMintCapacity(WorkingGroups.StorageWorkingGroup)).add(
-    mintCapacityIncrement
-  )
+  const newMintCapacity: BN = (await api.getWorkingGroupMintCapacity(group)).add(mintCapacityIncrement)
   const workingGroupMintCapacityProposalFixture: WorkingGroupMintCapacityProposalFixture = new WorkingGroupMintCapacityProposalFixture(
     api,
     m1KeyPairs,
     sudo,
     newMintCapacity,
-    WorkingGroups.StorageWorkingGroup
+    group
   )
   // Propose mint capacity
   await workingGroupMintCapacityProposalFixture.runner(false)

+ 16 - 8
tests/network-tests/src/scenarios/full.ts

@@ -1,5 +1,5 @@
 import { WsProvider } from '@polkadot/api'
-import { Api } from '../Api'
+import { Api, WorkingGroups } from '../Api'
 import { DbService } from '../DbService'
 import { config } from 'dotenv'
 import Debugger from 'debug'
@@ -56,18 +56,26 @@ const scenario = async () => {
   debug('Validator Count Proposal')
   await validatorCountProposal(api, env, db)
 
-  debug('Working Group Mint Capacity Proposal')
-  await workingGroupMintCapacityProposal(api, env, db)
+  debug('Working Group (Storage) Mint Capacity Proposal')
+  await workingGroupMintCapacityProposal(api, env, db, WorkingGroups.StorageWorkingGroup)
+
+  debug('Working Group (Content) Mint Capacity Proposal')
+  await workingGroupMintCapacityProposal(api, env, db, WorkingGroups.ContentDirectoryWorkingGroup)
 
   // Leads are fired at the end of the scenarios
-  debug('Lead Role Proposals')
-  await manageLeaderRole(api, env, db /*, storage group */)
-  // await manageLeaderRole(api, env, db /*, content group */)
+  debug('Lead Role (Storage) Proposals')
+  await manageLeaderRole(api, env, db, WorkingGroups.StorageWorkingGroup)
+
+  debug('Lead Role (Content) Proposals')
+  await manageLeaderRole(api, env, db, WorkingGroups.ContentDirectoryWorkingGroup)
 
   /* workers tests */
 
-  debug('Lead Setup')
-  await leaderSetup(api, env, db) /* storage */
+  debug('Lead Setup (Storage)')
+  await leaderSetup(api, env, db, WorkingGroups.StorageWorkingGroup)
+
+  debug('Lead Setup (Content)')
+  await leaderSetup(api, env, db, WorkingGroups.ContentDirectoryWorkingGroup)
 
   debug('Worker Tests')
   await atLeastValueBug(api, env, db)

+ 1 - 0
types/src/common.ts

@@ -98,6 +98,7 @@ export class InputValidationLengthConstraint extends JoyStructDecorated({ min: u
 
 export const WorkingGroupDef = {
   Storage: Null,
+  Content: Null,
 } as const
 export type WorkingGroupKey = keyof typeof WorkingGroupDef
 export class WorkingGroup extends JoyEnum(WorkingGroupDef) {}