github.com/lino-network/lino@v0.6.11/x/reputation/manager_test.go (about) 1 package reputation 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/suite" 11 12 "github.com/cosmos/cosmos-sdk/store" 13 sdk "github.com/cosmos/cosmos-sdk/types" 14 abci "github.com/tendermint/tendermint/abci/types" 15 "github.com/tendermint/tendermint/libs/log" 16 dbm "github.com/tendermint/tm-db" 17 18 "github.com/lino-network/lino/param" 19 "github.com/lino-network/lino/types" 20 "github.com/lino-network/lino/x/reputation/repv2" 21 ) 22 23 type reputationTestSuite struct { 24 suite.Suite 25 ms sdk.CommitMultiStore 26 ph param.ParamHolder 27 rep ReputationManager 28 height int64 29 ctx sdk.Context 30 t time.Time 31 } 32 33 func (suite *reputationTestSuite) timefies() { 34 suite.t = suite.t.Add(25 * time.Hour) 35 suite.height += 1 36 // donate several rounds 37 newctx := sdk.NewContext( 38 suite.ms, abci.Header{ 39 ChainID: "Lino", 40 Height: suite.height, 41 Time: suite.t}, false, log.NewNopLogger()) 42 43 _ = suite.rep.Update(newctx) 44 suite.ctx = newctx 45 } 46 47 func TestReputationTestSuite(t *testing.T) { 48 suite.Run(t, &reputationTestSuite{}) 49 } 50 51 func (suite *reputationTestSuite) SetupTest() { 52 suite.t = time.Now() 53 TestParamKVStoreKey := sdk.NewKVStoreKey("param") 54 TestRepv2KVStoreKey := sdk.NewKVStoreKey("repv2") 55 // TestReputationKVStoreKey := sdk.NewKVStoreKey("rep") 56 db := dbm.NewMemDB() 57 ms := store.NewCommitMultiStore(db) 58 ms.MountStoreWithDB(TestParamKVStoreKey, sdk.StoreTypeIAVL, db) 59 ms.MountStoreWithDB(TestRepv2KVStoreKey, sdk.StoreTypeIAVL, db) 60 _ = ms.LoadLatestVersion() 61 ctx := sdk.NewContext( 62 ms, abci.Header{ChainID: "Lino", Height: 1, Time: suite.t}, false, log.NewNopLogger()) 63 64 ph := param.NewParamHolder(TestParamKVStoreKey) 65 _ = ph.InitParam(ctx) 66 rep := NewReputationManager(TestRepv2KVStoreKey, ph) 67 suite.ph = ph 68 suite.rep = rep.(ReputationManager) 69 suite.ctx = ctx 70 suite.ms = ms 71 suite.height = 1 72 } 73 74 func (suite *reputationTestSuite) TestGetHandlers() { 75 rep := suite.rep 76 v2 := rep.getHandlerV2(suite.ctx) 77 v2impl := v2.(repv2.ReputationImpl) 78 79 suite.Equal(200, v2impl.BestN) 80 suite.Equal(50, v2impl.UserMaxN) 81 suite.Equal(int64(25*3600), v2impl.RoundDurationSeconds) 82 suite.Equal(int64(10), v2impl.SampleWindowSize) 83 suite.Equal(int64(10), v2impl.DecayFactor) 84 } 85 86 func (suite *reputationTestSuite) TestUserPostBasicCheck() { 87 suite.Nil(suite.rep.checkUsername("x")) 88 suite.NotNil(suite.rep.checkUsername("")) 89 suite.Nil(suite.rep.checkPost("x")) 90 suite.NotNil(suite.rep.checkPost("")) 91 suite.Nil(suite.rep.basicCheck("x", "y")) 92 suite.NotNil(suite.rep.basicCheck("", "y")) 93 suite.NotNil(suite.rep.basicCheck("x", "")) 94 suite.NotNil(suite.rep.basicCheck("", "")) 95 } 96 97 func (suite *reputationTestSuite) TestGetCurrentRound() { 98 rep := suite.rep 99 ts, err := rep.GetCurrentRound(suite.ctx) 100 suite.Nil(err) 101 suite.Equal(int64(0), ts) 102 103 suite.timefies() 104 ts, err = rep.GetCurrentRound(suite.ctx) 105 suite.Nil(err) 106 suite.Equal(suite.t.Unix(), ts) 107 108 suite.timefies() 109 ts, err = rep.GetCurrentRound(suite.ctx) 110 suite.Nil(err) 111 suite.Equal(suite.t.Unix(), ts) 112 } 113 114 func (suite *reputationTestSuite) TestDonateInvalid() { 115 rep := suite.rep 116 // errors 117 _, err := rep.DonateAt(suite.ctx, "", "", types.NewMiniDollar(3333)) 118 suite.NotNil(err) 119 _, err = rep.DonateAt(suite.ctx, "yxia", "", types.NewMiniDollar(3333)) 120 suite.NotNil(err) 121 _, err = rep.DonateAt(suite.ctx, "", "xxx", types.NewMiniDollar(3333)) 122 suite.NotNil(err) 123 } 124 125 func (suite *reputationTestSuite) TestDonateAtUpdate() { 126 rep := suite.rep 127 cases := []struct { 128 username types.AccountKey 129 post types.Permlink 130 amount int64 131 }{ 132 {"user1", "post1", (100 * 100000)}, 133 {"user2", "post1", (100 * 100000)}, 134 {"user3", "post2", (100 * 100000)}, 135 {"user4", "post2", (100 * 100000)}, 136 {"user5", "post3", (100 * 100000)}, 137 {"user6", "post3", (100 * 100000)}, 138 {"user7", "post4", (100 * 100000)}, 139 {"user8", "post4", (100 * 100000)}, 140 {"user9", "post5", (0.5 * 100000)}, 141 {"user10", "post6", (0.5 * 100000)}, 142 } 143 for _, v := range cases { 144 dp, err := rep.DonateAt(suite.ctx, v.username, v.post, types.NewMiniDollar(v.amount)) 145 suite.Nil(err) 146 suite.Equal(dp, types.NewMiniDollar(repv2.DefaultInitialReputation)) 147 } 148 suite.timefies() 149 150 // check reputation. 151 for i, v := range cases { 152 rv, err := rep.GetReputation(suite.ctx, v.username) 153 suite.Nil(err) 154 if i < 8 { 155 suite.Equal(types.NewMiniDollar(10), rv, "%d", i) 156 } else { 157 suite.Equal(types.NewMiniDollar(0), rv, "%d", i) 158 } 159 } 160 suite.timefies() 161 162 for i := 0; i < 30; i++ { 163 for _, v := range cases { 164 _, err := rep.DonateAt(suite.ctx, v.username, v.post, types.NewMiniDollar(v.amount)) 165 suite.Nil(err) 166 } 167 suite.timefies() 168 } 169 170 // check reputation. 171 for i, v := range cases { 172 rv, err := rep.GetReputation(suite.ctx, v.username) 173 suite.Nil(err) 174 if i < 8 { 175 suite.Equal(types.NewMiniDollar(8304386).String(), rv.String(), "%d", i) 176 } else { 177 suite.Equal(types.NewMiniDollar(0).String(), rv.String(), "%d", i) 178 } 179 } 180 } 181 182 func (suite *reputationTestSuite) TestExportImport() { 183 rep := suite.rep 184 cases := []struct { 185 username types.AccountKey 186 post types.Permlink 187 amount int64 188 }{ 189 {"user1", "post1", (100 * 100000)}, 190 {"user2", "post1", (100 * 100000)}, 191 {"user3", "post2", (100 * 100000)}, 192 {"user4", "post2", (100 * 100000)}, 193 {"user5", "post3", (100 * 100000)}, 194 {"user6", "post3", (100 * 100000)}, 195 {"user7", "post4", (100 * 100000)}, 196 {"user8", "post4", (100 * 100000)}, 197 {"user9", "post5", (0.5 * 100000)}, 198 {"user10", "post6", (0.5 * 100000)}, 199 } 200 201 for i := 0; i < 30+1; i++ { 202 for _, v := range cases { 203 _, err := rep.DonateAt(suite.ctx, v.username, v.post, types.NewMiniDollar(v.amount)) 204 suite.Nil(err) 205 } 206 suite.timefies() 207 } 208 209 // check reputation 210 for i, v := range cases { 211 rv, err := rep.GetReputation(suite.ctx, v.username) 212 suite.Nil(err) 213 if i < 8 { 214 suite.Equal(types.NewMiniDollar(8304386).String(), rv.String(), "%d", i) 215 } else { 216 suite.Equal(types.NewMiniDollar(0).String(), rv.String(), "%d", i) 217 } 218 } 219 220 dir, err2 := ioutil.TempDir("", "test") 221 suite.Require().Nil(err2) 222 defer os.RemoveAll(dir) // clean up 223 224 tmpfn := filepath.Join(dir, "tmpfile") 225 err2 = rep.ExportToFile(suite.ctx, nil, tmpfn) 226 suite.Nil(err2) 227 228 // clear everything 229 suite.SetupTest() 230 suite.timefies() // start to use repv2 231 rep = suite.rep 232 233 // check reputation, should all be initial reputation 234 for i, v := range cases { 235 rv, err := rep.GetReputation(suite.ctx, v.username) 236 suite.Nil(err) 237 suite.Require().Equal( 238 types.NewMiniDollar(repv2.DefaultInitialReputation).String(), rv.String(), "%d", i) 239 } 240 241 err3 := rep.ImportFromFile(suite.ctx, nil, tmpfn) 242 suite.Nil(err3) 243 244 // check reputation 245 for i, v := range cases { 246 rv, err := rep.GetReputation(suite.ctx, v.username) 247 suite.Nil(err) 248 if i < 8 { 249 suite.Equal(types.NewMiniDollar(8304386).String(), rv.String(), "%d", i) 250 } else { 251 suite.Equal(types.NewMiniDollar(0).String(), rv.String(), "%d", i) 252 } 253 } 254 }