quorum_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package vaa
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. )
  6. func TestCalculateQuorum(t *testing.T) {
  7. type Test struct {
  8. numGuardians int
  9. quorumResult int
  10. shouldPanic bool
  11. }
  12. tests := []Test{
  13. // Positive Test Cases
  14. {numGuardians: 0, quorumResult: 1},
  15. {numGuardians: 1, quorumResult: 1},
  16. {numGuardians: 2, quorumResult: 2},
  17. {numGuardians: 3, quorumResult: 3},
  18. {numGuardians: 4, quorumResult: 3},
  19. {numGuardians: 5, quorumResult: 4},
  20. {numGuardians: 6, quorumResult: 5},
  21. {numGuardians: 7, quorumResult: 5},
  22. {numGuardians: 8, quorumResult: 6},
  23. {numGuardians: 9, quorumResult: 7},
  24. {numGuardians: 10, quorumResult: 7},
  25. {numGuardians: 11, quorumResult: 8},
  26. {numGuardians: 12, quorumResult: 9},
  27. {numGuardians: 13, quorumResult: 9},
  28. {numGuardians: 14, quorumResult: 10},
  29. {numGuardians: 15, quorumResult: 11},
  30. {numGuardians: 16, quorumResult: 11},
  31. {numGuardians: 17, quorumResult: 12},
  32. {numGuardians: 18, quorumResult: 13},
  33. {numGuardians: 19, quorumResult: 13},
  34. {numGuardians: 50, quorumResult: 34},
  35. {numGuardians: 100, quorumResult: 67},
  36. {numGuardians: 1000, quorumResult: 667},
  37. // Negative Test Cases
  38. {numGuardians: -1, quorumResult: 1, shouldPanic: true},
  39. {numGuardians: -1000, quorumResult: 1, shouldPanic: true},
  40. }
  41. for _, tc := range tests {
  42. t.Run("", func(t *testing.T) {
  43. if tc.shouldPanic {
  44. assert.Panics(t, func() { CalculateQuorum(tc.numGuardians) }, "The code did not panic")
  45. } else {
  46. num := CalculateQuorum(tc.numGuardians)
  47. assert.Equal(t, tc.quorumResult, num)
  48. }
  49. })
  50. }
  51. }
  52. func FuzzCalculateQuorum(f *testing.F) {
  53. // Add examples to our fuzz corpus
  54. f.Add(1)
  55. f.Add(2)
  56. f.Add(4)
  57. f.Add(8)
  58. f.Add(16)
  59. f.Add(32)
  60. f.Add(64)
  61. f.Add(128)
  62. f.Fuzz(func(t *testing.T, numGuardians int) {
  63. // These are known cases, which the implementation will panic on and/or we have explicit
  64. // unit-test coverage of above, so we can safely ignore it in our fuzz testing
  65. if numGuardians <= 0 {
  66. t.Skip()
  67. }
  68. // Let's determine how many guardians are needed for quorum
  69. num := CalculateQuorum(numGuardians)
  70. // Let's always be sure that there are enough guardians to maintain quorum
  71. assert.LessOrEqual(t, num, numGuardians, "fuzz violation: quorum cannot be achieved because we require more guardians than we have")
  72. // Let's always be sure that num is never zero
  73. assert.NotZero(t, num, "fuzz violation: no guardians are required to achieve quorum")
  74. var floorFloat float64 = 0.66666666666666666
  75. numGuardiansFloat := float64(numGuardians)
  76. numFloat := float64(num)
  77. actualFloat := numFloat / numGuardiansFloat
  78. // Let's always make sure that the int division does not violate the floor of our float division
  79. assert.Greater(t, actualFloat, floorFloat, "fuzz violation: quorum has dropped below 2/3rds threshold")
  80. })
  81. }