Commit bf3945d6 authored by Andreas Bigger's avatar Andreas Bigger

place string parsing in band scorer constructor

parent 539b7504
...@@ -10,8 +10,8 @@ import ( ...@@ -10,8 +10,8 @@ import (
// on the default band scores cli flag value. // on the default band scores cli flag value.
func TestBandScorer_ParseDefault(t *testing.T) { func TestBandScorer_ParseDefault(t *testing.T) {
// Create a new band scorer. // Create a new band scorer.
bandScorer := NewBandScorer() bandScorer, err := NewBandScorer("-40:graylist;-20:restricted;0:nopx;20:friend;")
require.NoError(t, bandScorer.Parse("-40:graylist;-20:restricted;0:nopx;20:friend;")) require.NoError(t, err)
// Validate the [BandScorer] internals. // Validate the [BandScorer] internals.
require.ElementsMatch(t, bandScorer.bands, []scorePair{ require.ElementsMatch(t, bandScorer.bands, []scorePair{
...@@ -26,8 +26,8 @@ func TestBandScorer_ParseDefault(t *testing.T) { ...@@ -26,8 +26,8 @@ func TestBandScorer_ParseDefault(t *testing.T) {
// on a variety of scores. // on a variety of scores.
func TestBandScorer_BucketCorrectly(t *testing.T) { func TestBandScorer_BucketCorrectly(t *testing.T) {
// Create a new band scorer. // Create a new band scorer.
bandScorer := NewBandScorer() bandScorer, err := NewBandScorer("-40:graylist;-20:restricted;0:nopx;20:friend;")
require.NoError(t, bandScorer.Parse("-40:graylist;-20:restricted;0:nopx;20:friend;")) require.NoError(t, err)
// Validate the [BandScorer] internals. // Validate the [BandScorer] internals.
require.Equal(t, bandScorer.Bucket(-100), "graylist") require.Equal(t, bandScorer.Bucket(-100), "graylist")
...@@ -45,8 +45,8 @@ func TestBandScorer_BucketCorrectly(t *testing.T) { ...@@ -45,8 +45,8 @@ func TestBandScorer_BucketCorrectly(t *testing.T) {
// on a variety of scores, in descending order. // on a variety of scores, in descending order.
func TestBandScorer_BucketInverted(t *testing.T) { func TestBandScorer_BucketInverted(t *testing.T) {
// Create a new band scorer. // Create a new band scorer.
bandScorer := NewBandScorer() bandScorer, err := NewBandScorer("20:friend;0:nopx;-20:restricted;-40:graylist;")
require.NoError(t, bandScorer.Parse("20:friend;0:nopx;-20:restricted;-40:graylist;")) require.NoError(t, err)
// Validate the [BandScorer] internals. // Validate the [BandScorer] internals.
require.Equal(t, bandScorer.Bucket(-100), "graylist") require.Equal(t, bandScorer.Bucket(-100), "graylist")
...@@ -64,8 +64,8 @@ func TestBandScorer_BucketInverted(t *testing.T) { ...@@ -64,8 +64,8 @@ func TestBandScorer_BucketInverted(t *testing.T) {
// on an empty string. // on an empty string.
func TestBandScorer_ParseEmpty(t *testing.T) { func TestBandScorer_ParseEmpty(t *testing.T) {
// Create a band scorer on an empty string. // Create a band scorer on an empty string.
bandScorer := NewBandScorer() bandScorer, err := NewBandScorer("")
require.NoError(t, bandScorer.Parse("")) require.NoError(t, err)
// Validate the [BandScorer] internals. // Validate the [BandScorer] internals.
require.Len(t, bandScorer.bands, 0) require.Len(t, bandScorer.bands, 0)
...@@ -75,8 +75,8 @@ func TestBandScorer_ParseEmpty(t *testing.T) { ...@@ -75,8 +75,8 @@ func TestBandScorer_ParseEmpty(t *testing.T) {
// on a variety of whitespaced strings. // on a variety of whitespaced strings.
func TestBandScorer_ParseWhitespace(t *testing.T) { func TestBandScorer_ParseWhitespace(t *testing.T) {
// Create a band scorer on an empty string. // Create a band scorer on an empty string.
bandScorer := NewBandScorer() bandScorer, err := NewBandScorer(" ; ; ; ")
require.NoError(t, bandScorer.Parse(" ; ; ; ")) require.NoError(t, err)
// Validate the [BandScorer] internals. // Validate the [BandScorer] internals.
require.Len(t, bandScorer.bands, 0) require.Len(t, bandScorer.bands, 0)
......
...@@ -128,8 +128,8 @@ func loadPeerScoringParams(conf *p2p.Config, ctx *cli.Context, blockTime uint64) ...@@ -128,8 +128,8 @@ func loadPeerScoringParams(conf *p2p.Config, ctx *cli.Context, blockTime uint64)
// loadPeerScoreBands loads [p2p.BandScorer] from the CLI context. // loadPeerScoreBands loads [p2p.BandScorer] from the CLI context.
func loadPeerScoreBands(conf *p2p.Config, ctx *cli.Context) error { func loadPeerScoreBands(conf *p2p.Config, ctx *cli.Context) error {
scoreBands := ctx.GlobalString(flags.PeerScoreBands.Name) scoreBands := ctx.GlobalString(flags.PeerScoreBands.Name)
bandScorer := p2p.NewBandScorer() bandScorer, err := p2p.NewBandScorer(scoreBands)
if err := bandScorer.Parse(scoreBands); err != nil { if err != nil {
return err return err
} }
conf.BandScoreThresholds = bandScorer conf.BandScoreThresholds = bandScorer
......
...@@ -38,25 +38,16 @@ type BandScoreThresholds struct { ...@@ -38,25 +38,16 @@ type BandScoreThresholds struct {
// [Parse] function and then expose the [Bucket] function for // [Parse] function and then expose the [Bucket] function for
// downstream [BandScorer] consumers. // downstream [BandScorer] consumers.
type BandScorer interface { type BandScorer interface {
Parse(str string) error
Bucket(score float64) string Bucket(score float64) string
Reset() Reset()
} }
// NewBandScorer constructs a new [BandScorer] instance. // NewBandScorer constructs a new [BandScoreThresholds] instance.
func NewBandScorer() *BandScoreThresholds { func NewBandScorer(str string) (*BandScoreThresholds, error) {
return &BandScoreThresholds{ s := &BandScoreThresholds{
bands: make([]scorePair, 0), bands: make([]scorePair, 0),
} }
}
// Reset wipes the internal state of the [BandScorer].
func (s *BandScoreThresholds) Reset() {
s.bands = s.bands[:0]
}
// Parse creates a [BandScorer] from a given string.
func (s *BandScoreThresholds) Parse(str string) error {
for _, band := range strings.Split(str, ";") { for _, band := range strings.Split(str, ";") {
// Skip empty band strings. // Skip empty band strings.
band := strings.TrimSpace(band) band := strings.TrimSpace(band)
...@@ -65,11 +56,11 @@ func (s *BandScoreThresholds) Parse(str string) error { ...@@ -65,11 +56,11 @@ func (s *BandScoreThresholds) Parse(str string) error {
} }
split := strings.Split(band, ":") split := strings.Split(band, ":")
if len(split) != 2 { if len(split) != 2 {
return fmt.Errorf("invalid score band: %s", band) return nil, fmt.Errorf("invalid score band: %s", band)
} }
threshold, err := strconv.ParseFloat(split[0], 64) threshold, err := strconv.ParseFloat(split[0], 64)
if err != nil { if err != nil {
return err return nil, err
} }
s.bands = append(s.bands, scorePair{ s.bands = append(s.bands, scorePair{
band: split[1], band: split[1],
...@@ -82,7 +73,12 @@ func (s *BandScoreThresholds) Parse(str string) error { ...@@ -82,7 +73,12 @@ func (s *BandScoreThresholds) Parse(str string) error {
return s.bands[i].threshold < s.bands[j].threshold return s.bands[i].threshold < s.bands[j].threshold
}) })
return nil return s, nil
}
// Reset wipes the internal state of the [BandScorer].
func (s *BandScoreThresholds) Reset() {
s.bands = s.bands[:0]
} }
// Bucket returns the appropriate band for a given score. // Bucket returns the appropriate band for a given score.
......
...@@ -29,8 +29,9 @@ func (testSuite *PeerScorerTestSuite) SetupTest() { ...@@ -29,8 +29,9 @@ func (testSuite *PeerScorerTestSuite) SetupTest() {
testSuite.mockGater = &p2pMocks.PeerGater{} testSuite.mockGater = &p2pMocks.PeerGater{}
testSuite.mockStore = &p2pMocks.Peerstore{} testSuite.mockStore = &p2pMocks.Peerstore{}
testSuite.mockMetricer = &p2pMocks.GossipMetricer{} testSuite.mockMetricer = &p2pMocks.GossipMetricer{}
testSuite.bandScorer = &p2p.BandScoreThresholds{} bandScorer, err := p2p.NewBandScorer("0:graylist;")
testSuite.NoError(testSuite.bandScorer.Parse("0:graylist;")) testSuite.NoError(err)
testSuite.bandScorer = bandScorer
testSuite.logger = testlog.Logger(testSuite.T(), log.LvlError) testSuite.logger = testlog.Logger(testSuite.T(), log.LvlError)
} }
......
...@@ -39,8 +39,9 @@ func (testSuite *PeerScoresTestSuite) SetupTest() { ...@@ -39,8 +39,9 @@ func (testSuite *PeerScoresTestSuite) SetupTest() {
testSuite.mockGater = &p2pMocks.ConnectionGater{} testSuite.mockGater = &p2pMocks.ConnectionGater{}
testSuite.mockStore = &p2pMocks.Peerstore{} testSuite.mockStore = &p2pMocks.Peerstore{}
testSuite.mockMetricer = &p2pMocks.GossipMetricer{} testSuite.mockMetricer = &p2pMocks.GossipMetricer{}
testSuite.bandScorer = &p2p.BandScoreThresholds{} bandScorer, err := p2p.NewBandScorer("0:graylist;")
testSuite.NoError(testSuite.bandScorer.Parse("0:graylist;")) testSuite.NoError(err)
testSuite.bandScorer = bandScorer
testSuite.logger = testlog.Logger(testSuite.T(), log.LvlError) testSuite.logger = testlog.Logger(testSuite.T(), log.LvlError)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment