code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/the_volume_discount_stats_should_be.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package steps 17 18 import ( 19 "errors" 20 "fmt" 21 "strings" 22 23 "code.vegaprotocol.io/vega/core/integration/stubs" 24 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 25 26 "github.com/cucumber/godog" 27 "golang.org/x/exp/maps" 28 "golang.org/x/exp/slices" 29 ) 30 31 func TheVolumeDiscountStatsShouldBe(broker *stubs.BrokerStub, epochStr string, table *godog.Table) error { 32 epoch, err := U64(epochStr) 33 if err != nil { 34 return fmt.Errorf("could not parse epoch: %w", err) 35 } 36 37 expectedVolumeDiscountStatsStats, err := parseVolumeDiscountStatsShouldBeTable(table) 38 if err != nil { 39 return fmt.Errorf("table is invalid: %w", err) 40 } 41 42 VolumeDiscountStats := broker.VolumeDiscountStats() 43 44 foundStreaksForEpoch := map[string]eventspb.PartyVolumeDiscountStats{} 45 for _, stats := range VolumeDiscountStats { 46 if stats.AtEpoch == epoch { 47 return compareVolumeDiscountStats(expectedVolumeDiscountStatsStats, foundStreaksForEpoch) 48 } 49 } 50 51 return fmt.Errorf("no volume discount stats found for epoch %q", epochStr) 52 } 53 54 func parseVolumeDiscountStatsShouldBeTable(table *godog.Table) (map[string]eventspb.PartyVolumeDiscountStats, error) { 55 rows := StrictParseTable(table, []string{ 56 "party", 57 "running volume", 58 "discount factor", 59 }, []string{}) 60 61 stats := map[string]eventspb.PartyVolumeDiscountStats{} 62 for _, row := range rows { 63 specificRow := newVolumeDiscountStatsShouldBeRow(row) 64 partyID := specificRow.Party() 65 _, alreadyRegistered := stats[partyID] 66 if alreadyRegistered { 67 return nil, fmt.Errorf("cannot have more than one expectation for party %q", partyID) 68 } 69 stats[partyID] = eventspb.PartyVolumeDiscountStats{ 70 PartyId: partyID, 71 DiscountFactor: specificRow.DiscountFactor(), 72 RunningVolume: specificRow.RunningVolume(), 73 } 74 } 75 76 return stats, nil 77 } 78 79 func compareVolumeDiscountStats(expectedStats, foundStats map[string]eventspb.PartyVolumeDiscountStats) error { 80 foundStatsIDs := maps.Keys(expectedStats) 81 expectedStatsIDs := maps.Keys(expectedStats) 82 83 slices.Sort(foundStatsIDs) 84 slices.Sort(expectedStatsIDs) 85 86 unexpectedParties := []string{} 87 partiesNotFound := []string{} 88 89 for _, expectedID := range expectedStatsIDs { 90 if _, ok := foundStats[expectedID]; !ok { 91 partiesNotFound = append(partiesNotFound, expectedID) 92 } 93 } 94 95 for _, foundID := range foundStatsIDs { 96 if _, ok := expectedStats[foundID]; !ok { 97 unexpectedParties = append(unexpectedParties, foundID) 98 } 99 } 100 101 var errStr string 102 if len(partiesNotFound) > 0 { 103 errStr = "parties not found: " + strings.Join(partiesNotFound, ", ") 104 } 105 if len(unexpectedParties) > 0 { 106 if errStr != "" { 107 errStr += ", and " 108 } 109 errStr += "unexpected parties: " + strings.Join(unexpectedParties, ", ") 110 } 111 if errStr != "" { 112 return errors.New(errStr) 113 } 114 115 for _, party := range expectedStatsIDs { 116 foundActivityStreak := foundStats[party] 117 expectedActivityStreak := expectedStats[party] 118 119 if expectedActivityStreak.RunningVolume != foundActivityStreak.RunningVolume || 120 expectedActivityStreak.DiscountFactor != foundActivityStreak.DiscountFactor { 121 return formatDiff( 122 fmt.Sprintf("Volume discount stats did not match for party %q", party), 123 map[string]string{ 124 "running volume": expectedActivityStreak.RunningVolume, 125 "discount factor": expectedActivityStreak.DiscountFactor, 126 }, 127 map[string]string{ 128 "running volume": foundActivityStreak.RunningVolume, 129 "discount factor": foundActivityStreak.DiscountFactor, 130 }, 131 ) 132 } 133 } 134 135 return nil 136 } 137 138 type volumeDiscountStatsShouldBeRow struct { 139 row RowWrapper 140 } 141 142 func newVolumeDiscountStatsShouldBeRow(r RowWrapper) volumeDiscountStatsShouldBeRow { 143 return volumeDiscountStatsShouldBeRow{ 144 row: r, 145 } 146 } 147 148 func (r volumeDiscountStatsShouldBeRow) Party() string { 149 return r.row.MustStr("party") 150 } 151 152 func (r volumeDiscountStatsShouldBeRow) DiscountFactor() string { 153 return r.row.MustStr("discount factor") 154 } 155 156 func (r volumeDiscountStatsShouldBeRow) RunningVolume() string { 157 return r.row.MustStr("running volume") 158 }