thresholdstate_test.go raw

   1  package blockchain
   2  
   3  import (
   4  	"testing"
   5  	
   6  	"github.com/p9c/p9/pkg/chainhash"
   7  )
   8  
   9  // TestThresholdStateStringer tests the stringified output for the ThresholdState type.
  10  func TestThresholdStateStringer(t *testing.T) {
  11  	t.Parallel()
  12  	tests := []struct {
  13  		in   ThresholdState
  14  		want string
  15  	}{
  16  		{ThresholdDefined, "ThresholdDefined"},
  17  		{ThresholdStarted, "ThresholdStarted"},
  18  		{ThresholdLockedIn, "ThresholdLockedIn"},
  19  		{ThresholdActive, "ThresholdActive"},
  20  		{ThresholdFailed, "ThresholdFailed"},
  21  		{0xff, "Unknown ThresholdState (255)"},
  22  	}
  23  	// Detect additional threshold states that don't have the stringer added.
  24  	if len(tests)-1 != int(numThresholdsStates) {
  25  		t.Errorf("It appears a threshold statewas added without " +
  26  			"adding an associated stringer test",
  27  		)
  28  	}
  29  	t.Logf("Running %d tests", len(tests))
  30  	for i, test := range tests {
  31  		result := test.in.String()
  32  		if result != test.want {
  33  			t.Errorf("String #%d\n got: %s want: %s", i, result,
  34  				test.want,
  35  			)
  36  			continue
  37  		}
  38  	}
  39  }
  40  
  41  // TestThresholdStateCache ensure the threshold state cache works as intended including adding entries, updating
  42  // existing entries, and flushing.
  43  func TestThresholdStateCache(t *testing.T) {
  44  	t.Parallel()
  45  	tests := []struct {
  46  		name       string
  47  		numEntries int
  48  		state      ThresholdState
  49  	}{
  50  		{name: "2 entries defined", numEntries: 2, state: ThresholdDefined},
  51  		{name: "7 entries started", numEntries: 7, state: ThresholdStarted},
  52  		{name: "10 entries active", numEntries: 10, state: ThresholdActive},
  53  		{name: "5 entries locked in", numEntries: 5, state: ThresholdLockedIn},
  54  		{name: "3 entries failed", numEntries: 3, state: ThresholdFailed},
  55  	}
  56  nextTest:
  57  	for _, test := range tests {
  58  		cache := &newThresholdCaches(1)[0]
  59  		for i := 0; i < test.numEntries; i++ {
  60  			var hash chainhash.Hash
  61  			hash[0] = uint8(i + 1)
  62  			// Ensure the hash isn't available in the cache already.
  63  			_, ok := cache.Lookup(&hash)
  64  			if ok {
  65  				t.Errorf("Lookup (%s): has entry for hash %v",
  66  					test.name, hash,
  67  				)
  68  				continue nextTest
  69  			}
  70  			// Ensure hash that was added to the cache reports it's available and the state is the expected value.
  71  			cache.Update(&hash, test.state)
  72  			state, ok := cache.Lookup(&hash)
  73  			if !ok {
  74  				t.Errorf("Lookup (%s): missing entry for hash "+
  75  					"%v", test.name, hash,
  76  				)
  77  				continue nextTest
  78  			}
  79  			if state != test.state {
  80  				t.Errorf("Lookup (%s): state mismatch - got "+
  81  					"%v, want %v", test.name, state,
  82  					test.state,
  83  				)
  84  				continue nextTest
  85  			}
  86  			// Ensure adding an existing hash with the same state doesn't break the existing entry.
  87  			cache.Update(&hash, test.state)
  88  			state, ok = cache.Lookup(&hash)
  89  			if !ok {
  90  				t.Errorf("Lookup (%s): missing entry after "+
  91  					"second add for hash %v", test.name,
  92  					hash,
  93  				)
  94  				continue nextTest
  95  			}
  96  			if state != test.state {
  97  				t.Errorf("Lookup (%s): state mismatch after "+
  98  					"second add - got %v, want %v",
  99  					test.name, state, test.state,
 100  				)
 101  				continue nextTest
 102  			}
 103  			// Ensure adding an existing hash with a different state updates the existing entry.
 104  			newState := ThresholdFailed
 105  			if newState == test.state {
 106  				newState = ThresholdStarted
 107  			}
 108  			cache.Update(&hash, newState)
 109  			state, ok = cache.Lookup(&hash)
 110  			if !ok {
 111  				t.Errorf("Lookup (%s): missing entry after "+
 112  					"state change for hash %v", test.name,
 113  					hash,
 114  				)
 115  				continue nextTest
 116  			}
 117  			if state != newState {
 118  				t.Errorf("Lookup (%s): state mismatch after "+
 119  					"state change - got %v, want %v",
 120  					test.name, state, newState,
 121  				)
 122  				continue nextTest
 123  			}
 124  		}
 125  	}
 126  }
 127