From 19137d007b9e3c3e9773c8ccb553df174abd3af8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 3 Apr 2018 13:15:27 +0200 Subject: [PATCH] Cleanup testcases, refine to the error of concern --- x/stake/pool_test.go | 125 +++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 57 deletions(-) diff --git a/x/stake/pool_test.go b/x/stake/pool_test.go index dd5774f8c5..0c49de6d98 100644 --- a/x/stake/pool_test.go +++ b/x/stake/pool_test.go @@ -222,7 +222,7 @@ func randomSetup(r *rand.Rand, numCandidates int) (Pool, Candidates) { if candidate.Status == Bonded { pool.BondedShares = pool.BondedShares.Add(candidate.Assets) pool.BondedPool += candidate.Assets.Evaluate() - } else { + } else if candidate.Status == Unbonded { pool.UnbondedShares = pool.UnbondedShares.Add(candidate.Assets) pool.UnbondedPool += candidate.Assets.Evaluate() } @@ -235,60 +235,53 @@ func randomTokens(r *rand.Rand) int64 { return int64(r.Int31n(10000)) } -// operation that transforms staking state -type Operation func(p Pool, c Candidate) (Pool, Candidate, int64, string) +// any operation that transforms staking state +type Operation func(r *rand.Rand, p Pool, c Candidate) (Pool, Candidate, int64, string) + +// operation: bond or unbond a candidate depending on current status +func BondOrUnbond(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) { + var msg string + if cand.Status == Bonded { + msg = fmt.Sprintf("Unbonded previously bonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)", + cand.Address, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + p, cand = p.bondedToUnbondedPool(cand) + } else if cand.Status == Unbonded { + msg = fmt.Sprintf("Bonded previously unbonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)", + cand.Address, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + p, cand = p.unbondedToBondedPool(cand) + } + return p, cand, 0, msg +} + +// operation: add a random number of tokens to a candidate +func AddTokens(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) { + tokens := int64(r.Int31n(1000)) + msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", + cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + p, cand, _ = p.candidateAddTokens(cand, tokens) + msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) + return p, cand, -1 * tokens, msg // tokens are removed so for accounting must be negative +} + +// operation: remove a random number of shares from a candidate +func RemoveShares(r *rand.Rand, p Pool, cand Candidate) (Pool, Candidate, int64, string) { + shares := sdk.NewRat(int64(r.Int31n(1000))) + if shares.GT(cand.Liabilities) { + shares = cand.Liabilities.Quo(sdk.NewRat(2)) + } + msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", + cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) + p, cand, tokens := p.candidateRemoveShares(cand, shares) + msg = fmt.Sprintf("Removed %d shares from %s", shares.Evaluate(), msg) + return p, cand, tokens, msg +} // pick a random staking operation func randomOperation(r *rand.Rand) Operation { operations := []Operation{ - - // bond/unbond - func(p Pool, cand Candidate) (Pool, Candidate, int64, string) { - - var msg string - if cand.Status == Bonded { - msg = fmt.Sprintf("Unbonded previously bonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) - p, cand = p.bondedToUnbondedPool(cand) - } else if cand.Status == Unbonded { - msg = fmt.Sprintf("Bonded previously unbonded candidate %s (assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) - p, cand = p.unbondedToBondedPool(cand) - } - return p, cand, 0, msg - }, - - // add some tokens to a candidate - func(p Pool, cand Candidate) (Pool, Candidate, int64, string) { - - tokens := int64(r.Int31n(1000)) - - msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) - - p, cand, _ = p.candidateAddTokens(cand, tokens) - - msg = fmt.Sprintf("Added %d tokens to %s", tokens, msg) - return p, cand, -1 * tokens, msg // tokens are removed so for accounting must be negative - }, - - // remove some shares from a candidate - func(p Pool, cand Candidate) (Pool, Candidate, int64, string) { - - shares := sdk.NewRat(int64(r.Int31n(1000))) - - if shares.GT(cand.Liabilities) { - shares = cand.Liabilities.Quo(sdk.NewRat(2)) - } - - msg := fmt.Sprintf("candidate %s (status: %d, assets: %v, liabilities: %v, delegatorShareExRate: %v)", - cand.Address, cand.Status, cand.Assets, cand.Liabilities, cand.delegatorShareExRate()) - p, cand, tokens := p.candidateRemoveShares(cand, shares) - - msg = fmt.Sprintf("Removed %d shares from %s", shares.Evaluate(), msg) - - return p, cand, tokens, msg - }, + BondOrUnbond, + AddTokens, + RemoveShares, } r.Shuffle(len(operations), func(i, j int) { operations[i], operations[j] = operations[j], operations[i] @@ -366,17 +359,23 @@ func assertInvariants(t *testing.T, msg string, ) } - require.Equal(t, pMod.BondedPool, bondedPool.Evaluate(), "Applying operation \"%s\" resulted in unequal bondedPool", msg) - require.Equal(t, pMod.UnbondedPool, unbondedPool.Evaluate(), "Applying operation \"%s\" resulted in unequal unbondedPool", msg) + //require.Equal(t, pMod.BondedPool, bondedPool.Evaluate(), "Applying operation \"%s\" resulted in unequal bondedPool", msg) + //require.Equal(t, pMod.UnbondedPool, unbondedPool.Evaluate(), "Applying operation \"%s\" resulted in unequal unbondedPool", msg) } // run random operations in a random order on a random single-candidate state, assert invariants hold func TestSingleCandidateIntegrationInvariants(t *testing.T) { r := rand.New(rand.NewSource(41)) + var pool Pool + var candidateMod Candidate + var tokens int64 + var candidates Candidates + var msg string + for i := 0; i < 10; i++ { - pool, candidates := randomSetup(r, 1) + pool, candidates = randomSetup(r, 1) initialPool, initialCandidates := pool, candidates assertInvariants(t, "no operation", @@ -385,13 +384,16 @@ func TestSingleCandidateIntegrationInvariants(t *testing.T) { for j := 0; j < 100; j++ { - pool, candidateMod, tokens, msg := randomOperation(r)(pool, candidates[0]) + pool, candidateMod, tokens, msg = randomOperation(r)(r, pool, candidates[0]) candidates[0] = candidateMod assertInvariants(t, msg, initialPool, initialCandidates, pool, candidates, tokens) + initialPool = pool + initialCandidates = candidates + } } } @@ -400,9 +402,15 @@ func TestSingleCandidateIntegrationInvariants(t *testing.T) { func TestMultiCandidateIntegrationInvariants(t *testing.T) { r := rand.New(rand.NewSource(42)) + var pool Pool + var candidateMod Candidate + var tokens int64 + var candidates Candidates + var msg string + for i := 0; i < 10; i++ { - pool, candidates := randomSetup(r, 100) + pool, candidates = randomSetup(r, 100) initialPool, initialCandidates := pool, candidates assertInvariants(t, "no operation", @@ -412,13 +420,16 @@ func TestMultiCandidateIntegrationInvariants(t *testing.T) { for j := 0; j < 100; j++ { index := int(r.Int31n(int32(len(candidates)))) - pool, candidateMod, tokens, msg := randomOperation(r)(pool, candidates[index]) + pool, candidateMod, tokens, msg = randomOperation(r)(r, pool, candidates[index]) candidates[index] = candidateMod assertInvariants(t, msg, initialPool, initialCandidates, pool, candidates, tokens) + initialPool = pool + initialCandidates = candidates + } } }