Skip to content

Commit

Permalink
#16 working tests for data module
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc committed Mar 29, 2019
1 parent 3979fa1 commit 9d44700
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 101 deletions.
22 changes: 0 additions & 22 deletions x/data/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,3 @@ func GetCmdGetData(queryRoute string, cdc *codec.Codec) *cobra.Command {
},
}
}

func GetCmdGetDataBlockHeight(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "block-height [id]",
Short: "get the block height at which this data was committed",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
id := args[0]

res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/block-height/%s", queryRoute, id), nil)
if err != nil {
fmt.Printf("could not resolve data - %s \n", string(id))
return nil
}

fmt.Println(string(res))

return nil
},
}
}
1 change: 0 additions & 1 deletion x/data/client/module_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ func (mc ModuleClient) GetQueryCmd() *cobra.Command {

dataQueryCmd.AddCommand(client.GetCommands(
datacmd.GetCmdGetData(mc.storeKey, mc.cdc),
datacmd.GetCmdGetDataBlockHeight(mc.storeKey, mc.cdc),
)...)

return dataQueryCmd
Expand Down
114 changes: 114 additions & 0 deletions x/data/data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package data_test

import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/leanovate/gopter"
"github.com/leanovate/gopter/prop"
"github.com/regen-network/regen-ledger/graph"
"github.com/regen-network/regen-ledger/graph/binary"
"github.com/regen-network/regen-ledger/graph/gen"
"github.com/regen-network/regen-ledger/x/data"
"github.com/regen-network/regen-ledger/x/schema"
schematest "github.com/regen-network/regen-ledger/x/schema/test"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"testing"
)

type Suite struct {
suite.Suite
SchemaKeeper schema.Keeper
Keeper data.Keeper
Handler sdk.Handler
Ctx sdk.Context
Cms store.CommitMultiStore
AnAddr sdk.AccAddress
Resolver graph.SchemaResolver
}

func (s *Suite) SetupTest() {
db := dbm.NewMemDB()
s.Cms = store.NewCommitMultiStore(db)
schemaKey := sdk.NewKVStoreKey("schema")
dataKey := sdk.NewKVStoreKey("data")
cdc := codec.New()
schema.RegisterCodec(cdc)
s.SchemaKeeper = schema.NewKeeper(schemaKey, cdc)
s.Keeper = data.NewKeeper(dataKey, s.SchemaKeeper, cdc)
s.Cms.MountStoreWithDB(schemaKey, sdk.StoreTypeIAVL, db)
s.Cms.MountStoreWithDB(dataKey, sdk.StoreTypeIAVL, db)
_ = s.Cms.LoadLatestVersion()
s.Ctx = sdk.NewContext(s.Cms, abci.Header{}, false, log.NewNopLogger())
s.AnAddr = sdk.AccAddress{0, 1, 2, 3, 4, 5, 6, 7, 8}
s.Handler = data.NewHandler(s.Keeper)
s.Resolver = schema.NewOnChainSchemaResolver(s.SchemaKeeper, s.Ctx)
schematest.CreateSampleSchema(s.Suite, s.SchemaKeeper, s.Ctx, s.AnAddr)
}

func (s *Suite) TestStoreDataGraph() {
params := gopter.DefaultTestParameters()
properties := gopter.NewProperties(params)
properties.Property("can round trip store/retrieve graphs",
prop.ForAll(func(g1 graph.Graph) (bool, error) {
buf := new(bytes.Buffer)
err := binary.SerializeGraph(s.Resolver, g1, buf)
if err != nil {
return false, err
}
hash := graph.Hash(g1)

// check if we have exisitng data (because the generator repeats values)
bz := s.Keeper.GetData(s.Ctx, hash)
if bz == nil {
res := s.Handler(s.Ctx, data.MsgStoreGraph{Hash: hash, Data: buf.Bytes(), Signer: s.AnAddr})
if res.Code != sdk.CodeOK {
return false, fmt.Errorf("%+v", res)
}

// verify can't store same graph again
res = s.Handler(s.Ctx, data.MsgStoreGraph{Hash: hash, Data: buf.Bytes(), Signer: s.AnAddr})
if res.Code == sdk.CodeOK {
return false, fmt.Errorf("shouldn't be able to store the same graph twice")
}

bz = s.Keeper.GetData(s.Ctx, hash)
}

g2, err := binary.DeserializeGraph(s.Resolver, bytes.NewBuffer(bz))
if err != nil {
return false, err
}

hash2 := graph.Hash(g2)
if !bytes.Equal(hash, hash2) {
return false, fmt.Errorf("wrong hash")
}

s1, err := graph.CanonicalString(g1)
if err != nil {
return false, err
}

s2, err := graph.CanonicalString(g2)
if err != nil {
return false, err
}

if s1 != s2 {
return false, fmt.Errorf("wrong canonical text")
}

return true, nil
}, gen.Graph(s.Resolver)))
properties.TestingRun(s.T())
}

func TestSuite(t *testing.T) {
suite.Run(t, new(Suite))
}
51 changes: 6 additions & 45 deletions x/data/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import (
bytes2 "bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/regen-network/regen-ledger/graph"
"github.com/regen-network/regen-ledger/graph/binary"
"github.com/regen-network/regen-ledger/types"
"github.com/regen-network/regen-ledger/x/schema"
"math"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// Keeper maintains the link to data storage and exposes getter/setter methods for the various parts of the state machine
Expand All @@ -21,11 +19,6 @@ type Keeper struct {
cdc *codec.Codec // The wire codec for binary encoding/decoding.
}

type DataRecord struct {
Data []byte `json:"data"`
BlockHeight int64 `json:"block_height"`
}

// NewKeeper creates new instances of the nameservice Keeper
func NewKeeper(dataStoreKey sdk.StoreKey, schemaKeeper schema.Keeper, cdc *codec.Codec) Keeper {
return Keeper{
Expand All @@ -36,24 +29,12 @@ func NewKeeper(dataStoreKey sdk.StoreKey, schemaKeeper schema.Keeper, cdc *codec
}

func (k Keeper) GetData(ctx sdk.Context, hash []byte) []byte {
return k.getDataRecord(ctx, hash).Data
}

func (k Keeper) GetDataBlockHeight(ctx sdk.Context, hash []byte) int64 {
bh := k.getDataRecord(ctx, hash).BlockHeight
if bh <= 0 {
return math.MaxInt64
}
return bh
}

func (k Keeper) getDataRecord(ctx sdk.Context, hash []byte) (data DataRecord) {
store := ctx.KVStore(k.dataStoreKey)
bz := store.Get(hash)
if bz == nil {
return
return nil
}
return k.decodeDataRecord(bz)
return bz
}

const (
Expand All @@ -72,32 +53,12 @@ func (k Keeper) StoreGraph(ctx sdk.Context, hash []byte, data []byte) (types.Dat
return nil, sdk.ErrUnknownRequest("incorrect graph hash")
}
store := ctx.KVStore(k.dataStoreKey)
existing := k.getDataRecord(ctx, hash)
if existing.BlockHeight != 0 {
existing := k.GetData(ctx, hash)
if existing != nil {
return nil, sdk.ErrUnknownRequest("already exists")
}
bytes := len(data)
ctx.GasMeter().ConsumeGas(gasPerByteStorage*uint64(bytes), "store data")
bz := k.encodeDataRecord(DataRecord{
Data: data,
BlockHeight: ctx.BlockHeight(),
})
store.Set(hash, bz)
store.Set(hash, data)
return hash, nil
}

func (k Keeper) encodeDataRecord(data DataRecord) []byte {
bz, err := k.cdc.MarshalBinaryBare(data)
if err != nil {
panic(err)
}
return bz
}

func (k Keeper) decodeDataRecord(bz []byte) (data DataRecord) {
err := k.cdc.UnmarshalBinaryBare(bz, &data)
if err != nil {
panic(err)
}
return
}
18 changes: 1 addition & 17 deletions x/data/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import (
"encoding/hex"
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
"math"
"strconv"
)

// query endpoints supported by the governance Querier
const (
QueryData = "get"
QueryData = "get"
QueryDataBlockHeight = "block-height"
)

Expand All @@ -19,8 +17,6 @@ func NewQuerier(keeper Keeper) sdk.Querier {
switch path[0] {
case QueryData:
return queryData(ctx, path[1:], req, keeper)
case QueryDataBlockHeight:
return queryDataBlockHeight(ctx, path[1:], req, keeper)
default:
return nil, sdk.ErrUnknownRequest("unknown data query endpoint")
}
Expand All @@ -46,15 +42,3 @@ func queryData(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Kee

return value, nil
}

func queryDataBlockHeight(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
id := path[0]

value := keeper.GetDataBlockHeight(ctx, fromHex(id))

if value == math.MaxInt64 {
return []byte{}, sdk.ErrUnknownRequest("could not resolve id")
}

return []byte(strconv.FormatInt(value, 10)), nil
}
37 changes: 21 additions & 16 deletions x/schema/test/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,56 +38,61 @@ func (s *Harness) Setup() {
}

func (s *Harness) CreateSampleSchema() {
CreateSampleSchema(s.Suite, s.Keeper, s.Ctx, s.AnAddr)
}

func CreateSampleSchema(s suite.Suite, keeper schema.Keeper, ctx sdk.Context, anAddr sdk.AccAddress) {
anAddr = sdk.AccAddress{0, 1, 2, 3, 4, 5, 6, 7, 8}
// create a mock schema
_, _, err := s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err := keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "name",
PropertyType: graph.TyString,
})
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "x",
PropertyType: graph.TyDouble,
})
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "b",
PropertyType: graph.TyBool,
})
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "names",
PropertyType: graph.TyString,
Arity: graph.UnorderedSet,
})
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "xs",
PropertyType: graph.TyDouble,
Arity: graph.UnorderedSet,
})
s.Require().Nil(err)
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "nameList",
PropertyType: graph.TyString,
Arity: graph.OrderedSet,
})
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "xList",
PropertyType: graph.TyDouble,
Arity: graph.OrderedSet,
})
s.Require().Nil(err)
_, _, err = s.Keeper.DefineProperty(s.Ctx, schema.PropertyDefinition{
Creator: s.AnAddr,
_, _, err = keeper.DefineProperty(ctx, schema.PropertyDefinition{
Creator: anAddr,
Name: "bList",
PropertyType: graph.TyBool,
Arity: graph.OrderedSet,
Expand Down

0 comments on commit 9d44700

Please sign in to comment.