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  }