From 79689af3a89fdee4474c6448622607dbe14f53b7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 21 Feb 2018 18:25:00 -0600 Subject: [PATCH] blockchain: Correct error stringer tests. This adds missing error entries to the tests and also adds an additional check to ensure that all possibilities are tested to prevent drift in the future. --- blockchain/error.go | 5 +- blockchain/error_test.go | 151 +++++++++++++++++++++++++++------------ 2 files changed, 111 insertions(+), 45 deletions(-) diff --git a/blockchain/error.go b/blockchain/error.go index 9ecbe07b39..410a2d68d5 100644 --- a/blockchain/error.go +++ b/blockchain/error.go @@ -448,6 +448,9 @@ const ( // ErrInvalidEarlyFinalState indicates that a block before stake validation // height had a non-zero final state. ErrInvalidEarlyFinalState + + // numErrorCodes is the maximum error code number used in tests. + numErrorCodes ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -457,7 +460,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrBlockTooBig: "ErrBlockTooBig", ErrWrongBlockSize: "ErrWrongBlockSize", ErrBlockVersionTooOld: "ErrBlockVersionTooOld", - ErrBadStakeVersion: "ErrBlockStakeVersion", + ErrBadStakeVersion: "ErrBadStakeVersion", ErrInvalidTime: "ErrInvalidTime", ErrTimeTooOld: "ErrTimeTooOld", ErrTimeTooNew: "ErrTimeTooNew", diff --git a/blockchain/error_test.go b/blockchain/error_test.go index 02842d224a..1bcd864d8e 100644 --- a/blockchain/error_test.go +++ b/blockchain/error_test.go @@ -1,61 +1,124 @@ // Copyright (c) 2014 The btcsuite developers -// Copyright (c) 2015-2016 The Decred developers +// Copyright (c) 2015-2018 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package blockchain_test +package blockchain import ( "testing" - - "github.com/decred/dcrd/blockchain" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. func TestErrorCodeStringer(t *testing.T) { tests := []struct { - in blockchain.ErrorCode + in ErrorCode want string }{ - {blockchain.ErrDuplicateBlock, "ErrDuplicateBlock"}, - {blockchain.ErrBlockTooBig, "ErrBlockTooBig"}, - {blockchain.ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, - {blockchain.ErrInvalidTime, "ErrInvalidTime"}, - {blockchain.ErrTimeTooOld, "ErrTimeTooOld"}, - {blockchain.ErrTimeTooNew, "ErrTimeTooNew"}, - {blockchain.ErrDifficultyTooLow, "ErrDifficultyTooLow"}, - {blockchain.ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, - {blockchain.ErrHighHash, "ErrHighHash"}, - {blockchain.ErrBadMerkleRoot, "ErrBadMerkleRoot"}, - {blockchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, - {blockchain.ErrForkTooOld, "ErrForkTooOld"}, - {blockchain.ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, - {blockchain.ErrNoTransactions, "ErrNoTransactions"}, - {blockchain.ErrTooManyTransactions, "ErrTooManyTransactions"}, - {blockchain.ErrNoTxInputs, "ErrNoTxInputs"}, - {blockchain.ErrNoTxOutputs, "ErrNoTxOutputs"}, - {blockchain.ErrTxTooBig, "ErrTxTooBig"}, - {blockchain.ErrBadTxOutValue, "ErrBadTxOutValue"}, - {blockchain.ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, - {blockchain.ErrBadTxInput, "ErrBadTxInput"}, - {blockchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, - {blockchain.ErrMissingTxOut, "ErrMissingTxOut"}, - {blockchain.ErrUnfinalizedTx, "ErrUnfinalizedTx"}, - {blockchain.ErrDuplicateTx, "ErrDuplicateTx"}, - {blockchain.ErrOverwriteTx, "ErrOverwriteTx"}, - {blockchain.ErrImmatureSpend, "ErrImmatureSpend"}, - {blockchain.ErrSpendTooHigh, "ErrSpendTooHigh"}, - {blockchain.ErrBadFees, "ErrBadFees"}, - {blockchain.ErrTooManySigOps, "ErrTooManySigOps"}, - {blockchain.ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, - {blockchain.ErrMultipleCoinbases, "ErrMultipleCoinbases"}, - {blockchain.ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, - {blockchain.ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, - {blockchain.ErrScriptMalformed, "ErrScriptMalformed"}, - {blockchain.ErrScriptValidation, "ErrScriptValidation"}, + {ErrDuplicateBlock, "ErrDuplicateBlock"}, + {ErrMissingParent, "ErrMissingParent"}, + {ErrBlockTooBig, "ErrBlockTooBig"}, + {ErrWrongBlockSize, "ErrWrongBlockSize"}, + {ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, + {ErrBadStakeVersion, "ErrBadStakeVersion"}, + {ErrInvalidTime, "ErrInvalidTime"}, + {ErrTimeTooOld, "ErrTimeTooOld"}, + {ErrTimeTooNew, "ErrTimeTooNew"}, + {ErrDifficultyTooLow, "ErrDifficultyTooLow"}, + {ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, + {ErrHighHash, "ErrHighHash"}, + {ErrBadMerkleRoot, "ErrBadMerkleRoot"}, + {ErrBadCheckpoint, "ErrBadCheckpoint"}, + {ErrForkTooOld, "ErrForkTooOld"}, + {ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, + {ErrNoTransactions, "ErrNoTransactions"}, + {ErrTooManyTransactions, "ErrTooManyTransactions"}, + {ErrNoTxInputs, "ErrNoTxInputs"}, + {ErrNoTxOutputs, "ErrNoTxOutputs"}, + {ErrTxTooBig, "ErrTxTooBig"}, + {ErrBadTxOutValue, "ErrBadTxOutValue"}, + {ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, + {ErrBadTxInput, "ErrBadTxInput"}, + {ErrMissingTxOut, "ErrMissingTxOut"}, + {ErrUnfinalizedTx, "ErrUnfinalizedTx"}, + {ErrDuplicateTx, "ErrDuplicateTx"}, + {ErrOverwriteTx, "ErrOverwriteTx"}, + {ErrImmatureSpend, "ErrImmatureSpend"}, + {ErrSpendTooHigh, "ErrSpendTooHigh"}, + {ErrBadFees, "ErrBadFees"}, + {ErrTooManySigOps, "ErrTooManySigOps"}, + {ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, + {ErrCoinbaseHeight, "ErrCoinbaseHeight"}, + {ErrMultipleCoinbases, "ErrMultipleCoinbases"}, + {ErrStakeTxInRegularTree, "ErrStakeTxInRegularTree"}, + {ErrRegTxInStakeTree, "ErrRegTxInStakeTree"}, + {ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, + {ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, + {ErrBadCoinbaseOutpoint, "ErrBadCoinbaseOutpoint"}, + {ErrBadCoinbaseFraudProof, "ErrBadCoinbaseFraudProof"}, + {ErrBadCoinbaseAmountIn, "ErrBadCoinbaseAmountIn"}, + {ErrBadStakebaseAmountIn, "ErrBadStakebaseAmountIn"}, + {ErrBadStakebaseScriptLen, "ErrBadStakebaseScriptLen"}, + {ErrBadStakebaseScrVal, "ErrBadStakebaseScrVal"}, + {ErrScriptMalformed, "ErrScriptMalformed"}, + {ErrScriptValidation, "ErrScriptValidation"}, + {ErrNotEnoughStake, "ErrNotEnoughStake"}, + {ErrStakeBelowMinimum, "ErrStakeBelowMinimum"}, + {ErrNonstandardStakeTx, "ErrNonstandardStakeTx"}, + {ErrNotEnoughVotes, "ErrNotEnoughVotes"}, + {ErrTooManyVotes, "ErrTooManyVotes"}, + {ErrFreshStakeMismatch, "ErrFreshStakeMismatch"}, + {ErrTooManySStxs, "ErrTooManySStxs"}, + {ErrInvalidEarlyStakeTx, "ErrInvalidEarlyStakeTx"}, + {ErrTicketUnavailable, "ErrTicketUnavailable"}, + {ErrVotesOnWrongBlock, "ErrVotesOnWrongBlock"}, + {ErrVotesMismatch, "ErrVotesMismatch"}, + {ErrIncongruentVotebit, "ErrIncongruentVotebit"}, + {ErrInvalidSSRtx, "ErrInvalidSSRtx"}, + {ErrRevocationsMismatch, "ErrRevocationsMismatch"}, + {ErrTooManyRevocations, "ErrTooManyRevocations"}, + {ErrSStxCommitment, "ErrSStxCommitment"}, + {ErrInvalidSSGenInput, "ErrInvalidSSGenInput"}, + {ErrSSGenPayeeNum, "ErrSSGenPayeeNum"}, + {ErrSSGenPayeeOuts, "ErrSSGenPayeeOuts"}, + {ErrSSGenSubsidy, "ErrSSGenSubsidy"}, + {ErrSStxInImmature, "ErrSStxInImmature"}, + {ErrSStxInScrType, "ErrSStxInScrType"}, + {ErrInvalidSSRtxInput, "ErrInvalidSSRtxInput"}, + {ErrSSRtxPayeesMismatch, "ErrSSRtxPayeesMismatch"}, + {ErrSSRtxPayees, "ErrSSRtxPayees"}, + {ErrTxSStxOutSpend, "ErrTxSStxOutSpend"}, + {ErrRegTxSpendStakeOut, "ErrRegTxSpendStakeOut"}, + {ErrInvalidFinalState, "ErrInvalidFinalState"}, + {ErrPoolSize, "ErrPoolSize"}, + {ErrForceReorgWrongChain, "ErrForceReorgWrongChain"}, + {ErrForceReorgMissingChild, "ErrForceReorgMissingChild"}, + {ErrBadStakebaseValue, "ErrBadStakebaseValue"}, + {ErrDiscordantTxTree, "ErrDiscordantTxTree"}, + {ErrStakeFees, "ErrStakeFees"}, + {ErrNoStakeTx, "ErrNoStakeTx"}, + {ErrBadBlockHeight, "ErrBadBlockHeight"}, + {ErrBlockOneTx, "ErrBlockOneTx"}, + {ErrBlockOneInputs, "ErrBlockOneInputs"}, + {ErrBlockOneOutputs, "ErrBlockOneOutputs"}, + {ErrNoTax, "ErrNoTax"}, + {ErrExpiredTx, "ErrExpiredTx"}, + {ErrExpiryTxSpentEarly, "ErrExpiryTxSpentEarly"}, + {ErrFraudAmountIn, "ErrFraudAmountIn"}, + {ErrFraudBlockHeight, "ErrFraudBlockHeight"}, + {ErrFraudBlockIndex, "ErrFraudBlockIndex"}, + {ErrZeroValueOutputSpend, "ErrZeroValueOutputSpend"}, + {ErrInvalidEarlyVoteBits, "ErrInvalidEarlyVoteBits"}, + {ErrInvalidEarlyFinalState, "ErrInvalidEarlyFinalState"}, {0xffff, "Unknown ErrorCode (65535)"}, } + // Detect additional error codes that don't have the stringer added. + if len(tests)-1 != int(numErrorCodes) { + t.Errorf("It appears an error code was added without adding an " + + "associated stringer test") + } + t.Logf("Running %d tests", len(tests)) for i, test := range tests { result := test.in.String() @@ -70,15 +133,15 @@ func TestErrorCodeStringer(t *testing.T) { // TestRuleError tests the error output for the RuleError type. func TestRuleError(t *testing.T) { tests := []struct { - in blockchain.RuleError + in RuleError want string }{ { - blockchain.RuleError{Description: "duplicate block"}, + RuleError{Description: "duplicate block"}, "duplicate block", }, { - blockchain.RuleError{Description: "human-readable error"}, + RuleError{Description: "human-readable error"}, "human-readable error", }, }