Cleanup testcases, refine to the error of concern

This commit is contained in:
Christopher Goes 2018-04-03 13:15:27 +02:00
parent b78aa2f650
commit 19137d007b
No known key found for this signature in database
GPG Key ID: E828D98232D328D3

View File

@ -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
}
}
}